Skip to content

Using Monolog for Logging

Monolog is a comprehensive logging library for PHP that sends your log records to files, sockets, inboxes, databases and various web services. It’s perfect for tracking application behavior, debugging issues, and monitoring your REST API built with Slim framework.

Key benefits:

  • PSR-3 compliant logging interface
  • Multiple handlers for different output destinations
  • Processors to add extra information to log records
  • Flexible formatting options
  • Support for log levels from DEBUG to EMERGENCY

Install Monolog using Composer:

Terminal window
composer require monolog/monolog
bash
  • However, Monolog is already included in the provided Slim template. So you can skip this step.

  1. Import Monolog classes in your application

    use Monolog\Logger;
    use Monolog\Handler\StreamHandler;
    php
  2. Create a logger instance with a channel name

    // Create a logger with a channel name (e.g., 'app_access', 'api', 'database').
    $logger = new Logger('app_access');
    php
  3. Add one or more handlers to define where logs go

    // Log to a file - INFO level and above.
    $logger->pushHandler(new StreamHandler(__DIR__ . '/logs/app.log', Logger::INFO));
    // You can add multiple handlers for different purposes.
    // For example, log errors to a separate file.
    $logger->pushHandler(new StreamHandler(__DIR__ . '/logs/errors.log', Logger::ERROR));
    php
  4. Use the logger throughout your application

    $app->post('/api/planets', function ($request, $response) use ($logger) {
    $data = $request->getParsedBody();
    // Log the incoming request.
    $logger->info('Creating new planet', ['data' => $data]);
    // Your business logic here...
    return $response->withStatus(201);
    });
    php

Monolog implements the PSR-3 logging standard with eight severity levels. Use the appropriate level based on the type of information you’re logging:

LevelMethodWhen to UseExample
DEBUG$logger->debug()Detailed debug informationVariable values, loop iterations
INFO$logger->info()Interesting eventsUser login, API requests
NOTICE$logger->notice()Normal but significant eventsConfiguration changes
WARNING$logger->warning()Exceptional occurrences that are not errorsUse of deprecated APIs, poor API usage
ERROR$logger->error()Runtime errors that don’t require immediate actionDatabase connection failed
CRITICAL$logger->critical()Critical conditionsApplication component unavailable
ALERT$logger->alert()Action must be taken immediatelyEntire website down
EMERGENCY$logger->emergency()System is unusableDatabase unavailable, system crash

  • Logging Request Information
  • Logging Database Operations
  • Logging API Calls
  • Logging Exceptions
  • Logging Authentication Events

Monolog allows you to add contextual information to your log messages using arrays:

// Simple context.
$logger->info('User logged in', ['user_id' => 123]);
// Rich context.
$logger->error('Payment processing failed', [
'user_id' => 123,
'amount' => 99.99,
'currency' => 'USD',
'error_code' => 'CARD_DECLINED',
'timestamp' => time()
]);
php

By default, Monolog uses UTC for timestamps. You can change this globally for all loggers:

use Monolog\Logger;
$logger = new Logger('access');
// Set the default timezone for this logger.
$logger->setTimezone(new \DateTimeZone('America/New_York'));
php

Monolog uses formatters to control how log records appear. The default LineFormatter can be customized:

use Monolog\Handler\StreamHandler;
use Monolog\Formatter\LineFormatter;
$handler = new StreamHandler(__DIR__ . '/logs/app.log', Logger::INFO);
// Create a custom format.
// Available placeholders: %datetime%, %channel%, %level_name%, %message%, %context%, %extra%
$dateFormat = "Y-m-d H:i:s";
$outputFormat = "[%datetime%] %channel%.%level_name%: %message% %context%\n";
$formatter = new LineFormatter($outputFormat, $dateFormat);
$handler->setFormatter($formatter);
$logger = new Logger('app');
$logger->pushHandler($handler);
php

Example output:

[2025-11-10 14:30:45] app.INFO: User logged in {"user_id":123}
[2025-11-10 14:31:12] app.ERROR: Database connection failed {"error":"Connection timeout"}
plaintext