LOG4PHP-188: Events logged by upstream loggers even if disabled by level. git-svn-id: https://svn.apache.org/repos/asf/logging/log4php/trunk@1395241 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/src/changes/changes.xml b/src/changes/changes.xml index a4a9790..8540961 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml
@@ -21,6 +21,7 @@ </properties> <body> <release version="2.3.0" date="SVN"> + <action date="2012-10-07" type="fix" issue="LOG4PHP-188" dev="Ivan Habunek">Events logged by upstream loggers even if disabled by level.</action> <action date="2012-10-06" type="update" issue="LOG4PHP-186" dev="Ivan Habunek" due-to="Rasmus Lerdorf" due-to-email="rasmus at lerdorf dot com">Don't clear the entire stat cache on an append.</action> <action date="2012-10-06" type="add" issue="LOG4PHP-141" dev="Ivan Habunek">Allow setting of a default renderer.</action> <action date="2012-09-08" type="update" issue="LOG4PHP-120" dev="Ivan Habunek" due-to="Michal Vanek" due-to-email="michal dot vanek at gmail dot com">Fixed LoggerAppenderDailyFile to rollover on date change in long running scipts.</action>
diff --git a/src/main/php/Logger.php b/src/main/php/Logger.php index 08e6704..9751f59 100644 --- a/src/main/php/Logger.php +++ b/src/main/php/Logger.php
@@ -170,7 +170,34 @@ */ public function log(LoggerLevel $level, $message, $throwable = null) { if($this->isEnabledFor($level)) { - $this->forcedLog($this->fqcn, $throwable, $level, $message); + $event = new LoggerLoggingEvent($this->fqcn, $this, $level, $message, null, $throwable); + $this->callAppenders($event); + } + + // Forward the event upstream if additivity is turned on + if(isset($this->parent) && $this->getAdditivity()) { + + // Use the event if already created + if (isset($event)) { + $this->parent->logEvent($event); + } else { + $this->parent->log($level, $message, $throwable); + } + } + } + + /** + * Logs an already prepared logging event object. + * @param LoggerLoggingEvent $event + */ + public function logEvent(LoggerLoggingEvent $event) { + if($this->isEnabledFor($event->getLevel())) { + $this->callAppenders($event); + } + + // Forward the event upstream if additivity is turned on + if(isset($this->parent) && $this->getAdditivity()) { + $this->parent->logEvent($event); } } @@ -202,8 +229,24 @@ * @param mixed $message message to log */ public function forcedLog($fqcn, $throwable, LoggerLevel $level, $message) { - $this->callAppenders(new LoggerLoggingEvent($fqcn, $this, $level, $message, null, $throwable)); - } + $event = new LoggerLoggingEvent($fqcn, $this, $level, $message, null, $throwable); + $this->callAppenders($event); + + // Forward the event upstream if additivity is turned on + if(isset($this->parent) && $this->getAdditivity()) { + $this->parent->logEvent($event); + } + } + + /** + * Forwards the given logging event to all linked appenders. + * @param LoggerLoggingEvent $event + */ + public function callAppenders($event) { + foreach($this->appenders as $appender) { + $appender->doAppend($event); + } + } // ****************************************** // *** Checker methods *** @@ -302,22 +345,6 @@ } /** - * Forwards the given logging event to all linked appenders. - * @param LoggerLoggingEvent $event - */ - public function callAppenders($event) { - // Forward the event to each linked appender - foreach($this->appenders as $appender) { - $appender->doAppend($event); - } - - // Forward the event upstream if additivity is turned on - if(isset($this->parent) && $this->getAdditivity()) { - $this->parent->callAppenders($event); - } - } - - /** * Returns the appenders linked to this logger as an array. * @return array collection of appender names */
diff --git a/src/test/php/LoggerTest.php b/src/test/php/LoggerTest.php index a4629e8..145ac20 100644 --- a/src/test/php/LoggerTest.php +++ b/src/test/php/LoggerTest.php
@@ -27,6 +27,88 @@ */ class LoggerTest extends PHPUnit_Framework_TestCase { + private $testConfig1 = array ( + 'rootLogger' => array ( + 'level' => 'ERROR', + 'appenders' => array ( + 'default', + ), + ), + 'appenders' => array ( + 'default' => array ( + 'class' => 'LoggerAppenderEcho', + ), + ), + 'loggers' => array ( + 'mylogger' => array ( + 'additivity' => 'false', + 'level' => 'DEBUG', + 'appenders' => array ( + 'default', + ), + ), + ), + ); + + // For testing additivity + private $testConfig2 = array ( + 'appenders' => array ( + 'default' => array ( + 'class' => 'LoggerAppenderEcho', + ), + ), + 'rootLogger' => array( + 'appenders' => array('default'), + ), + 'loggers' => array ( + 'foo' => array ( + 'appenders' => array ( + 'default', + ), + ), + 'foo.bar' => array ( + 'appenders' => array ( + 'default', + ), + ), + 'foo.bar.baz' => array ( + 'appenders' => array ( + 'default', + ), + ), + ), + ); + + // For testing additivity + private $testConfig3 = array ( + 'appenders' => array ( + 'default' => array ( + 'class' => 'LoggerAppenderEcho', + ), + ), + 'rootLogger' => array( + 'appenders' => array('default'), + ), + 'loggers' => array ( + 'foo' => array ( + 'appenders' => array ( + 'default', + ), + ), + 'foo.bar' => array ( + 'appenders' => array ( + 'default', + ), + ), + 'foo.bar.baz' => array ( + 'level' => 'ERROR', + 'appenders' => array ( + 'default', + ), + ), + ), + ); + protected function setUp() { Logger::clear(); Logger::resetConfiguration(); @@ -54,7 +136,7 @@ } public function testCanLogToAllLevels() { - Logger::configure(dirname(__FILE__) . '/LoggerTest.properties'); + Logger::configure($this->testConfig1); $logger = Logger::getLogger('mylogger'); ob_start(); @@ -63,7 +145,6 @@ $logger->error('this is an error'); $logger->debug('this is a debug message'); $logger->fatal('this is a fatal message'); - $v = ob_get_contents(); ob_end_clean(); @@ -77,17 +158,25 @@ } public function testIsEnabledFor() { - Logger::configure(dirname(__FILE__) . '/LoggerTest.properties'); + Logger::configure($this->testConfig1); $logger = Logger::getLogger('mylogger'); + self::assertFalse($logger->isTraceEnabled()); self::assertTrue($logger->isDebugEnabled()); self::assertTrue($logger->isInfoEnabled()); + self::assertTrue($logger->isWarnEnabled()); + self::assertTrue($logger->isErrorEnabled()); + self::assertTrue($logger->isFatalEnabled()); $logger = Logger::getRootLogger(); + self::assertFalse($logger->isTraceEnabled()); self::assertFalse($logger->isDebugEnabled()); self::assertFalse($logger->isInfoEnabled()); + self::assertFalse($logger->isWarnEnabled()); + self::assertTrue($logger->isErrorEnabled()); + self::assertTrue($logger->isFatalEnabled()); } public function testGetCurrentLoggers() { @@ -96,10 +185,39 @@ self::assertEquals(0, count(Logger::getCurrentLoggers())); - Logger::configure(dirname(__FILE__) . '/LoggerTest.properties'); + Logger::configure($this->testConfig1); self::assertEquals(1, count(Logger::getCurrentLoggers())); $list = Logger::getCurrentLoggers(); self::assertEquals('mylogger', $list[0]->getName()); } - + + public function testAdditivity() { + Logger::configure($this->testConfig2); + + $logger = Logger::getLogger('foo.bar.baz'); + ob_start(); + $logger->info('test'); + $actual = ob_get_contents(); + ob_end_clean(); + + // The message should get logged 4 times: once by every logger in the + // hierarchy (including root) + $expected = str_repeat('INFO - test' . PHP_EOL, 4); + self::assertSame($expected, $actual); + } + + public function testAdditivity2() { + Logger::configure($this->testConfig3); + + $logger = Logger::getLogger('foo.bar.baz'); + ob_start(); + $logger->info('test'); + $actual = ob_get_contents(); + ob_end_clean(); + + // The message should get logged 3 times: once by every logger in the + // hierarchy, except foo.bar.baz which is set to level ERROR + $expected = str_repeat('INFO - test' . PHP_EOL, 3); + self::assertSame($expected, $actual); + } }
diff --git a/src/test/php/LoggerTest.properties b/src/test/php/LoggerTest.properties deleted file mode 100644 index ea5fd36..0000000 --- a/src/test/php/LoggerTest.properties +++ /dev/null
@@ -1,21 +0,0 @@ -; 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.appender.loggertestdefault = LoggerAppenderEcho -log4php.appender.loggertestdefault.layout = LoggerLayoutSimple - -log4php.additivity.mylogger= "false" -log4php.logger.mylogger = DEBUG, loggertestdefault -log4php.rootLogger = ERROR, loggertestdefault