Home » Php » php – How to output exception information in log file with log4php?

php – How to output exception information in log file with log4php?

Posted by: admin July 12, 2020 Leave a comment

Questions:

I have set up log4php to log to a file using the LoggerAppenderRollingFile appender and the LoggerLayoutTTCC layout. When I log an exception, however, it doesn’t display the exception details such as the stack trace like I’m used to seeing in log4net.

I’ve had a quick look through the code and it looks like the LoggerAppenderMongoDB has support for displaying exceptions with the formatThrowable method, but I don’t see anything similar in the other appenders.

I feel like I am missing something obvious. Is there something that I need to configure in order to print these details to the log file? Do I need to create a custom LoggerAppender class? Or can these be done with a different layout or a custom renderer?

How to&Answers:

FYI, now that LoggerLayoutTTCC is deprecated, you can use LoggerLayoutPattern with a better format string to include exceptions.

<layout class="LoggerLayoutPattern">
   <param name="conversionPattern" value="%d{m/d/y H:i:s,u} [%t] %p %c %x - %m %newline%throwable" />
</layout>

<!-- %newline%throwable is the important part -->

See the Logging Exceptions section of the docs: http://logging.apache.org/log4php/docs/layouts/pattern.html#Logging_exceptions

Answer:

You should use PHP set_exception_handler function and wrap log4php using this function.
check it out at: http://php.net/manual/en/function.set-exception-handler.php

function exception_handler($exception) {

$log->debug($exception->getMessage());
}

set_exception_handler(‘exception_handler’);

Answer:

I’ve come to the same conclusion: it looks like log4php only does something with the $throwable parameter in the LoggerAppenderMongoDB.php appender.

The LoggerAppenderFile base class relies on the layout, LoggerLayoutTTCC, to format the message (as would be expected). That class has a method ignoresThrowable(), which returns true. Although this method does not appear to be called, it does mildly communicate that the authors did not seem to intend to take any note of the error.

I have added my own layout class that extends LoggerLayoutTTCC and overrides format()

    class LoggerLayoutTTCCWithException extends LoggerLayoutTTCC
    {
        public function format(LoggerLoggingEvent $event) {
            $format = parent::format($event);

            $throwableInfo = $event->getThrowableInformation();
            if ($throwableInfo === null) {
                return $format;
            }

            $renderer = new LoggerRendererException();
            return $format . $renderer->render($throwableInfo->getThrowable());
        }
    }

Answer:

It took me a while to figure out why the original file name and line number was not logged by log4php when an exception is thrown. It turned out that my custom exception_handler class was only logging the exception message (by doing $exception->getMessage()), which does not contain the file name nor the line number. All I to do is concatenate that info: $exception->getFile() and $exception->getLine():

public function exception_handler ($exception) {
        $logger = Logger9::create();
        $logger->info($exception->getMessage()." ".$exception->getFile()." ".$exception->getLine());
}

Don’t forget to register the custom handler:

@set_exception_handler(array($this, 'exception_handler'));