2012-02-16 17 views
11

Por qué no se registran los errores de las tareas de la consola. Por ejemplo Excepción sobre alerta php:Symfony 2 Excepciones de registro en la consola

[ErrorException]
Notice: Undefined offset: 1 in /var/www/project/vendor/doctrine/lib/Doctrine/ORM/Query.php line 298

veo lo imprime en la salida estándar, pero nada conectado a los registros. (Utilizo comandos de consola en cron). En la Web, estas excepciones se registran con trazas inversas, que en esta situación es más informativo que solo esta excepción.

Como una solución: encierre toda la función de proceso en el bloque try..catch y registre la ruta de retroceso manualmente.

¿Alguien sabe cómo habilitar o configurar el registro en tareas de la consola. Creo que debe estar en alguna parte.

Respuesta

14

Como seguí el código, en realidad no existe una opción para habilitar el registro de comandos. En app/console es este código:

use Symfony\Bundle\FrameworkBundle\Console\Application; 

... 

$application = new Application($kernel); 
$application->run(); 

Se llama Symfony\Component\Console\Application::run() en el que no hay bloque try/catch. Se llama al método de excepción renderException(), pero no se registra en ningún lugar.

También tenga en cuenta que app/console siempre sale de forma predeterminada con el código de error en la excepción.

Puede crear su propia clase Application extendiendo Symfony\Bundle\FrameworkBundle\Console\Application y modificar app/console para usarla. Entonces puede anular el método run() y agregar el registro de errores.

o puede modificar simplemente app/console y manejar erros como este:

// $application->run(); 
$application->setCatchExceptions(false); 
try { 
    $output = new Symfony\Component\Console\Output\ConsoleOutput(); 
    $application->run(null, $output); 
} catch (Exception $e) { 
    ... error logging ... 

    $application->renderException($e, $output); 

    $statusCode = $e->getCode(); 
    $statusCode = is_numeric($statusCode) && $statusCode ? $statusCode : 1; 
    exit($statusCode); 
} 
+0

Gracias por su explicación. Busco en los archivos de inicio console & index.php pero debería profundizar en la clase de aplicación. Pero parece que las clases de aplicaciones en la web y la consola comparten el mismo comportamiento. – Sawered

2

Otra forma es poner en práctica su propia clase personalizada OutputInterface y reemplazar el método writeln a registrar el error allí. Luego use la nueva clase cuando ejecute el método run().

De esta forma puede adherirse al Open/Close Principle de Symfony sin tener que modificar las clases base y aun así lograr sus objetivos.

6

TL; DR: sólo tiene que utilizar this bundle

Desde el cookbook:

para obtener su aplicación de consola para iniciar sesión automáticamente excepciones no capturadas para todos sus comandos, puede utilizar la consola de eventos.

Crear un servicio de etiquetado como un detector de eventos para el evento console.exception:

# services.yml 
services: 
    kernel.listener.command_dispatch: 
    class: Acme\DemoBundle\EventListener\ConsoleExceptionListener 
    arguments: 
     logger: "@logger" 
    tags: 
     - { name: kernel.event_listener, event: console.exception } 

Ahora puede hacer lo que quiera con excepciones consola:

<?php 
// src/Acme/DemoBundle/EventListener/ConsoleExceptionListener.php 
namespace Acme\DemoBundle\EventListener; 

use Symfony\Component\Console\Event\ConsoleExceptionEvent; 
use Psr\Log\LoggerInterface; 

class ConsoleExceptionListener 
{ 
    private $logger; 

    public function __construct(LoggerInterface $logger) 
    { 
    $this->logger = $logger; 
    } 

    public function onConsoleException(ConsoleExceptionEvent $event) 
    { 
    $command = $event->getCommand(); 
    $exception = $event->getException(); 

    $message = sprintf(
     '%s: %s (uncaught exception) at %s line %s while running console command `%s`', 
     get_class($exception), 
     $exception->getMessage(), 
     $exception->getFile(), 
     $exception->getLine(), 
     $command->getName() 
    ); 

    $this->logger->error($message); 
    } 
} 
+0

Sí, desde Symfony 2.3 esta es una mejor solución. – Martin

6

Si ese es el asunto de simplemente entendiendo qué salió mal, puede ejecutar su aplicación con la bandera detallada -v o --verbose, que mostrará automatically print the exception trace en la pantalla.

+0

Tiene razón, pero la pregunta era sobre escribir errores para registrar (por ejemplo, en el archivo) Fue necesario cuando ejecuto cli comandos de cron – Sawered

+0

Es cierto, lo siento, se perdió la parte de cron. No pude entender cómo llegar al backtrace sin complicarlo demasiado, decidí compartir los hallazgos. –

+1

@IanBytchek, gracias de todos modos, ¡tu respuesta me ayudó mucho! –