An opinionated Symfony Monolog Configuration for Prod and Dev Environments

TL;DR: Skip right to the configuration files below

Logging is one the most important parts for debugging your application. Symfony framework comes bundled with Monolog which is 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 a huge traffic, you have to choose persistence layer of logs carefully. Luckily loosely coupled architecture of Monolog makes it possible to use a wide range of handlers to handle persistence of logs.

Graylog, Gelf protocol and ELK Stack

When choosing log management tool for logging there are a wide range of products. At first we chose Graylog since 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 ignores 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 own channels. These channels can generate excessive log if you don’t configure them properly.

By specifying levels for each channel excessive logging can be avoided.

Let’s see configuration files:

An opinionated configuration for Symfony in prod environment
An opinionated configuration for Symfony in dev environment

Intercepting Exceptions using kernel.exception event

Finally it is a good idea to send all your exceptions to your application log server. In order to do this you have to intercept exceptions using Symfony’s kernel.exception event.

Conclusion

Symfony and Monolog play pretty well and at Enuygun we are happy that with minimal effort you are be able to trace all your logs in your desired log management tool.

Kudos to all open source contributors!