Top Topic ?

Logging into CouchDb using Zend Framework

Posted in php by Ladislav Prskavec on September 10, 2010

Logging in web applications are common task. Mostly i’m using logging into files. When you can some statistics data is better use database for logs. You can use RBMS (MySQL, PostgreSQL) but is problem with changing schema. NoSQL database as CouchDb can be solution. Here is my implementation in Zend Framework.

For writing into database i use log writer:

class App_Log_Writer_CouchDb extends Zend_Log_Writer_Abstract
     * Db
     * @var Phly_Couch
    private $_db;
     * CouchDb host localhost default
     * @var string
    private $_host;
     * Couchdb port 3184 default
     * @var int
    private $_port;
     * @param array $params
     * @return void
    public function __construct($dbname, $options = null)
        if (is_null($options)) {
            $options['host'] = "localhost";
            $options['port'] = "5984";
            $options['db'] = $dbname;
        $this->_db = new Phly_Couch($options);

    static public function factory($config)
        $config = self::_parseConfig($config);
        return $config;
     * @param array $event
     * @return void
    protected function _write($event)
        // action body
        $doc = new Phly_Couch_Document($event);
        $result = $this->_db->docSave($doc);
        // return array ok, id, rev
        $info = $result->getInfo();
        if (!$info['ok']) {
            throw new Zend_Log_Exception("Error in save to CouchDb");


In application ini have to set libraries and options for connect to CouchDb database, you can make yours on or use local instalation. More info for instalation you can find in Couch Db wiki.

autoloaderNamespaces.phly = "Phly_" = "App_"
; Options for CouchDb =
couchdb.port = 80
couchdb.db = "test-log"

in indexController i have two action, indexAction for display logs and logAction for creating some dummy log records.

class IndexController extends Zend_Controller_Action
    protected $_config;

    public function preDispatch()  
            $this->_config = new Zend_Config_Ini('../application/configs/'.
                    'application.ini', APPLICATION_ENV);

    public function indexAction()
         $db = new Phly_Couch($this->_config->couchdb);

         $this->view->form = $form = new App_Form_Filter();
         if ($this->getRequest()->isPost()) {
             $formData = $this->getRequest()->getPost();
             if ($form->isValid($formData)) {
                 $filterValue = $form->getValue('filter');
                 $dateFrom = $form->getValue('datefrom');
                 $dateTo = $form->getValue('dateto');
                 if (empty($filterValue) || $filterValue===0) $filterValue = null;
                 if (empty($dateFrom)) $dateFrom = null;
                 if (empty($dateTo)) $dataTo = null;
                 if (!is_null($dateFrom) && !is_null($dateTo)) {
                 $result = $db->view('logger','log_by_timestamp', array($dateFrom, $dateTo), array("db"=>$this->_config->couchdb->db));
                 } else {
                 $result = $db->view('logger','log_by_prior', $filterValue, array("db"=>$this->_config->couchdb->db));

             } else {
         } else {
            $result = $db->view('logger','log_by_prior', null, array("db"=>$this->_config->couchdb->db));         
         $this->view->docs = $result->toArray();
         $this->view->messages = $this->_helper->flashMessenger->getMessages();
         $logger = new Zend_Log();
         $r = new ReflectionClass($logger);
         $this->view->priorities = array_flip($r->getConstants());


    public function logAction()
          $id = $this->_request->getParam('id', 0);  

          $logger = new Zend_Log();
          $format = '%timestamp% %priorityName% (%priority%): '.
            '[%module%] [%controller%] %message%';                                                                                                
          $formatter = new Zend_Log_Formatter_Simple($format);
          $writer = new App_Log_Writer_CouchDb($this->_config->couchdb->db, $this->_config->couchdb);

          $logger->setEventItem('module', $this->getRequest()->getModuleName());
          $logger->setEventItem('controller', $this->getRequest()->getControllerName());                        
          $logger->log("Testovani chyba", $id);
          $this->_helper->flashMessenger->addMessage('Log item saved');


In controller I call view in CouchDb database and this use parametr log level or time interval for display logs. For manage views in CouchDb can use Futon.

In controller i create two views.

First for priority, save as: logger/log_by_prior

function(doc) {
  if (doc.priority) {
     emit(doc.priority, [doc.priorityName, doc.timestamp, doc.message, doc.module, doc.controller]);

Second for timestamp, save as: logger/log_by_timestamp

function(doc) {
  if (doc.timestamp) {
     emit(doc.timestamp, [doc.priorityName, doc.message, doc.module, doc.controller]);

Whole example you can find on my github. In example using CouchDb library make by Matthew Weier O’Phinney and I make some improvement for actual version CouchDb 1.0.1.

I think this is useful solution for many applications.

Tagged with:

One Response

Subscribe to comments with RSS.

  1. Javier Gonel said, on September 28, 2010 at 5:31 pm

    Nice idea.

    I’m working in something similar. I log to a udp packet then a Node.js insterts that into couchdb.

    Udp logging is quite cheap, you don’t need to open connections and many logging frameworks have udp integrated.

Leave a Reply

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

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

Google photo

You are commenting using your Google 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 )

Connecting to %s

%d bloggers like this: