Logging in Zend Framework (Zend_Log & Zend_Log_Writer_Db)

Adding logging capability to your application is an important step towards enhanced security and efficient troubleshooting. The Zend framework makes it really easy to incorporate logging.

The main class for Logging is the Zend_Log class. In order to accomplish the ‘actual writing’ to log, you need to make use of a ‘writer’ class. The writer class encapsulates algorithms to write to different destinations. For example,

  1. Zend_Log_Writer_Stream - Write to flat file
  2. Zend_Log_Writer_Db - Write to a database table
  3. Zend_Log_Writer_Firebug - Write to firebug console
  4. Zend_Log_Writer_Mail - Send out emails using the Zend_Mail component

This concept is akin to using different adapters for Zend_Auth.

My personal preference is to use Zend_Log_Writer_Db. This is mainly because a database table offers much greater flexibility in searching (querying) for events of importance than a flat file. Also, when using files for logging, the webserver must have write permissions on the folder housing the log file(s).

Step1 : Create the database table to hold log entries

CREATE TABLE `log_table` (
`priority` varchar(50) default NULL,
`message` varchar(100) default NULL,
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`username` varchar(40) default NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Whenever a log event is raised, the following keys are made available to us automagically by the framework: timestamp, message, priority, and priorityName.

Of course custom fields may be added to the default array.. In this example, I have added the username field.

Step2: Add the required initialization lines in the bootstrapper file (index.php)

The basic syntax is to first create a Zend_Log_Writer_Db object :
$writer = new Zend_Log_Writer_Db($db, ‘log_table’, $columnMapping);

Then, pass that writer object to a Zend_Log instance like so:
$logger = new Zend_Log($writer);

Note the use of a $columnMapping parameter. This is an array that maps table column names to fields in the event array. In our case, we could define it as:

$columnMapping = array(‘priority’ => ‘priority’, ‘message’ => ‘message’,
‘timestamp’ => ‘timestamp’, ‘username’ => ‘username’
);

The setEventItem() method of the Zend_Log object is used to add custom fields into the event array.
The final code in index.php is :

// Set up the logging system and put it in the Zend Registry.
$columnMapping = array(‘priority’ => ‘priority’, ‘message’ => ‘message’,
‘timestamp’ => ‘timestamp’, ‘username’ => ‘username’
);
$logger = new Zend_Log(new Zend_Log_Writer_Db($db, ‘log_table’, $columnMapping));
Zend_Registry::set(‘logger’,$logger);

Note that the setEventItem() function can be invoked at a later time when the data is actually available. I use the following code to assign the username in my base action controller

$this->logger->setEventItem(‘username’, $this->auth->getIdentity());

Step 3: Isolating common code

Those of you who have read my earlier posts, know that I prefer isolating all common code into a base controller for global use. Continuing with that philosophy, the base controller is now modified as :

<?php
class BaseController extends Zend_Controller_Action
{
protected $db;
protected $auth;
protected $messenger;
protected $logger;
public function init()
{
$this->db = Zend_Db_Table::getDefaultAdapter();
$this->view->baseUrl = Zend_Controller_Front::getInstance()->getBaseUrl();
$this->auth=Zend_Auth::getInstance();
$this->logger=Zend_Registry::get(‘logger’);
$this->logger->setEventItem(‘username’, $this->auth->getIdentity());

$this->messenger=$this->_helper->FlashMessenger;
}
public function postDispatch()
{
$this->view->messages = $this->messenger->getCurrentMessages();
}
}
?>

Simple enough.. The logger object is retrieved from the Zend_Registry and the ‘username’ field is assigned a value from the instance of Zend_Auth. The logger object is also available in every controller that inherits from the Base_Controller using $this->logger

Step 4: Writing a log entry

The final step is to actually record data in our log_table. This is as easy as adding the following line at any point in your action script:

$this->logger->info(‘Login Successful’);

This is what log_table looks like after a successful log entry:

image

As always, please feel free to leave comments or any questions that you may have. Also, take a look at the Zend frame work documentation for additional information regarding logging.

Advertisements

2 thoughts on “Logging in Zend Framework (Zend_Log & Zend_Log_Writer_Db)

  1. Thanks! This helped to clarify. The reference guide on that is somewhat crude. It’s not mentioning the automagic and the important setEventItem method. The the log writer concept of ZF is truly great nevertheless.
    Cheers from Cologne, Germany.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s