2012-02-16 18 views
11

Tại sao lỗi từ nhiệm vụ bảng điều khiển không được ghi lại. Ví dụ ngoại lệ cảnh báo php:Symfony 2 Ghi nhật ký ngoại lệ trong bảng điều khiển

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

tôi xem những gì in stdout, nhưng không đăng nhập vào các bản ghi. (Tôi sử dụng lệnh console trong cron). Trong trang web, các trường hợp ngoại lệ này được ghi lại bằng backtrace, trong trường hợp này có nhiều thông tin hơn ngoại lệ này.

Là giải pháp: Tôi đính kèm tất cả các chức năng quy trình trong khối try..catch và đăng nhập ngược theo cách thủ công.

Có ai biết cách bật hoặc định cấu hình ghi nhật ký trong các tác vụ của bảng điều khiển. Tôi nghĩ nó phải ở đâu đó.

Trả lời

14

Khi tôi theo mã, thực sự không có tùy chọn nào để bật ghi nhật ký lệnh. Trong app/console là mã này:

use Symfony\Bundle\FrameworkBundle\Console\Application; 

... 

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

Nó kêu gọi Symfony\Component\Console\Application::run() trong đó có try/catch block. Trên phương thức ngoại lệ, renderException() được gọi, nhưng không có ghi nhật ký nào xảy ra ở bất kỳ đâu.

Cũng lưu ý rằng app/console luôn theo mặc định thoát với mã lỗi ngoại lệ.

Bạn có thể tạo bạn sở hữu Application mở rộng lớp Symfony\Bundle\FrameworkBundle\Console\Application và sửa đổi app/console để sử dụng. Hơn bạn có thể ghi đè lên phương thức run() và thêm ghi nhật ký lỗi.

Hoặc bạn có thể thay đổi chỉ app/console và xử lý erros như thế này:

// $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

Cảm ơn bạn đã giải thích. Tôi đào sâu vào các tập tin khởi động console & index.php nhưng nên đào sâu hơn trong lớp Ứng dụng. Nhưng có vẻ như các lớp ứng dụng trong web và bảng điều khiển chia sẻ cùng một hành vi. – Sawered

2

Một cách khác là thực hiện riêng lớp tùy chỉnh OutputInterface của bạn và ghi đè lên writeln phương pháp để ghi lại các lỗi đó. Sau đó, sử dụng lớp mới khi bạn thực hiện phương thức run().

Bằng cách này bạn có thể tuân thủ Open/Close Principle của Symfony mà không phải sửa đổi các lớp cơ sở và vẫn đạt được mục tiêu của mình.

6

TL; DR: chỉ cần sử dụng this bundle

Từ cookbook:

Để có được ứng dụng giao diện điều khiển của bạn để tự động đăng nhập ngoại lệ còn tự do cho tất cả các lệnh của bạn, bạn có thể sử dụng giao diện điều khiển các sự kiện.

Tạo một dịch vụ được gắn thẻ như là một người biết lắng nghe sự kiện cho sự kiện 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 } 

Bây giờ bạn có thể làm bất cứ điều gì bạn muốn với giao diện điều khiển ngoại lệ:

<?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

Có, vì Symfony 2.3 đây là một giải pháp tốt hơn. – Martin

6

Nếu đó là vấn đề của đơn giản hiểu những gì đã xảy ra ở đâu, bạn có thể chạy ứng dụng của mình với cờ dài -v hoặc --verbose, sẽ automatically print the exception trace trên màn hình.

+0

Bạn nói đúng, nhưng câu hỏi là viết lỗi để đăng nhập (ví dụ: trong tập tin) Nó là cần thiết khi tôi chạy lệnh cli từ cron – Sawered

+0

Đúng, xin lỗi, đã bỏ qua phần cron. Không thể tìm ra cách để có được backtrace mà không làm phức tạp nó quá nhiều, quyết định chia sẻ những phát hiện. –

+1

@IanBytchek, cảm ơn bạn, câu trả lời của bạn đã giúp tôi rất nhiều! –