Skip to content
This repository was archived by the owner on Dec 19, 2020. It is now read-only.

Add a new filter that matches against a logger name #3

Open
wants to merge 5 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ composer.lock

# PhpStorm project files
.idea

# Vim swapfiles.
.*.swp
.*.swo
1 change: 1 addition & 0 deletions src/changes/changes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</properties>
<body>
<release version="develop">
<action date="2013-05-05" type="add" dev="Alex Pounds">Added new filter for matching a logger name.</action>
<action date="2012-12-31" type="update" issue="LOG4PHP-197" dev="Ivan Habunek" due-to="Sven Rautenberg" due-to-email="sven at rtbg dot de">Made Logger::isInitialized() public.</action>
<action date="2012-12-31" type="update" issue="LOG4PHP-144" dev="Ivan Habunek">Improved LoggerAppenderMail to set the Content-type header as defined in layout.</action>
</release>
Expand Down
26 changes: 26 additions & 0 deletions src/examples/php/filter_namematch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// START SNIPPET: doxia
require_once dirname(__FILE__).'/../../main/php/Logger.php';

Logger::configure(dirname(__FILE__).'/../resources/filter_namematch.xml');
$loggerFoo = Logger::getLogger('foo');
$loggerBar = Logger::getLogger('bar');

$loggerFoo->info("Messages from foo are denied due to the second filter");
$loggerBar->info("Messages from bar are accepted");
30 changes: 30 additions & 0 deletions src/examples/resources/filter_namematch.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<log4php:configuration xmlns:log4php="http://logging.apache.org/log4php/" threshold="all">
<appender name="default" class="LoggerAppenderEcho">
<layout class="LoggerLayoutTTCC" />
<filter class="LoggerFilterNameMatch">
<param name="StringToMatch" value="bar" />
</filter>
<filter class="LoggerFilterDenyAll" />
</appender>
<root>
<level value="INFO" />
<appender_ref ref="default" />
</root>
</log4php:configuration>
25 changes: 13 additions & 12 deletions src/main/php/LoggerAutoloader.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*
* @package log4php
*/

Expand All @@ -26,15 +26,15 @@

