Just a quick post, but this is a nice way of setting up logging!
I have a class extending Zend_Controller_Action. Instead of my controllers extending Zend_Controller_Action, they now extend my own class. In that class, I added two methods, applicationLog(), and systemLog().
Application log will log user actions in your site, system log will log any exceptions or other stuff. The cool thing is, if you are using Firefox, you can send directly to the console!
In your base controller class:
/**
* Log any errors etc
* @param string $type
* @param string $message
*/
public function systemLogger($type='info',$message)
{
/** @var Zend_Log $log*/
$log = Zend_Registry::get('logger');
$log->$type($message);
}
/**
* Audit site usage
* @param string $type
* @param string $message
*/
public function applicationLogger($type='info',$message)
{
/** @var Zend_Log $log*/
$log = Zend_Registry::get('applog');
$log->setEventItem('category',$this->getRequest()->getControllerName());
$log->setEventItem('action',$this->getRequest()->getActionName());
/** @todo */
// $user = Zend_Registry::get('user');
// $log->setEventItem('user_id',$user->getId());
// $log->setEventItem('user_email',$user->getEmail());
$log->$type($message);
}
In your Bootstrap, initialise them like this:
/**
* Initialise Logger
*/
protected function _initLogging()
{
$this->bootstrap('frontController');
$logger = new Zend_Log();
date_default_timezone_set('Europe/London');
$logFileDatePart = date('Y-m-d', time());
switch ( $this->getEnvironment() ) {
case 'production' :
case 'staging' :
$writer = new Zend_Log_Writer_Stream(
APPLICATION_PATH . '/../data/logs/esos_' . $logFileDatePart . '.log');
$filter = new Zend_Log_Filter_Priority( Zend_Log::INFO );
break;
default :
$writer = new Zend_Log_Writer_Firebug();
$filter = new Zend_Log_Filter_Priority( Zend_Log::DEBUG );
break;
}
$logger->addWriter( $writer );
$logger->addFilter( $filter );
$this->_logger = $logger;
Zend_Registry::set('logger', $logger);
}
/**
* Initialise Application Log
*/
protected function _initApplicationLogging()
{
$db = Zend_Db_Table::getDefaultAdapter();
date_default_timezone_set('Europe/London');
$mapping = array(
'customer_email' => 'customer_email',
'customer_name' => 'customer_name',
'company_name' => 'company_name',
'category' => 'category',
'action' => 'action',
'description' => 'message',
'priority' => 'priority',
'priority_name' => 'priorityName',
'dump' => 'dump'
);
$applog = new Zend_Log();
$writer = new Zend_Log_Writer_Db( $db, 'applog', $mapping);
$filter = new Zend_Log_Filter_Priority( Zend_Log::DEBUG );
$applog->addWriter( $writer );
$applog->addFilter( $filter );
Zend_Registry::set('applog', $applog);
// set user params here to save having to do it each time applog is used
// $applog->info('application logging installed');
}
Only in a development environment will logs be sent to the firebug console. Otherwise, it will go in a log file. Set your path and permissions accordingly. Finally, create your DB table for the application log:
/*
* Application Log Table
*/
CREATE TABLE `esos_auditor`.`applog` (
id INT UNSIGNED UNIQUE NOT NULL AUTO_INCREMENT, -- id of log item
category VARCHAR(30), -- category of action / activity
action VARCHAR(30), -- action / activity
user_id INT UNSIGNED, -- id of user performing action
user_email VARCHAR(100), -- email address of user performing action
action_time TIMESTAMP default CURRENT_TIMESTAMP, -- time action ocurred
description VARCHAR(200), -- brief description of action
priority TINYINT, -- numeric log level
priority_name VARCHAR(20), -- Zend log level name
dump TEXT,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Now, in your controller (Extending your base class of course), you can call $this->systemLogger(‘err’,$e->getMessage()); in your catch blocks! You can have various levels of logging as per the Zend_Log page:
-
EMERG = 0; // Emergency: system is unusable
-
ALERT = 1; // Alert: action must be taken immediately
-
CRIT = 2; // Critical: critical conditions
-
ERR = 3; // Error: error conditions
-
WARN = 4; // Warning: warning conditions
-
NOTICE = 5; // Notice: normal but significant condition
-
INFO = 6; // Informational: informational messages
-
DEBUG = 7; // Debug: debug messages
Remember and use lower case when passing err or warn etc. Have fun with it!