4

dev envでは、警告はsymfonyErrorHandlerによってキャッチされます。これは問題ありません。prod envでは、symfonyは警告を無視し、phpエラーログでのみ警告を取得します。今、私はそれらのエラーもログに記録したいと思います。

これらのエラーはまったく処理されないため、ログレベルの脱脂は機能しませんでした。では、Symfonyのprod環境でこれらのエラーをログに記録するにはどうすればよいですか?

私はSymfony2.0を使用しています

編集:わかりました。デバッグモード(Kernel.php)でない場合は、エラーハンドラーすらありません。

if ($this->debug) {
        ini_set('display_errors', 1);
        error_reporting(-1);

        DebugUniversalClassLoader::enable();
        ErrorHandler::register();
        if ('cli' !== php_sapi_name()) {
            ExceptionHandler::register();
        }
} else {
    ini_set('display_errors', 0);
}

では、フレームワークに逆らうことなくこれを実装するための最良の方法は何でしょうか?

4

2 に答える 2

2

カスタムを実装し、いくつかのメソッドErrorHandlerをオーバーライドすることで、これを行うことができます。AppKernel例えば:

class AppKernel
{
    protected $prodErrorHandler;
    public function init()
    {
        if ($this->debug) {
            ini_set('display_errors', 1);
            error_reporting(-1);

            DebugUniversalClassLoader::enable();
            ErrorHandler::register();
            if ('cli' !== php_sapi_name()) {
                ExceptionHandler::register();
            }
        } else {
            ini_set('display_errors', 0);
            error_reporting(-1);
            $this->prodErrorHandler = new CustomErrorHandler();
            set_error_handler(array($this->prodErrorHandler, 'handle'));
        }
    }
    public function boot()
    {
        $booted = $this->booted;
        parent::boot();
        if (!$booted && $this->prodErrorHandler !== null && $this->container->has('logger')) {
            $this->prodErrorHandler->setLogger($this->container->get('logger'));
        }
    }
    // ... other methods
}
class CustomErrorHandler
{
    protected $logger;
    protected $buffer = array();
    public function setLogger($logger)
    {
        $this->logger = $logger;
        foreach ($this->buffer as $error) {
            $this->logger->warning($error);
        }
        $this->buffer = array();
    }
    public function handle($level, $message, $file, $line, $context)
    {
        if (error_reporting() & $level) {
            $error = new \ErrorException(sprintf('%s: %s in %s line %d', isset($this->levels[$level]) ? $this->levels[$level] : $level, $message, $file, $line));
            if ($this->logger !== null) {
                $this->logger->warning($error);
            } else {
                $this->buffer[] = $error;
            }
            return true;    // this would skip logging to file etc. Return false to just log and pass error handling to other handlers
        } else {
            return false;
        }
    }
}

別のバンドルでも同様のことができますが、バンドルが登録される前に発生したエラーの一部を「スキップ」できます。

Monolog 1.6またはそれ以降を使用する場合はMonolog\ErrorHandler、エラー、未処理の例外、および致命的なエラーのロガーを登録するために使用することもできます。

于 2013-11-05T08:44:07.807 に答える
0

これを行うには、カーネルにデバッグモードで実行するように指示して、環境をカスタマイズする必要があります。

new AppKernel('prod', true);

重要ですが、環境のトピックとは無関係に、上記のフロントコントローラーの8行目にある偽のキーがあります。これは、アプリケーションを「デバッグモード」で実行するかどうかを指定します。環境に関係なく、Symfony2アプリケーションはデバッグモードをtrueまたはfalseに設定して実行できます。これは、エラーを表示するかどうかや、リクエストごとにキャッシュファイルを動的に再構築するかどうかなど、アプリケーションの多くのことに影響します。要件ではありませんが、デバッグモードは通常、開発環境とテスト環境ではtrueに設定され、prod環境ではfalseに設定されます。

http://symfony.com/doc/2.0/cookbook/configuration/environments.html

于 2013-03-05T19:13:20.747 に答える