Johni
Johni

Reputation: 2961

Log warnings and notices in Symfony 2

In the dev env warnings are catched by the symfony ErrorHandler which is fine. In the prod env symfony ignores warnings and I only get them in the php error log. Now I want those errors also to be logged.

Degreasing the log level didn't worked since those errors arn't handled at all. So how can I log those errors in Symfony prod environment?

I'm using Symfony 2.0

Edit: Ok, I see there isn't even a error handler when not in debug mode (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);
}

So what's the best way to implement this without working against the framework?

Upvotes: 4

Views: 10995

Answers (2)

Marius Balčytis
Marius Balčytis

Reputation: 2651

You could do this by implementing custom ErrorHandler and overriding some of AppKernel methods. For example:

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;
        }
    }
}

Something similar can be done with separate Bundle too, but it can "skip" some of errors occurred before bundle is registered.

If you use Monolog 1.6 or later, you can also use Monolog\ErrorHandler to register logger for errors, unhandled exceptions and fatal errors.

Upvotes: 2

james_t
james_t

Reputation: 2733

You will have to customize your environment to do this by telling the kernel to run in debug mode.

new AppKernel('prod', true);

Important, but unrelated to the topic of environments is the false key on line 8 of the front controller above. This specifies whether or not the application should run in "debug mode". Regardless of the environment, a Symfony2 application can be run with debug mode set to true or false. This affects many things in the application, such as whether or not errors should be displayed or if cache files are dynamically rebuilt on each request. Though not a requirement, debug mode is generally set to true for the dev and test environments and false for the prod environment.

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

Upvotes: 0

Related Questions