namespace MediaWiki\Logger;
use DateTimeZone;
+use Exception;
use MWDebug;
use MWExceptionHandler;
use Psr\Log\AbstractLogger;
* See documentation in DefaultSettings.php for detailed explanations of each
* variable.
*
- * @see \\MediaWiki\\Logger\\LoggerFactory
+ * @see \MediaWiki\Logger\LoggerFactory
* @since 1.25
* @author Bryan Davis <bd808@wikimedia.org>
* @copyright © 2014 Bryan Davis and Wikimedia Foundation.
protected $channel;
/**
- * Convert Psr\\Log\\LogLevel constants into int for sane comparisons
+ * Convert \Psr\Log\LogLevel constants into int for sane comparisons
* These are the same values that Monlog uses
*
* @var array $levelMapping
*/
- protected static $levelMapping = array(
+ protected static $levelMapping = [
LogLevel::DEBUG => 100,
LogLevel::INFO => 200,
LogLevel::NOTICE => 250,
LogLevel::CRITICAL => 500,
LogLevel::ALERT => 550,
LogLevel::EMERGENCY => 600,
- );
-
+ ];
/**
* @param string $channel
* @param string $message
* @param array $context
*/
- public function log( $level, $message, array $context = array() ) {
+ public function log( $level, $message, array $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 );
}
- // Add to debug toolbar
- MWDebug::debugMsg( $message, array( 'channel' => $this->channel ) + $context );
+ if ( !isset( $context['private'] ) || !$context['private'] ) {
+ // Add to debug toolbar if not marked as "private"
+ MWDebug::debugMsg( $message, [ 'channel' => $this->channel ] + $context );
+ }
}
-
/**
* Determine if the given message should be emitted or not.
*
* @param string $channel
* @param string $message
- * @param string|int $level Psr\\Log\\LogEvent constant or Monlog level int
+ * @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
// All messages on the wfErrorLog channel should be emitted.
$shouldEmit = true;
+ } elseif ( $channel === 'wfDebug' ) {
+ // wfDebug messages are emitted if a catch all logging file has
+ // been specified. Checked explicitly so that 'private' flagged
+ // messages are not discarded by unset $wgDebugLogGroups channel
+ // handling below.
+ $shouldEmit = $wgDebugLogFile != '';
+
} elseif ( isset( $wgDebugLogGroups[$channel] ) ) {
$logConfig = $wgDebugLogGroups[$channel];
return $shouldEmit;
}
-
/**
* Format a message.
*
}
// Append stacktrace of exception if available
- if ( $wgLogExceptionBacktrace &&
- isset( $context['exception'] ) &&
- $context['exception'] instanceof Exception
- ) {
- $text .= MWExceptionHandler::getRedactedTraceAsString(
- $context['exception']->getTraceAsString()
- ) . "\n";
+ if ( $wgLogExceptionBacktrace && isset( $context['exception'] ) ) {
+ $e = $context['exception'];
+ $backtrace = false;
+
+ if ( $e instanceof Exception ) {
+ $backtrace = MWExceptionHandler::getRedactedTrace( $e );
+
+ } elseif ( is_array( $e ) && isset( $e['trace'] ) ) {
+ // Exception has already been unpacked as structured data
+ $backtrace = $e['trace'];
+ }
+
+ if ( $backtrace ) {
+ $text .= MWExceptionHandler::prettyPrintTrace( $backtrace ) .
+ "\n";
+ }
}
return self::interpolate( $text, $context );
}
-
/**
* Format a message as `wfDebug()` would have formatted it.
*
return "{$text}\n";
}
-
/**
* Format a message as `wfLogDBError()` would have formatted it.
*
$cachedTimezone = new DateTimeZone( $wgDBerrorLogTZ );
}
- // Workaround for https://bugs.php.net/bug.php?id=52063
- // Can be removed when min PHP > 5.3.6
- if ( $cachedTimezone === null ) {
- $d = date_create( 'now' );
- } else {
- $d = date_create( 'now', $cachedTimezone );
- }
+ $d = date_create( 'now', $cachedTimezone );
$date = $d->format( 'D M j G:i:s T Y' );
$host = wfHostname();
return $text;
}
-
/**
* Format a message as `wfDebugLog() would have formatted it.
*
return $text;
}
-
/**
* Interpolate placeholders in logging message.
*
*/
public static function interpolate( $message, array $context ) {
if ( strpos( $message, '{' ) !== false ) {
- $replace = array();
+ $replace = [];
foreach ( $context as $key => $val ) {
$replace['{' . $key . '}'] = self::flatten( $val );
}
return $message;
}
-
/**
* Convert a logging context element to a string suitable for
* interpolation.
}
if ( is_scalar( $item ) ) {
- return (string) $item;
+ return (string)$item;
}
if ( is_array( $item ) ) {
return $item->format( 'c' );
}
- if ( $item instanceof \Exception ) {
+ if ( $item instanceof Exception ) {
return '[Exception ' . get_class( $item ) . '( ' .
$item->getFile() . ':' . $item->getLine() . ') ' .
$item->getMessage() . ']';
if ( is_object( $item ) ) {
if ( method_exists( $item, '__toString' ) ) {
- return (string) $item;
+ return (string)$item;
}
return '[Object ' . get_class( $item ) . ']';
return '[Unknown ' . gettype( $item ) . ']';
}
-
/**
* Select the appropriate log output destination for the given log event.
*
return $destination;
}
-
/**
* Log to a file without getting "file size exceeded" signals.
*