How to Log Requests in Symfony

Updated: January 13, 2024 By: Guest Contributor Post a comment

Overview

When it comes to web development, logging is a vital aspect that helps in diagnosing issues, tracking application behavior, and monitoring traffic. Symfony, one of the most popular PHP frameworks, provides robust logging mechanisms that can ease the process of logging HTTP requests for developers.

This tutorial will guide you through the process of setting up request logging in a Symfony application using Monolog, the default logging library in Symfony. Before diving in, ensure that you have a running Symfony application. If not, you can quickly create one by following the official Symfony documentation.

Understanding Symfony’s Logging Mechanisms

Symfony uses Monolog to handle logging. Monolog allows for various handlers and formatters that you can configure to control where logs are sent and their format. Some common handlers include StreamHandler for logging to files, FirePHPHandler for logging to browsers, and SyslogHandler for logging to system logs.

Installing Monolog in a Symfony Application

If Monolog is not already set up in your application, you can install it using Composer:

composer require symfony/monolog-bundle

Configuring Monolog to Log Requests

Creating a Monolog Channel

Channels are useful for categorizing logs. To create a dedicated channel for request logs:

# config/packages/monolog.yaml
monolog:
    channels: ['request']

This channel can be referenced in different handlers so that only specific logs are written there.

Creating a Custom Service to Log Requests

You can create a service that listens to kernel events to log every HTTP request. Here’s how:

# src/EventListener/RequestLogger.php

namespace App\EventListener;

use Symfony\Component\HttpKernel\Event\RequestEvent;
use Psr\Log\LoggerInterface;

class RequestLogger
{
    private $logger;

    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    public function onKernelRequest(RequestEvent $event)
    {
        // Only log master requests
        if (!$event->isMasterRequest()) {
            return;
        }
        $request = $event->getRequest();
        $this->logger->info(sprintf(
            'New request: %s %s',
            $request->getMethod(),
            $request->getRequestUri()
        ));
    }
}

Next, register this listener and tag it for use with your ‘request’ channel. Add the following to services.yaml:

# config/services.yaml
services:
    App\EventListener\RequestLogger:
        arguments: ['@monolog.logger.request']
        tags:
            - { name: 'kernel.event_listener', event: 'kernel.request', method: 'onKernelRequest' }

Configuring the Handler to Write Logs

With the service in place, configure a handler to write the request logs to a specific file. Modify the Monolog config:

# config/packages/monolog.yaml
monolog:
    handlers:
        request:
            type: stream
            path: '%kernel.logs_dir%/request.log'
            level: info
            channels: ['request']

With this configuration, all request logs gathered by the RequestLogger service will be written to ‘var/log/request.log’ at an ‘info’ level.

Implementing Structured Logging

Structured logging can be beneficial for readability and parsing log data. To implement JSON formatted logs:

# config/packages/monolog.yaml
monolog:
    handlers:
        request:
            type: stream
            path: '%kernel.logs_dir%/request.log'
            level: info
            channels: ['request']
            formatter: 'monolog.formatter.json'

This will ensure that each log entry is a JSON object, making it easier to process logs using log management tools.

Security Considerations

When logging requests, be careful not to log sensitive information such as passwords or personal data. You can filter out sensitive data in the RequestLogger service before logging the request. Also, ensure proper file permissions are set for your log files to prevent unauthorized access.

Monitoring and Rotating Logs

For a production application, consider using log rotating to manage log file sizes and ensure that logs are not consuming disk space excessively. Symfony and Monolog support log rotation, which can be set up by configuring a rotating_file handler:

# config/packages/monolog.yaml
monolog:
    handlers:
        request:
            type: rotating_file
            path: '%kernel.logs_dir%/request.log'
            level: info
            channels: ['request']
            max_files: 10 

This configuration will rotate the request.log file, keeping at most 10 files of historic logs.

Conclusion

Logging HTTP requests in a Symfony application provides insights into application use and can help identify issues quickly. By following the steps outlined in this tutorial, you can set up a robust logging system tailored to the needs of your Symfony application. Always ensure to keep security best practices in mind and to protect your log files as diligently as you would your source code or databases.