An opinionated Symfony Monolog Configuration for Prod and Dev Environments
TL;DR: Skip right to configuration files below
Logging is one of the most important parts for debugging your application. Symfony framework comes bundled with Monolog which is a quite robust logging library for PHP applications.
Monolog sends your logs to files, sockets, inboxes, databases and various web services
Here I will describe how we configured Monolog to scale our logs on prod and dev environments. At Enuygun we have a distributed architecture where users may round-robin among web servers. By default Monolog configuration in Symfony logs to environments file as %kernel.logs_dir%/%kernel.environment%.log
. But for a distributed environment it’s not a scalable solution.
Monolog Handlers to the Rescue
When your application serves to huge traffic, you have to choose the persistence layer of logs carefully. Luckily, the loosely coupled architecture of Monolog makes it possible to use a wide range of handlers to handle the persistence of logs.
Graylog, Gelf protocol and ELK Stack
When choosing a log management tool for logging there is a wide range of products. At first, we chose Graylog because its gelf protocol supports logging via UDP port which does not impact application response time much. But our BI unit is more experienced with ELK stack thus eventually we went to deploy ELK to log all our application logs. Fortunately, ELK’s logstash supports gelf protocol and the deployment went flawless since we didn’t have to make any changes to application configuration.
Configuring fault-tolerant logger
In distributed environments, you always have to make every part of your application highly available. Monolog has some special handlers like WhatFailureGroupHandler
which ignore exceptions thrown by child handlers like failure of connections to Graylog server or Logstash server. Of course for the price of losing some logs, but at least your application survives.
Default Symfony Monolog configuration redirects logs generated by developer to channel app
. Route (request)
, Event Dispatcher (event)
, Doctrine (doctrine)
and other components create their channels. These channels can generate excessive log if you don’t configure them properly.
Excessive logging can be avoided by specifying levels for each channel.
Let’s see configuration files:
Intercepting Exceptions using kernel.exception event
Finally, it is a good idea to send all your exceptions to your application log server. To do this, you have to intercept exceptions using Symfony’s kernel.exception
event.
Conclusion
Symfony and Monolog play pretty well together, and at Enuygun we are happy that with minimal effort you can trace all your logs in your desired log management tool.
Kudos to all open source contributors!