Using JLog

From Joomla! Documentation


Other languages:
English • ‎español • ‎français • ‎Nederlands

Overview

Joomla logging gives you the ability to log messages to files and to the screen (within the Joomla! Debug Console at the bottom of the web page), and the main Joomla class which underpins this is JLog.

The logging can be controlled dynamically to some extent through the Joomla Global Configuration and by configuring the System – Debug plugin (which is shipped with Joomla). Overall these facilities allow you to:

  • switch DEBUG logging on or off – so that ordinarily you don't consume resources needlessly, but you have the logging information to assist troubleshooting when there are issues, for example on a live site which has your extension installed.
  • route log messages through to a specific log file for your own extension
  • view log messages in the Debug Console – you can select the group of users to which log messages should be displayed, so that on a live site developers can see the messages while other users are unaffected.
  • filter Debug Console messages by priority (ie INFO, DEBUG, WARNING, etc) and by category (you are free to define your own categories).

In addition, the log messages can be translatable into different languages.

The main configuration options relating to logging are shown below.

Switching on debug and display of the Joomla Debug Console is controlled through the global configuration options. Global conf debug-en.jpg

Logging to the general log file is controlled via the Logging tab of the configuration of the Joomla System - Debug plugin. (In the administrator menu click on Extensions / Plugins, find the System - Debug plugin, and click on it to edit its configurable options). Debug logging settings-en.jpg

And the options within the Plugin tab control display on the Joomla Debug Console. Debug plugin settings-en.jpg


Basic File Logging

To log a message you use the JLog::add() function. For example:

   JLog::add('my error message', JLog::ERROR, 'my-error-category');

The parameters are

  1. A message string. You can use translation with these eg JText::_('MY_EXTENSION_ERR_MSG'), You can also display the values of variables, provided you convert them into a string format (eg using __toString() if the type of the variable supports that).
  2. A priority, which can be one of JLog::EMERGENCY, JLog::ALERT, JLog::CRITICAL, JLog::ERROR, JLog::WARNING, JLog::NOTICE, JLog::INFO, JLog::DEBUG (based on the standard syslog / RFC 5424 severity levels – see wikipedia article on syslog).
  3. A category, which is just a text string. You can define whatever categories you like, but best to define them to avoid possible clashes with those of other extensions.

It can be very helpful with troubleshooting problems later if you include diagnostic debug messages in your extension. In this case, enclose your log message within a check for JDEBUG:

   if (JDEBUG) 
   {
       JLog::add('my debug message', JLog::DEBUG, 'my-debug-category');
   }

Logging a specific log file

You can use JLog::addLogger() to set up logging to an additional log file, filtering the log messages to be sent there by priority (aka severity level) and/or category. The parameters of JLog::addLogger() are:

  1. an array with configuration details – including the name of the log file
  2. the severity levels to be logged in that file
  3. an array of the categories to be logged in that file (or if parameter 4 is set to true then this array defines the categories which are NOT to be logged in the file)
  4. (often omitted) a boolean specifying whether parameter 3 is an include list (the default, P4 = false) or an exclude list (P4 = true)

For example if you have developed a 'com_helloworld' extension you could use the following:

   JLog::addLogger(
       array(
            // Sets file name
            'text_file' => 'com_helloworld.log.php'
       ),
           // Sets messages of all log levels to be sent to the file
       JLog::ALL,
           // The log category/categories which should be recorded in this file
           // In this case, it's just the one category from our extension, still
           // we need to put it inside an array
       array('com_helloworld')
   );

Then when you log a message, specify the category as 'com_helloworld', as in the example below

   JLog::add(JText::_('COM_HELLOWORLD_ERROR_MESSAGE_123'), JLog::ERROR, 'com_helloworld');

This will result in your log message being written to com_helloworld.log.php. If the System – Debug plugin settings have "Log Almost Everything" set to Yes, then the message will appear in the common everything.php log file as well.

Note: You may wish to combine this with the Display error messages and notices section to display visible error notifications to users.

