2015-08-17 17:00:26 -07:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Console\Logger ;
use Psr\Log\AbstractLogger ;
use Psr\Log\InvalidArgumentException ;
use Psr\Log\LogLevel ;
use Symfony\Component\Console\Output\ConsoleOutputInterface ;
2018-11-23 12:29:20 +00:00
use Symfony\Component\Console\Output\OutputInterface ;
2015-08-17 17:00:26 -07:00
/**
2015-10-08 11:40:12 -07:00
* PSR - 3 compliant console logger .
2015-08-17 17:00:26 -07:00
*
* @ author Kévin Dunglas < dunglas @ gmail . com >
2015-10-08 11:40:12 -07:00
*
2017-02-02 16:28:38 -08:00
* @ see http :// www . php - fig . org / psr / psr - 3 /
2015-08-17 17:00:26 -07:00
*/
class ConsoleLogger extends AbstractLogger
{
const INFO = 'info' ;
const ERROR = 'error' ;
private $output ;
private $verbosityLevelMap = array (
LogLevel :: EMERGENCY => OutputInterface :: VERBOSITY_NORMAL ,
LogLevel :: ALERT => OutputInterface :: VERBOSITY_NORMAL ,
LogLevel :: CRITICAL => OutputInterface :: VERBOSITY_NORMAL ,
LogLevel :: ERROR => OutputInterface :: VERBOSITY_NORMAL ,
LogLevel :: WARNING => OutputInterface :: VERBOSITY_NORMAL ,
LogLevel :: NOTICE => OutputInterface :: VERBOSITY_VERBOSE ,
LogLevel :: INFO => OutputInterface :: VERBOSITY_VERY_VERBOSE ,
LogLevel :: DEBUG => OutputInterface :: VERBOSITY_DEBUG ,
);
private $formatLevelMap = array (
LogLevel :: EMERGENCY => self :: ERROR ,
LogLevel :: ALERT => self :: ERROR ,
LogLevel :: CRITICAL => self :: ERROR ,
LogLevel :: ERROR => self :: ERROR ,
LogLevel :: WARNING => self :: INFO ,
LogLevel :: NOTICE => self :: INFO ,
LogLevel :: INFO => self :: INFO ,
LogLevel :: DEBUG => self :: INFO ,
);
2018-11-23 12:29:20 +00:00
private $errored = false ;
2015-08-17 17:00:26 -07:00
public function __construct ( OutputInterface $output , array $verbosityLevelMap = array (), array $formatLevelMap = array ())
{
$this -> output = $output ;
$this -> verbosityLevelMap = $verbosityLevelMap + $this -> verbosityLevelMap ;
$this -> formatLevelMap = $formatLevelMap + $this -> formatLevelMap ;
}
/**
* { @ inheritdoc }
*/
public function log ( $level , $message , array $context = array ())
{
if ( ! isset ( $this -> verbosityLevelMap [ $level ])) {
throw new InvalidArgumentException ( sprintf ( 'The log level "%s" does not exist.' , $level ));
}
2018-11-23 12:29:20 +00:00
$output = $this -> output ;
2015-08-17 17:00:26 -07:00
// Write to the error output if necessary and available
2018-11-23 12:29:20 +00:00
if ( self :: ERROR === $this -> formatLevelMap [ $level ]) {
if ( $this -> output instanceof ConsoleOutputInterface ) {
$output = $output -> getErrorOutput ();
}
$this -> errored = true ;
2015-08-17 17:00:26 -07:00
}
2018-11-23 12:29:20 +00:00
// the if condition check isn't necessary -- it's the same one that $output will do internally anyway.
// We only do it for efficiency here as the message formatting is relatively expensive.
2015-08-17 17:00:26 -07:00
if ( $output -> getVerbosity () >= $this -> verbosityLevelMap [ $level ]) {
2018-11-23 12:29:20 +00:00
$output -> writeln ( sprintf ( '<%1$s>[%2$s] %3$s</%1$s>' , $this -> formatLevelMap [ $level ], $level , $this -> interpolate ( $message , $context )), $this -> verbosityLevelMap [ $level ]);
2015-08-17 17:00:26 -07:00
}
}
2018-11-23 12:29:20 +00:00
/**
* Returns true when any messages have been logged at error levels .
*
* @ return bool
*/
public function hasErrored ()
{
return $this -> errored ;
}
2015-08-17 17:00:26 -07:00
/**
2015-10-08 11:40:12 -07:00
* Interpolates context values into the message placeholders .
2015-08-17 17:00:26 -07:00
*
* @ author PHP Framework Interoperability Group
*
* @ param string $message
* @ param array $context
*
* @ return string
*/
private function interpolate ( $message , array $context )
{
2018-11-23 12:29:20 +00:00
if ( false === strpos ( $message , '{' )) {
return $message ;
}
$replacements = array ();
2015-08-17 17:00:26 -07:00
foreach ( $context as $key => $val ) {
2018-11-23 12:29:20 +00:00
if ( null === $val || is_scalar ( $val ) || ( \is_object ( $val ) && method_exists ( $val , '__toString' ))) {
$replacements [ " { { $key } } " ] = $val ;
} elseif ( $val instanceof \DateTimeInterface ) {
$replacements [ " { { $key } } " ] = $val -> format ( \DateTime :: RFC3339 );
} elseif ( \is_object ( $val )) {
$replacements [ " { { $key } } " ] = '[object ' . \get_class ( $val ) . ']' ;
} else {
$replacements [ " { { $key } } " ] = '[' . \gettype ( $val ) . ']' ;
2015-08-17 17:00:26 -07:00
}
}
2018-11-23 12:29:20 +00:00
return strtr ( $message , $replacements );
2015-08-17 17:00:26 -07:00
}
}