How to register Zend_Log in the bootstrap of a ZF 1.8+ application?
-
20-09-2019 - |
Question
So I want to start logging in my Zend Framework application. I want to register the logger somewhere in my bootstrap so that I can easily access it from any controller action. I think this should be a simple thing that has been done before, but how can I do this?
The documentation shows something like this, but I don't want to create a new Zend_Log every time I want to log something:
$writer = new Zend_Log_Writer_Stream('/path/to/my/log/file');
$logger = new Zend_Log($writer);
$logger->log('Informational message', Zend_Log::INFO);
Solution
This is what I came up with. Thanks for the reminder about Zend_Registry!
// in /application/Bootstrap.php
protected function _initLogger()
{
$writer = new Zend_Log_Writer_Stream('php://output');
$logger = new Zend_Log($writer);
Zend_Registry::set('logger', $logger);
}
// in controller actions
$logger = Zend_Registry::get('logger');
$logger->log('message');
Solution
The easiest is to use Zend_Registry to store the log
Use this inside your bootstrap
Zend_Registry::set('log', $log);
and use this to fetch that log
Zend_Registry::get('log')
OTHER TIPS
I did nearly the same but logging to a db. Here my code I placed in the Bootstrap
public function _initLogger(){
$resource = $this->getPluginResource('db');
$dbAdapter = $resource->getDbAdapter();
$columnMapping = array(
'level' => 'priorityName',
'priority' => 'priority',
'message' => 'message',
'created' => 'timestamp',
'user_agent'=> 'user_agent',
'get_vars' => 'get_vars',
'post_vars' => 'post_vars',
'ip' => 'ip'
);
$writerDb = new Zend_Log_Writer_Db($dbAdapter, 'tbl_history', $columnMapping);
$logger = new Zend_Log($writerDb);
$logger->setEventItem('datetime',date('Y-m-d H:i:s'));
$logger->setEventItem('user_agent',$_SERVER['HTTP_USER_AGENT']);
$logger->setEventItem('get_vars',print_r($_GET,true));
$logger->setEventItem('post_vars',print_r($_POST,true));
$logger->setEventItem('ip',$_SERVER['REMOTE_ADDR']);
Zend_Registry::set('logger', $logger);
}
And access it from anywhere like :
Zend_Registry::get('logger')->log('log emergency message', Zend_Log::EMERG);
Zend_Registry::get('logger')->info('just logging some information');
Hope this helps to ;)
Like this maybe;
/*
* In case of need to change Log object
*
* $options['writer'] = Zend_Log_Writer_...();
*
* @param array $options Configuration options
*/
protected function _initLog(array $options = array())
{
$writer = new Zend_Log_Writer_Null();
if(array_key_exists('writer', $options))
{
if($options['writer'] instanceof Zend_Log_Writer_Abstract) {
$writer = $options['writer'];
}
else {
if(class_exists($options['writer'])) {
$writer = new $options['writer'];
}
else {
throw new H2B_Exception("Writer class not found", H2B_Messages_Generic::OBJECT_NOT_FOUND);
}
}
}
$logger = new Zend_Log($writer);
return $logger;
}
Having just written a logging class, maybe by sharing what I did you'll get some ideas...
From index.php (on ZF 1.62) I call a static method from a class in my library, it determines whether you're in dev or higher, then gives you an appropriate logger. In dev it will log to Firebug, in stage+ it will log to file...I plan to add an emergency logger that will send email alerts on bad events like a failed query which might indicate an attempt to inject into the dB...
Then in my base Controller from which all controllers extend, I call the logger. This way all actions need only one line to talk to the logger...e.g. $this->_logger->debug('test');
Saving one line may not seem like a big deal, but when you're just spitting out debug messages that you plan to delete a minute later, it's really annoying to remember syntax and type both...
Also, by spitting out to firebug, you don't have to deal w/ messing up layout nor removing the debug message right away, since it'll never show in production.