In the last few years, the way applications log messages has changed. Using files was the common way to store logs but with the Cloud (read containers, Docker, and the likes), using stderr to stream logs is recommended.

Did you know that you don't need Monolog to capture application logs? Since Symfony 3.4, the Symfony HttpKernel component comes with a default PSR3 logger that logs everything in stderr, without the help of any other packages. This feature was added along side the introduction of Flex as new applications start with no extra packages, and so no logger. Loggin via `stderr` was chosen with containers in mind.

By default, new Symfony applications log in stderr via this default HttpKernel logger. It is probably enough for small applications; I'm using it for fabbot and Twig's website for instance.

Using Monolog is still very useful as it comes with way more options and configurability. But for historical reasons, and probably practicability on dedicated servers, Monolog default recipe still uses a file to store logs (%kernel.logs_dir%/%kernel.environment%.log). The Symfony Kernel class even has a getLogDir() method as defined in the Kernel interface.

It might make sense on a development server (more on that later), but in production, stderr is a better option, especially when using Docker, SymfonyCloud, lambdas, ... So, I now recommend to use php://stderr as the path for Monolog:

1
2
3
4
5
6
7
8
9
10
11
--- a/config/packages/prod/monolog.yaml
+++ b/config/packages/prod/monolog.yaml
@@ -11,7 +11,7 @@ monolog:
            members: [nested, buffer]
        nested:
            type: stream
-            path: "%kernel.logs_dir%/%kernel.environment%.log"
+            path: php://stderr
            level: debug
        buffer:
            type: buffer

On SymfonyCloud, using stderr also has a few added benefits (the same should apply to most containerized platforms). Even if in the end, the logs sent to stderr end up in a file as well: app.log. You might wonder how this could be better than using a dedicated file then. First, the app.log file is "managed" by SymfonyCloud: it is automatically rotated (no more log files growing indefinitely until it fills up your disk), the app.log file is stored in a local and fast disk instead of a network disk (which is used when storing files under var/log/). It might also be less expensive as you don't "waste" network disk capacity with ephemeral logs.

Using stderr also means that there is one less write-able directory needed by Symfony (don't forget to log deprecation notices in stderr as well and check that no third-party bundles write into the getLogDir() directory).

What about development? Can you use stderr as well? The answer is yes and I recommend you to do so as well.

If you are using PHP-FPM, you need to configure it to "forward" logs to FPM logs (which can be streamed on stderr as well!):

1
2
3
; Ensure worker stdout and stderr are sent to the main error log
catch_workers_output = yes
decorate_workers_output = no (7.3+ only)

If you are using Symfony CLI, that's the default configuration for PHP-FPM and logs are automatically "un-decorated" for all PHP versions.

Happy logging!

Published in #Cloud #Community #Symfony