/**
* Class autoloader.
*
*
* @package log4php
* @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
*/
class LoggerAutoloader {

/** Maps classnames to files containing the class. */
private static $classes = array(

// Base
'LoggerAppender' => '/LoggerAppender.php',
'LoggerAppenderPool' => '/LoggerAppenderPool.php',
Expand All @@ -52,7 +52,7 @@ class LoggerAutoloader {
'LoggerReflectionUtils' => '/LoggerReflectionUtils.php',
'LoggerRoot' => '/LoggerRoot.php',
'LoggerThrowableInformation' => '/LoggerThrowableInformation.php',

// Appenders
'LoggerAppenderConsole' => '/appenders/LoggerAppenderConsole.php',
'LoggerAppenderDailyFile' => '/appenders/LoggerAppenderDailyFile.php',
Expand All @@ -68,7 +68,7 @@ class LoggerAutoloader {
'LoggerAppenderRollingFile' => '/appenders/LoggerAppenderRollingFile.php',
'LoggerAppenderSocket' => '/appenders/LoggerAppenderSocket.php',
'LoggerAppenderSyslog' => '/appenders/LoggerAppenderSyslog.php',

// Configurators
'LoggerConfigurationAdapter' => '/configurators/LoggerConfigurationAdapter.php',
'LoggerConfigurationAdapterINI' => '/configurators/LoggerConfigurationAdapterINI.php',
Expand All @@ -80,14 +80,15 @@ class LoggerAutoloader {
'LoggerFilterDenyAll' => '/filters/LoggerFilterDenyAll.php',
'LoggerFilterLevelMatch' => '/filters/LoggerFilterLevelMatch.php',
'LoggerFilterLevelRange' => '/filters/LoggerFilterLevelRange.php',
'LoggerFilterNameMatch' => '/filters/LoggerFilterNameMatch.php',
'LoggerFilterStringMatch' => '/filters/LoggerFilterStringMatch.php',

// Helpers
'LoggerFormattingInfo' => '/helpers/LoggerFormattingInfo.php',
'LoggerOptionConverter' => '/helpers/LoggerOptionConverter.php',
'LoggerPatternParser' => '/helpers/LoggerPatternParser.php',
'LoggerUtils' => '/helpers/LoggerUtils.php',

// Pattern converters
'LoggerPatternConverter' => '/pattern/LoggerPatternConverter.php',
'LoggerPatternConverterClass' => '/pattern/LoggerPatternConverterClass.php',
Expand All @@ -113,22 +114,22 @@ class LoggerAutoloader {
'LoggerPatternConverterSessionID' => '/pattern/LoggerPatternConverterSessionID.php',
'LoggerPatternConverterSuperglobal' => '/pattern/LoggerPatternConverterSuperglobal.php',
'LoggerPatternConverterThrowable' => '/pattern/LoggerPatternConverterThrowable.php',

// Layouts
'LoggerLayoutHtml' => '/layouts/LoggerLayoutHtml.php',
'LoggerLayoutPattern' => '/layouts/LoggerLayoutPattern.php',
'LoggerLayoutSerialized' => '/layouts/LoggerLayoutSerialized.php',
'LoggerLayoutSimple' => '/layouts/LoggerLayoutSimple.php',
'LoggerLayoutTTCC' => '/layouts/LoggerLayoutTTCC.php',
'LoggerLayoutXml' => '/layouts/LoggerLayoutXml.php',

// Renderers
'LoggerRendererDefault' => '/renderers/LoggerRendererDefault.php',
'LoggerRendererException' => '/renderers/LoggerRendererException.php',
'LoggerRendererMap' => '/renderers/LoggerRendererMap.php',
'LoggerRenderer' => '/renderers/LoggerRenderer.php',
);

/**
* Loads a class.
* @param string $className The name of the class to load.
Expand Down
130 changes: 130 additions & 0 deletions src/main/php/filters/LoggerFilterNameMatch.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
<?php
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @package log4php
*/

/**
* This is a very simple filter based on string matching.
*
* <p>The filter admits four options: {@link $stringToMatch}, {@link $caseSensitive},
* {@link $exactMatch}, and
* {@link $acceptOnMatch}. If the value of the {@link $stringToMatch} option is included
* in name of the {@link LoggerLoggingEvent}, then the {@link decide()} method returns
* {@link LoggerFilter::ACCEPT} if the <b>AcceptOnMatch</b> option value is true and
* {@link LoggerFilter::DENY} if it is false. If there is no match, {@link LoggerFilter::NEUTRAL}
* is returned. Matching is case-sensitive by default. Setting {@link $caseSensitive}
* to false makes matching case insensitive. An exact match can be required by setting
* {@link $exactMatch} to true.</p>
*
* <p>
* An example for this filter:
*
* {@example ../../examples/php/filter_namematch.php 19}
*
* <p>
* The corresponding XML file:
*
* {@example ../../examples/resources/filter_namematch.xml 18}
*
* @package log4php
* @subpackage filters
* @since 2.3.1
*/
class LoggerFilterNameMatch extends LoggerFilter {

/**
* @var boolean
*/
protected $acceptOnMatch = true;

/**
* @var boolean
*/
protected $caseSensitive = true;

/**
* @var boolean
*/
protected $exactMatch = false;

/**
* @var string
*/
protected $stringToMatch;

/**
* @param mixed $acceptOnMatch a boolean or a string ('true' or 'false')
*/
public function setAcceptOnMatch($acceptOnMatch) {
$this->setBoolean('acceptOnMatch', $acceptOnMatch);
}

/**
* @param mixed $caseSensitive a boolean or a string ('true' or 'false')
*/
public function setCaseSensitive($caseSensitive) {
$this->setBoolean('caseSensitive', $caseSensitive);
}

/**
* @param mixed $caseSensitive a boolean or a string ('true' or 'false')
*/
public function setExactMatch($exactMatch) {
$this->setBoolean('exactMatch', $exactMatch);
}

/**
* @param string $s the string to match
*/
public function setStringToMatch($string) {
$this->setString('stringToMatch', $string);
}

/**
* @return integer a {@link LOGGER_FILTER_NEUTRAL} is there is no string match.
*/
public function decide(LoggerLoggingEvent $event) {
$msg = $event->getLoggerName();

if($msg === null or $this->stringToMatch === null) {
return LoggerFilter::NEUTRAL;
}

if($this->caseSensitive) {
return $this->testString((function_exists('mb_strpos') ? 'mb_strpos' : 'strpos'), $msg);
} else {
return $this->testString((function_exists('mb_stripos') ? 'mb_stripos' : 'stripos'), $msg);
}
}


protected function testString($method, $msg) {
if($method($msg, $this->stringToMatch) !== false) {
if($this->exactMatch) {
$lenFunc = function_exists('mb_strlen') ? 'mb_strlen' : 'strlen';
if($lenFunc($this->stringToMatch) === $lenFunc($msg)) {
// We were looking for an exact match, and we found one.
return ($this->acceptOnMatch) ? LoggerFilter::ACCEPT : LoggerFilter::DENY;
}
} else { // No exact match required.
return ($this->acceptOnMatch) ? LoggerFilter::ACCEPT : LoggerFilter::DENY;
}
}
return LoggerFilter::NEUTRAL;
}
}
77 changes: 77 additions & 0 deletions src/site/xdoc/docs/filters.xml
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,10 @@ array(
<td><a href="#LoggerFilterLevelRange">LoggerFilterLevelRange</a></td>
<td>Filters based on logging event level range.</td>
</tr>
<tr>
<td><a href="#LoggerFilterNameMatch">LoggerFilterNameMatch</a></td>
<td>Filters by searching for a string in the logger name.</td>
</tr>
<tr>
<td><a href="#LoggerFilterStringMatch">LoggerFilterStringMatch</a></td>
<td>Filters by searching for a string in the logging event message.</td>
Expand Down Expand Up @@ -265,6 +269,79 @@ array(
<param name="levelMax" value="warn" />
<param name="acceptOnMatch" value="false" />
</filter>
]]></pre>

</subsection>

<subsection name="LoggerFilterNameMatch" id="LoggerFilterNameMatch">
<p>This filter allows or denies logging events if the logger name contains a given string. If no match
is found the filter remains neutral.</p>


<h4>Configurable parameters</h4>

<table>
<thead>
<tr>
<th>Parameter</th>
<th>Type</th>
<th>Required</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>stringToMatch</td>
<td>LoggerLevel</td>
<td><strong>Yes</strong></td>
<td>-</td>
<td>The string to match.</td>
</tr>
<tr>
<td>caseSensitive</td>
<td>boolean</td>
<td>No</td>
<td>true</td>
<td>If true, matches are case sensitive. If false, matches ignore case differences.</td>
</tr>
<tr>
<td>exactMatch</td>
<td>LoggerLevel</td>
<td>No</td>
<td>false</td>
<td>If true, the stringToMatch must have the same text content as the logger name. This
parameter co-operates with the <code>caseSensitive</code> parameter; that is, if your
match is case insensitive, then &quot;Example&quot; is considered an exact match with
&quot;example&quot;.</td>
</tr>
<tr>
<td>acceptOnMatch</td>
<td>boolean</td>
<td>No</td>
<td>true</td>
<td>If true and a match is found, the matching log event is accepted. If false and a
match is found, the matching log event is denied.</td>
</tr>
</tbody>
</table>

<h4>Example</h4>

<p>One common pattern is to give each class in your application a logger via
<code>$this->logger = Logger::getLogger(__CLASS__)</code> in the constructor. You could use this
filter to log any events from your <code>Payment</code> class for easier debugging and greater
visibility.</p>

<p>The following filter configuration only accepts events which contain the string "Payment" in
the logger name.</p>

<pre class="prettyprint linenums"><![CDATA[
<filter class="LoggerFilterNameMatch">
<param name="StringToMatch" value="Payment" />
<param name="AcceptOnMatch" value="true" />
</filter>
<filter class="LoggerFilterDenyAll" />
]]></pre>

</subsection>
Expand Down
Loading