Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 在Symfony 2中记录警告和通知_Php_Logging_Symfony - Fatal编程技术网

Php 在Symfony 2中记录警告和通知

Php 在Symfony 2中记录警告和通知,php,logging,symfony,Php,Logging,Symfony,在dev env中,symfony ErrorHandler捕捉到警告,这很好。在prod env中,symfony忽略警告,我只在php错误日志中得到它们。现在我希望这些错误也被记录下来 除去日志级别的油污没有起作用,因为这些错误根本没有得到处理。那么如何在Symfony prod环境中记录这些错误呢 我正在使用symfony2.0 编辑: 好的,我看到在不处于调试模式(Kernel.php)时甚至没有错误处理程序: 那么,在不违反框架的情况下实现这一点的最佳方法是什么呢?您必须通过告诉内核以

在dev env中,symfony ErrorHandler捕捉到警告,这很好。在prod env中,symfony忽略警告,我只在php错误日志中得到它们。现在我希望这些错误也被记录下来

除去日志级别的油污没有起作用,因为这些错误根本没有得到处理。那么如何在Symfony prod环境中记录这些错误呢

我正在使用symfony2.0

编辑: 好的,我看到在不处于调试模式(Kernel.php)时甚至没有错误处理程序:


那么,在不违反框架的情况下实现这一点的最佳方法是什么呢?

您必须通过告诉内核以调试模式运行来定制您的环境

new AppKernel('prod', true);
重要但与环境主题无关的是假键 在上面的前控制器的第8行。这指定是否 应用程序应在“调试模式”下运行。不顾一切 环境中,可以在调试模式设置为的情况下运行Symfony2应用程序 对或错。这会影响应用程序中的许多事情,例如 是否应显示错误,或者缓存文件是否正确 根据每个请求动态重建。虽然不是必需的,但调试 对于开发和测试环境以及 对于prod环境,为false


您可以通过实现自定义
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;
        }
    }
}
类似的事情也可以通过单独的Bundle来完成,但它可以“跳过”注册Bundle之前发生的一些错误


如果您使用
Monolog 1.6
或更高版本,还可以使用注册记录器以查找错误、未处理的异常和致命错误。

您确定没有日志吗?你看过app/logs/prod.log文件了吗?你说的是日志级别“警告”还是php抛出的警告?phpYes抛出的警告,我知道它是在调试模式下启用的,这对开发很好。但主要原因是在网站运行时发现隐藏的错误,php错误日志有时没有足够的信息,我认为最好将所有日志合并起来。对。您必须创建一个名为“prod\u custom”的自定义环境,并使用
new AppKernel(“prod\u custom”,true)创建一个app\u prod\u custom.php文件作为入口点。如果您不想破解源代码并失去更新Symfony供应商软件包的能力,Symfony必须在内核中启用调试才能处理此问题。启用调试模式不是一个选项。然后您需要“破解”内核并添加该行。该文件不会经常更改,因此您可能只需验证主要版本(2.1->2.2)之间的所有内容是否兼容即可。为了捕获所有警告,必须在脚本执行的早期注册错误处理程序。不幸的是,由于需要从容器中检索记录器,这在Kernel->boot()之前不会生效。这意味着有一个很大的时间窗口,在此期间,初始化捆绑包时发生的任何通知/警告/错误等都不会被记录。对于Symfony2来说,这是一个巨大的失误-应该尽早初始化正确的错误/异常日志处理程序<代码>公共函数boot(){parent::boot();$logger=$this->container->get('logger');\monog\ErrorHandler::register($logger);}
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;
        }
    }
}