php - logger - Registro de seguimiento de pila completo con Monolog
monolog symfony (8)
¡Tengo una solución muy simple!
$mylogger->error((string) $exception);
Uso Monolog como una biblioteca independiente en mi aplicación y recientemente encontré un problema. Digamos que, en algún momento de mi aplicación, capté una excepción y quiero iniciar sesión:
$mylogger->error(''Exception caught'', array(''exception'' => $exception));
Esto funciona perfectamente, excepto una pequeña cosa: no registra el seguimiento de la pila completa. ¿Es posible registrar la traza completa de la pila de la excepción usando formateadores integrados de monólogo?
Añadiendo a la respuesta de Tomasz Madeyski , así es como puedes usarlo solo por código:
use Monolog/Logger;
use Monolog/Handler/StreamHandler;
use Monolog/ErrorHandler;
use Monolog/Formatter/LineFormatter;
$formatter = new LineFormatter(LineFormatter::SIMPLE_FORMAT, LineFormatter::SIMPLE_DATE);
$formatter->includeStacktraces(true); // <--
$stream = new StreamHandler(''error.log'');
$stream->setFormatter($formatter);
$logger = new Logger(''logger'');
$logger->pushHandler($stream);
Así es como lo hago, sí, años después ...
$mylogger->error(''Exception caught'', $exception->getTrace());
ya que getTrace () devuelve una matriz, que es lo que quiere Monolog.
En realidad, desde la versión 1.12.0
es posible incluir stacktrace en su archivo de registro: hay un nuevo método de LineFormatter
llamado includeStacktraces
.
Para utilizar esto, debe sobrescribir el comportamiento predeterminado del formateador de monólogos:
config.yml
monolog:
handlers:
main:
formatter: your.monolog.service.id
(rest of config is as usual)
services.yml
services:
your.monolog.service.id:
class: Monolog/Formatter/LineFormatter
calls:
- [includeStacktraces]
Ver github para más información: solicitud de extracción
La respuesta alcista funciona , pero no está obligado a crear un servicio personalizado para eso.
monolog.formatter.line
ya existe en la pila completa de Symfony 3.4. Simplemente puede agregar una llamada de método gracias a CompilerPassInterface
:
use Symfony/Component/DependencyInjection/Compiler/CompilerPassInterface;
use Symfony/Component/DependencyInjection/ContainerBuilder;
use use Symfony/Component/HttpKernel/Kernel;
class AppKernel extends Kernel implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$container->getDefinition(''monolog.formatter.line'')->addMethodCall(''includeStacktraces'');
}
}
El manejador de monólogos no parece recibir el servicio de manera predeterminada, por lo que aún debe especificarlo. Ejemplo:
monolog:
handlers:
main:
type: rotating_file
max_files: 12
date_format: ''Y-m''
path: ''%kernel.logs_dir%/%kernel.environment%.log''
level: debug
formatter: monolog.formatter.line
No, no puede registrar el seguimiento de la pila con los formateadores incorporados. Vea mi pregunta here .
Si echa un vistazo a LineFormatter.php
, verá que el método normalizeException
es responsable de captar los datos de excepción. Entonces, tuve que crear un nuevo formateador que ampliara LineFormatter
. Aquí está el código:
<?php
namespace Monolog/Formatter;
use Exception;
class ExceptionLineFormatter extends LineFormatter
{
protected function normalizeException(Exception $e)
{
return ''Message: '' . $e->getMessage() .
''Stack Trace: ''. $e->getTraceAsString();
}
}
Y inicié mi registrador de esta manera:
$logFile = ''MyLogFile.txt'';
$handler = new StreamHandler($logFile);
$handler->setFormatter(new ExceptionLineFormatter);
$log = new Logger(''MyLogger'');
$handler = self::getStreamHander();
$log->pushHandler($handler);
Esto imprimirá tu rastro de pila.
Si desea registrar stacktrace solo cuando se lanza Exception, puede hacerlo en el AppServiceProvider
:
public function register()
{
$logger = Log::getMonolog();
$logger->pushProcessor(function ($record) {
if (isset($record[''context''][''exception'']))
{
$record[''extra''][''stacktrace''] = $record[''context''][''exception'']->getTraceAsString();
}
return $record;
});
}
Esto agregará stacktrace a extra
columna extra
, que luego se puede usar por LineFormatter
getTraceAsString le dará la matriz Stack Trace como una cadena delimitada por ''End of Line''. Explotar en PHP_EOL y luego foreach a través de la matriz de registro de cada elemento. Espero que esto ayude.
<?php
function test() {
throw new Exception;
}
try {
test();
} catch(Exception $e) {
$array = explode(PHP_EOL, $e->getTraceAsString());
foreach($array as $line){
$mylogger->error($line);
}
Debería producir algo como esto:
#0 index.php(14): test()
#1 {main}