From: Kunal Mehta Date: Tue, 30 Dec 2014 01:42:48 +0000 (-0800) Subject: Implement support for a minimum log level in $wgDebugLogGroups X-Git-Tag: 1.31.0-rc.0~12823 X-Git-Url: http://git.cyclocoop.org/%28?a=commitdiff_plain;h=4316c8c48bece51347088783f60b8959bdf6b5d2;p=lhc%2Fweb%2Fwiklou.git Implement support for a minimum log level in $wgDebugLogGroups For some log groups, we only want to log them if they meet a certain level of severity. An example of this is the current 'memcached-serious' log group, which can be merged with the normal 'memcached' group in the future, and report at a severity of ERROR. This adds a 'level' parameter to the $wgDebugLogGroups, for example: $wgDebugLogGroups['memcached'] = array( 'destination' => '/var/log/mw/memcached.log', 'level' => \Psr\Log\LogLevel::ERROR, ); Bug: T85073 Change-Id: Ic53bc4c8e318ed188fe6f4e838e6789b3c3fd574 --- diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php index 4261c68b43..1884b5feb5 100644 --- a/includes/DefaultSettings.php +++ b/includes/DefaultSettings.php @@ -5239,9 +5239,11 @@ $wgDebugDumpSqlLength = 500; * Log destinations may be one of the following: * - false to completely remove from the output, including from $wgDebugLogFile. * - string values specifying a filename or URI. - * - associative array mapping 'destination' key to the desired filename or URI. - * The associative array may also contain a 'sample' key with an integer value, - * specifying a sampling factor. + * - associative array with keys: + * - 'destination' desired filename or URI. + * - 'sample' an integer value, specifying a sampling factor (optional) + * - 'level' A \Psr\Log\LogLevel constant, indicating the minimum level + * to log (optional, since 1.25) * * @par Example: * @code @@ -5253,6 +5255,7 @@ $wgDebugDumpSqlLength = 500; * $wgDebugLogGroups['memcached'] = array( * 'destination' => '/var/log/mediawiki/memcached.log', * 'sample' => 1000, // log 1 message out of every 1,000. + * 'level' => \Psr\Log\LogLevel::WARNING * ); * @endcode */ diff --git a/includes/debug/logger/legacy/Logger.php b/includes/debug/logger/legacy/Logger.php index a682504fb8..0737770fb8 100644 --- a/includes/debug/logger/legacy/Logger.php +++ b/includes/debug/logger/legacy/Logger.php @@ -36,13 +36,33 @@ * @author Bryan Davis * @copyright © 2014 Bryan Davis and Wikimedia Foundation. */ -class MWLoggerLegacyLogger extends \Psr\Log\AbstractLogger { +use Psr\Log\AbstractLogger; +use Psr\Log\LogLevel; + +class MWLoggerLegacyLogger extends AbstractLogger { /** * @var string $channel */ protected $channel; + /** + * Convert Psr\Log\LogLevel constants into int for sane comparisons + * These are the same values that Monlog uses + * + * @var array + */ + protected static $levelMapping = array( + LogLevel::DEBUG => 100, + LogLevel::INFO => 200, + LogLevel::NOTICE => 250, + LogLevel::WARNING => 300, + LogLevel::ERROR => 400, + LogLevel::CRITICAL => 500, + LogLevel::ALERT => 550, + LogLevel::EMERGENCY => 600, + ); + /** * @param string $channel @@ -59,7 +79,7 @@ class MWLoggerLegacyLogger extends \Psr\Log\AbstractLogger { * @param array $context */ public function log( $level, $message, array $context = array() ) { - if ( self::shouldEmit( $this->channel, $message, $context ) ) { + if ( self::shouldEmit( $this->channel, $message, $level, $context ) ) { $text = self::format( $this->channel, $message, $context ); $destination = self::destination( $this->channel, $message, $context ); self::emit( $text, $destination ); @@ -72,11 +92,12 @@ class MWLoggerLegacyLogger extends \Psr\Log\AbstractLogger { * * @param string $channel * @param string $message + * @param string|int $level Psr\Log\LogEvent constant or Monlog level int * @param array $context * @return bool True if message should be sent to disk/network, false * otherwise */ - public static function shouldEmit( $channel, $message, $context ) { + public static function shouldEmit( $channel, $message, $level, $context ) { global $wgDebugLogFile, $wgDBerrorLog, $wgDebugLogGroups; if ( $channel === 'wfLogDBError' ) { @@ -91,10 +112,19 @@ class MWLoggerLegacyLogger extends \Psr\Log\AbstractLogger { } elseif ( isset( $wgDebugLogGroups[$channel] ) ) { $logConfig = $wgDebugLogGroups[$channel]; - if ( is_array( $logConfig ) && isset( $logConfig['sample'] ) ) { - // Emit randomly with a 1 in 'sample' chance for each message. - $shouldEmit = mt_rand( 1, $logConfig['sample'] ) === 1; - + if ( is_array( $logConfig ) ) { + $shouldEmit = true; + if ( isset( $logConfig['sample'] ) ) { + // Emit randomly with a 1 in 'sample' chance for each message. + $shouldEmit = mt_rand( 1, $logConfig['sample'] ) === 1; + } + + if ( isset( $logConfig['level'] ) ) { + if ( is_string( $level ) ) { + $level = self::$levelMapping[$level]; + } + $shouldEmit = $level >= self::$levelMapping[$logConfig['level']]; + } } else { // Emit unless the config value is explictly false. $shouldEmit = $logConfig !== false; diff --git a/includes/debug/logger/monolog/Handler.php b/includes/debug/logger/monolog/Handler.php index 42ab797ade..05ac64ee25 100644 --- a/includes/debug/logger/monolog/Handler.php +++ b/includes/debug/logger/monolog/Handler.php @@ -101,7 +101,7 @@ class MWLoggerMonologHandler extends \Monolog\Handler\AbstractProcessingHandler $levelOk = parent::isHandling( $record ); if ( $levelOk && $this->useLegacyFilter ) { return MWLoggerLegacyLogger::shouldEmit( - $record['channel'], $record['message'], $record + $record['channel'], $record['message'], $record['level'], $record ); } return $levelOk; diff --git a/tests/phpunit/includes/debug/logging/legacy/LoggerTest.php b/tests/phpunit/includes/debug/logging/legacy/LoggerTest.php index 22d32706b5..66e9be4805 100644 --- a/tests/phpunit/includes/debug/logging/legacy/LoggerTest.php +++ b/tests/phpunit/includes/debug/logging/legacy/LoggerTest.php @@ -17,6 +17,7 @@ * * @file */ +use Psr\Log\LogLevel; class MWLoggerLegacyLoggerTest extends MediaWikiTestCase { @@ -66,4 +67,52 @@ class MWLoggerLegacyLoggerTest extends MediaWikiTestCase { ); } + /** + * @covers MWLoggerLegacyLogger::shouldEmit + * @dataProvider provideShouldEmit + */ + public function testShouldEmit( $level, $config, $expected ) { + $this->setMwGlobals( 'wgDebugLogGroups', array( 'fakechannel' => $config ) ); + $this->assertEquals( + $expected, + MWLoggerLegacyLogger::shouldEmit( 'fakechannel', 'some message', $level, array() ) + ); + } + + public static function provideShouldEmit() { + $dest = array( 'destination' => 'foobar' ); + $tests = array( + array( + LogLevel::DEBUG, + $dest, + true + ), + array( + LogLevel::WARNING, + $dest + array( 'level' => LogLevel::INFO ), + true, + ), + array( + LogLevel::INFO, + $dest + array( 'level' => LogLevel::CRITICAL ), + false, + ), + ); + + if ( class_exists( '\Monolog\Logger' ) ) { + $tests[] = array( + \Monolog\Logger::INFO, + $dest + array( 'level' => LogLevel::INFO ), + true, + ); + $tests[] = array( + \Monolog\Logger::WARNING, + $dest + array( 'level' => LogLevel::EMERGENCY ), + false, + ); + } + + return $tests; + } + }