LoggingThe Ultimate Guide

your open-source resource for understanding, analyzing, and troubleshooting system logs

curated byloggly


PHP Framework Logging

PHP logging is handled usually through an applications framework interface. This guide includes examples from a few popular frameworks and explores how each one handles logging. Frameworks included are Laravel, Drupal, Zend Framework, Symfony, and Magento. Some of the examples included pertain to specific versions and others to the current version.


Laravel is a popular full stack framework. True to its philosophy of reusing the best components available, Laravel chose Monolog as its logging functionality.


The central config/app.php provides some settings to configure how logging behaves in your application. For the log keyword, you can set it to:

  • single (default): Write to a monolithic log file in the storage/logs directory. The file will be named laravel.log .
  • daily : Write to a log file in the storage/logs directory. A new log file is created each day and a limited number are kept. Using logrotate is recommended, so only use this Monolog Handler if logrotate is not available.
  • syslog : Use Monolog’s Syslog handler.
  • errorlog : Use Monolog’s Errorlog handler.


Your application will log error details depending on the value of the APP_DEBUG environment level in laravel/.env . On your development environment, you’ll want this value set to true, so that errors are displayed along with output. However, for your production environment, you should set it to false, which will log errors depending on your configurations settings. For example, if you are using single or daily and your code encounters an error or an exception and APP_DEBUG=false, your laravel.log would have a line that looks like this:

Logging Custom Actions

You can log custom actions in Laravel very easily with the Log facade. It has different methods that correspond to severity levels. These correspond to PSR-3 Log Levels for emergency, alert, critical, error, warning, notice, info, and debug, which come for RFC 5424. (Read more about PSR-3.) In your route or controller, the following will log an informational item:

When a user tries to log in, the following example JSON output will be written to your log file:

Similarly, you can log other severity levels:

Drupal 7

Logging in Drupal 7 is totally different than Drupal 8, so jump to the Drupal 8 logging section below unless you’re running Drupal 7. Drupal 7 logging is done using the hook_watchdog function. It passes you an array containing the necessary logging details you need for your module. We can take the DBLog module as an example:

The log_entry variable contains the following details:

type Log message type (system, cron, user, etc.)
user Logged-in user
uid Logged-in user ID
request_uri Page where the logged event happened
referrer Referrer page
ip Page visitor IP
timestamp Logged event date timestamp
link Link to the module that logged the event
message Log message (May contain placeholders like: “User @id is suspended.”)
variables Variables to replace with placeholders
array( ‘@id’ => 136)


Logging modules like SysLog, FileLog, and MailLog provide a configuration page to personalize things like errors display, limits, logs formatting, etc. For the example below, you may give the user the ability to select the logging severity, custom system variables (user, timestamp), etc.


Building a Logger

We are going to build a MailLog module for our example. It will only email log errors and above. (ERROR, CRITICAL, ALERT, EMERGENCY)

Inside our mailog.module file, we’re going to register our hook function. You can read more about building a Drupal module in the official documentation.

The severity attribute inside the log_entry array contains an integer from 0 to 7 describing error severity. So, the if condition will only log errors and above. If the log contains any context variables, we substitute them using the strtr PHP function.

Drupal 8

Drupal 8 loggers are PSR-3 compliant. You can resolve the Drupal logger class from the container like the following:

You may also pass some context variables as a second parameter:

Because the DBLog module is activated by default, messages are logged to the watchdog table in your database.

wid type message variables
81 general Just an info message a:0:{}
82 general User %username has been deleted. a:1:{s:9:”%username”;s:6:”younes”;}

You can install other loggers from the modules page on the dashboard to log to different destinations. As an example, let’s use the Syslog module. You can go ahead and install it on the modules dashboard.

If you run the same code samples from above, you can check the log message on the /var/log/syslog file. I’m running a Linux Ubuntu 14.04.


You can configure logging through the Configuration > Development > Logging and Errors. The interface lets you specify errors display level, database log records limit, Syslog format (when Syslog module is installed), etc.


Note: Don’t forget to turn off errors display when moving to production.

Building a Logger

You can read all about defining a logger for Drupal 8 in this thread. Our logger class should implement the Psr\Log\LoggerInterface interface and define the nine parent methods (emergency, alert, critical, error, warning, notice, info, debug, and log). You can check the [PSR-3 Logging Standard](our PSR-3 logging guide) guide for more details on how to use the Psr\Log package.

For example, I’m going to build a MailLog class that will log to the website admin. We are not going to cover how to create Drupal modules and settings pages. Here is a stripped down example:

Zend Framework

Zend Framework is a modular framework. It’s components are available for use outside of the framework if desired on an individual basis. One such component is the framework’s logging functionality, Zend\Log component.


The Zend\Log component is comprised of a group of logging classes that provide general logging functionality within a Zend Framework application, or can be used as a standalone component in another framework or application.

The base class for logging is the Zend\Log\Logger.php. Once instantiated, the logger object needs at least one writer to log data. You can have as many logger objects as needed without concerns about interoperability.

Once the logger object is instantiated, add writers as needed using the addWriter() method. The writer objects do the heavy lifting of writing to various data sources.

Optional filter objects are added to logger objects as needed to provide granular control over what is logged.

Optional formatter objects provide a string formatting to log entries. These objects are added to the writer objects, which in turn use them to format the log entries.

Once a logger object is set up with a writer, a call to the log() method writes the log data.

Note: The following examples assume loaded classes.

Using a logger with a stream writer to a file path.

Available Filters include:

Priority Regex Timestamp SuppressFilter Validator

