Extended logging with Past

Introduction

Past is an extended logging framework, designed to log and later analyze complex data structures to a pluggable backend.

A typical use case for this is logging communication between one or multiple services, where data is received, processed and forwarded.

A single log message is called an event, which can have multiple attached arguments, each argument can be a scalar, an array, an object or an exception. Complex data structures like arrays and objects are stored separately so that they can be searched and displayed in a readable way, those rows are called "(event) data".

There are two API functions provided for creating a log event, past_event_create() and past_event_save().

Example usage

Below are two examples of how past can be used.

One-off log events using past_event_save()

past_event_save() is a thin wrapper around past_event_create() that doesn't much more than create a log event and automatically save it using the given arguments.

It is useful for simple log messages, where all the information is present at once and when relying on a wrapper for optional integration (see README.txt for details).

$arguments =  array('arg1' => 'Example argument', 'arg2' => array(1, 2, 3, 4, 5));
past_event_save('yourmodule', 'machine_name', 'This is an example log message', $arguments);

Sophisticated logging using the object oriented interface

When working with services, there are often multiple requests, data is processed, sent to another service and so on. The process can go wrong, when e.g. an exception is thrown in the middle, different results can happen where it would be useful to have a different log message. The following example demonstrates how the object oriented interface based on the PastEventInterface interface can be used to support all these situations.

We have an imaginary process that requests information from service A, processes it locally and then sends it to service B.

// Create a log event.
$event = past_event_create('yourmodule', 'sync_stuff');
 
// Add local information that is sent to service A.
$latest_sync = new DateTime($latest_sync);
$event->addArgument('latest_sync', $latest_sync->format('Y-m-d H:i:s'));
 
$stuff = servicea_request_stuff($latest_sync->getTimestamp());
if (empty($stuff)) {
  // We did not receive new information, log this
  // is a debug log message.
  $event
    ->setMessage('No new stuff received from A')
    ->setSeverity(PAST_EVENT_DEBUG)
    ->save();
  return;
}
 
// Add the received data. We use addArgumentArray() so that each item
// in the $stuff array is a separate argument. This makes
// viewing/debugging easier because nested keys in the argument
// data are stored as a serialized string for performance reasons. Each
// entry will be stored as a separate argument named
// servicea_stuff:array_key.
$event->addArgumentArray('servicea_stuff', $stuff);
 
// Process the data somehow locally.
$processed_stuff = yourmodule_process_stuff($stuff);
// Also add the processed stuff to the log event.
$event->addArgumentArray('processed_stuff', $processed_stuff);
 
// Try to submit the processed data to Service B. This can result
// in an exception, so handle that.
try {
  $response = serviceb_send_stuff($processed_stuff);
  // Add final arguments and save the log event.
  $event
    ->setMessage('Synced ' . count($stuff) . ' pieces of stuff')
    ->addArgument('serviceb_response', $response);
    ->save();
}
catch (ServiceBException $e) {
  // Something wrent wrong, log as an error with the exception.
  $event
    ->addMessage('Failed to send stuff to service B')
    ->setSeverity(PAST_EVENT_ERROR)
    // This is a shortcut for addArgument('exception', $exception), all
    // exception arguments are automatically decoded and include the
    // message, exception location and message.
    ->addException($e)
    ->save();
}

View log events

Log messages can either be viewed using the drush integration or with the views-powered reports UI. The drush integration is similar to watchdog and allows to view a single log event, a (continuous) list of log events and log events can be filtered, see drush ps --help for more information.

The reports UI can be found at admin/reports/past and consists of a view that allows to search and filter log events and detail pages for each log event, displaying the data in a nicely formatted way.

Past detail page

Additional information

Visit the project page to learn more about Past and download it. Use the issue queue to ask support questions. Stay tuned for more articles about additional features provided by Past.