Reputation: 14575
I have used the following configuration for my production logging:
monolog:
handlers:
mail:
type: fingers_crossed
action_level: error
handler: grouped
grouped:
type: group
members: [streamed, buffered]
streamed:
type: stream
path: %kernel.logs_dir%/%kernel.environment%.log
level: debug
# buffered is used to accumulate errors and send them as batch to the email address
buffered:
type: buffer
handler: swift
swift:
type: swift_mailer
from_email: [email protected]
to_email: [email protected]
subject: Error Occurred!
level: debug
This sends emails like this:
[2012-03-21 21:24:09] security.DEBUG: Read SecurityContext from the session [] []
[2012-03-21 21:24:09] security.DEBUG: Reloading user from user provider. [] []
[2012-03-21 21:24:09] security.DEBUG: Username "jakob.asdf" was reloaded from user provider. [] [] [2012-03-21 21:24:09] request.INFO: Matched route "_user_settings" (parameters: "_controller": "...Bundle\Controller\UserController::settingsAction", "username": "Jakob.asdf", "_route": "_user_settings") [] []
[2012-03-21 21:24:09] request.ERROR: Symfony\Component\HttpKernel\Exception\NotFoundHttpException: ...Bundle\Entity\User object not found. (uncaught exception) at /var/www/.../vendor/bundles/Sensio/Bundle/FrameworkExtraBundle/Request/ParamConverter/DoctrineParamConverter.php line 50 [] []
[2012-03-21 21:24:09] security.DEBUG: Write SecurityContext in the session [] []
I would really love to have a stack trace here, or at least the line number in my controller which triggered the error. Otherwise it's really a lot of guessing of what could have gone wrong.
Now, the question: Is there any way to achieve such an even more verbose logging?
Upvotes: 20
Views: 8172
Reputation: 3690
I like the solution from the Symfony docs. All you have to do is add the following code to your services.yml
file:
services:
my_service:
class: Monolog\Processor\IntrospectionProcessor
tags:
- { name: monolog.processor }
This uses the IntrospectionProcessor
, a tested processor to add more information to your log. It pulls out the information you care about too probably.
Upvotes: 8
Reputation: 15002
Yes it can be achievable.
Create a ExceptionListener
class.
//namespace declarations
class ExceptionListener{
/**
* @var \Symfony\Component\HttpKernel\Log\LoggerInterface
*/
private $logger =null;
/**
* @param null|\Symfony\Component\HttpKernel\Log\LoggerInterface $logger
*/
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
}
/**
* @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
if($this->logger === null)
return;
$exception = $event->getException();
$flattenException = FlattenException::create($exception);
$this->logger->err('Stack trace');
foreach ($flattenException->getTrace() as $trace) {
$traceMessage = sprintf(' at %s line %s', $trace['file'], $trace['line']);
$this->logger->err($traceMessage);
}
}
}
And then register listener.
kernel.listener.your_listener_name:
class: FQCN\Of\ExceptionListener
tags:
- { name: kernel.event_listener, event: kernel.exception, method: onKernelException , priority: -1}
- { name: monolog.logger, channel: mychannel }
arguments:
- "@logger"
You can tweak it as your requirement.
Upvotes: 23