You can also add an additional logger to capture only critical and emergency log notifications:

   JLog::addLogger(
       array(
            // Sets file name
            'text_file' => 'com_helloworld.critical_emergency.php'
       ),
           // Sets critical and emergency log level messages to be sent to the file
       JLog::CRITICAL + JLog::EMERGENCY,
           // The log category which should be recorded in this file
       array('com_helloworld')
   );

You can also exclude a specific priority level from being included. For example, to log all but DEBUG messages:

   JLog::addLogger(
       array(
            // Sets file name
            'text_file' => 'com_helloworld.all_but_debug.php'
       ),
           // Sets all but DEBUG log level messages to be sent to the file
       JLog::ALL & ~JLog::DEBUG,
           // The log category which should be recorded in this file
       array('com_helloworld')
   );

The JLog priority levels are implemented as separate bits of an integer, so you can use bitwise operations (bitwise AND, &; and bitwise NOT, ~) to calculate the appropriate log levels. JLog::All is a constant integer which has all the relevant bits set, so that all the Joomla priority levels are included.

Formatting the logfile

The first parameter to addLogger can have a few optional additional settings in addition to the text_file entry.

There is for example the entry text_entry_format, specifying the format of each line in your logfile.

The default format is:

   '{DATETIME} {PRIORITY}      {CATEGORY}      {MESSAGE}'

Here is an example of a different format which shows how to omit the category:

   JLog::addLogger(
       array(
            // Sets file name
            'text_file' => 'com_helloworld.critical_emergency.php',
            // Sets the format of each line
            'text_entry_format' => '{DATETIME} {PRIORITY} {MESSAGE}'
       ),
           // Sets all but DEBUG log level messages to be sent to the file
       JLog::ALL & ~JLog::DEBUG,
           // The log category which should be recorded in this file
       array('com_helloworld')
   );

In addition to the placeholders shown above in the default string, the following values are available:

   {CLIENTIP}      (this is the IP address of the client)
   {TIME}
   {DATE}


There is an additional optional boolean parameter text_file_no_php, which specifies whether the log file is prepended with the usual prefix of:

   #
   #<?php die('Forbidden.');?>

Note: Usually you should not set this setting to false. Log files should not be readable from the outside, since they can provide valuable information about your system for attackers. Only dabble with this if you know what you're doing!

Furthermore, if you want to store the log file somewhere else than the logging path configured in the Joomla! settings, you can there is the text_file_path setting.

Logging to other places

As well as logging to files, you can log to other places as well, such as

  • the Joomla message area (where the message is shown if you call JFactory::getApplication()->enqueueMessage())
  • a database table
  • just a simple echo statement

Of these, probably the most useful is the logging to the message bar, which you can set up via:

   JLog::addLogger(array('logger' => 'messagequeue'), JLog::ALL, array('msg-error-cat'));

Then when you do

   JLog::add('an error to display', JLog::ERROR, 'msg-error-cat');

you will get the message copied to the message bar.

Note that Joomla core code sets up logging to the messagequeue for category 'jerror', so that if you use this category in your log messages, you will get the message displayed on the message bar. Eg

   JLog::add('error copied to message bar', JLog::Error, 'jerror');

will result in the message being shown in the Joomla message area, even though you haven't explicitly set up a logger to log there.

Exceptions

JLog::add() will throw an exception if it can't write to the log file. To avoid this, you'd have to either wrap the call in another function, or implement your own logger class and then include it with:

   JLog::addLogger(
       array(
            // Use mycustomlogger
            'logger' => 'mycustomlogger',
            'text_file' => 'com_helloworld.errors.php'
       ),
       JLog::ALL,
       array('com_helloworld')
   );

Further Reading

Joomla logging should be used in tandem with PHP exceptions, not as a replacement. See Exceptions and Logging in Joomla 1.7 and Joomla Platform 11.1 for more information on this.

Another tutorial (a little out of date, but still useful) is at logging in joomla with jlog.