Severity Levels: Left to right by order of severity.


Adding a filter to a stream writer. In this case, a priority filter of critical. Filters include: Priority | Regex | Timestamp | SuppressFilter | Validator

Adding a filter to a stream writer allowing for different priorities. Filters include: Priority | Regex | Timestamp | SuppressFilter | Validator

Writers Available:

Writer Description
Db Sends log data to a database table
FirePHP Sends log data to the Firefox FirePHP extension
ChromePHP Sends log data to the ChromePHP extension
Mail Sends log data to an email via Zend\Mail
MongoDB Sends log data to a MongoDB database
Stream Sends log data to a PHP stream
Syslog Sends log data to the system log
ZendMonitor Sends log data to Zend Monitor server API

Symfony classes

Symfony is another well-regarded, full stack framework. While framework components can be used separately, this section assumes you are using the standard edition for your application as indicated in the Installation docs. The standard edition also uses the Monolog package to handle logging.

Configuring a Logger

Depending on your environment, Monolog is configured as a service in app/config/config_dev.yml or app/config/config_prod.yml . In the development environment, you’ll see a section with the following content (note that the level is set to debug, which can be quite verbose):

If you look at config_prod.yml, you’ll see that a different handler and action_level are used:

The FingersCrossedHandler class from Monolog stores messages in a buffer and only logs them if a message reaches the action_level specified. This keeps your production logs from getting cluttered with log messages you are not interested in.

Monolog service configuration includes specifying a logging format as a console service in app/config/services.yml. If you want to see errors logged to the console, here is an example. The formatting are placeholders for passed arguments.


For a production environment, a typical Symfony app will use Monolog to save messages to app/logs/prod.log . Similarly, if you’re in a dev environment, the log file is app/logs/env.log .

Log a Message

To log a message, retrieve the logger service from the DI container.

In your log file, you’ll find a line with:

As with Laravel, you can log different severity levels:

For more tips on how to handle logging with Symfony and Monolog, check out the Recipes about Logging on the Symfony Cookbook.

Magento 1.9*

Logging capability provided by the Magento eCommerce platform is made available by an Admin user via the admin interface at <your/site/url/admin>. Logging is not enabled by default and requires configuration settings adjustments.

To enable logging

Within the Admin panel, select the top menu “System”. On the left menu under configuration, select Advanced>Developer to display the Developer configuration options.

In the main content, select the “Log Settings” option to display the options for enabling logging and define the log paths for the system and exception logs. The path default settings are {{base_dir}}/var/log. The base_dir in this case is the install directory for the source code on the server. The default log for system logging is the /var/log/system.log, and the default for exception logging is the /var/log/exception.log.

Once logging is enabled and the log paths set, select the “Save Config” button. A message is displayed to confirm the saved configuration.

The Mage class is used to log the two types of messages: the Mage::log() method for general system logging and the Mage::logExceptions() method for exceptions.

The log method defines four parameters: A required message to log, an optional severity level, an optional file location path, and a forceLog boolean.

The logException defines a single parameter: An exception object.

Example: Log a message to the system log.

Example: Log a message to the system log with a severity.

Example: Log a message to a custom log location with a severity and log path.

System Log Cleaning Options (from the Admin interface)

Log configuration beyond enabling and defining the log locations is accomplished via the “System” configuration. Settings such as dates, times, and cleaning are found here and are configurable by system administrators.

Within the Admin panel, select the top menu “System”. On the left menu under configuration, select Advanced>System to display the Log accordion option. These settings have global system impact.

Table of Log Cleaning Options

Option Description
Enable Log Disables recently viewed products and compare products functionality for customers who are not logged in
Save Log, Days Defines how long logs are saved
Enable Log Cleaning Defines whether log cleaning is enabled
Start Time Configures log cleaning start times
Frequency Configures log cleaning frequency
Error Email Recipient Defines a recipient email for log cleaning error notification
Error Email Sender Defines a sender email for log cleaning error notification (This setting provides selections for system representatives like “Customer Support” and “General Contact” and a couple of custom email senders.)
Error Email Template Defines the email template used for log cleaning notifications

Magento 2

Magento 2 is a full stack e-commerce platform. It integrates and uses the Monolog logging framework as its main logging functionality rather than the previous base class Mage::log() method. The new release will comply with the PSR-3 logging implementation standard, as well as namespaces.

A word about PSR-3

Magento 2 will comply with the PSR-3 standard as specified by the PHP Framework Interop Group. The standard specifies use of classes that implement a standard LoggerInterface which drives abilities to use different library logging implementations in a consistent manner.

What this means is any third-party logging library will need to implement the methods specified in the PSR-3 standard. Injecting a class with a logging instance that complies with the PSR-3 standard is a good way to ensure the class has a compliant object.

Example: Using a PSR-3 standard implementation object in a class.

This OOP example uses constructor injection to ensure logging is available via a class implementing the standard. To use the logger, grab the injected instance and call one of the standard methods passing an exception.

Magento 2 and Monolog

Magento 2 uses Monolog as a standard framework implementation in the form of Magento\Framework\Logger\Monolog. This means that when a class injects the \Psr\Logger\LoggerInterface instance, it will receive an instance of the Monolog logger.

This coupling of the PSR-3 standard and the implementation of the Monolog logger gives the developer a powerful toolset for logging in Magento 2.

Written & Contributed by




This guide will help software developers and system administrators become experts at using logs to better run their systems. This is a vendor-neutral, community effort featuring examples from a variety of solutions

Meet Our Contributors Become a contributor