This repository has been archived by the owner on May 26, 2018. It is now read-only.
/
2010-09-10-logging-into-couchdb-using-zend-framework.html
184 lines (160 loc) · 6.45 KB
/
2010-09-10-logging-into-couchdb-using-zend-framework.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
---
layout: post
title: Logging into CouchDb using Zend Framework
published: true
meta:
delicious: a:3:{s:5:"count";s:1:"2";s:9:"post_tags";s:0:"";s:4:"time";s:10:"1315952952";}
_edit_lock: "1284138616"
_edit_last: "2153812"
_wp_old_slug: ""
reddit: a:2:{s:5:"count";s:1:"0";s:4:"time";s:10:"1315952953";}
jabber_published: "1284138409"
tags:
- couchdb
- php
type: post
status: publish
---
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:
<pre>
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");
}
}
}
</pre>
In application ini have to set libraries and options for connect to CouchDb database, you can make yours on <a href="http://couchone.com">http://couchone.com</a> or use local instalation. More info for instalation you can find in <a href="http://wiki.apache.org/couchdb/Installation">Couch Db wiki</a>.
<pre>
autoloaderNamespaces.phly = "Phly_"
autoloaderNamespaces.app = "App_"
; Options for CouchDb
couchdb.host = prskavec.couchone.com
couchdb.port = 80
couchdb.db = "test-log"
</pre>
in indexController i have two action, indexAction for display logs and logAction for creating some dummy log records.
<pre>
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 {
$form->populate($formData);
}
} 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);
$writer->setFormatter($formatter);
$logger->addWriter($writer);
$logger->setEventItem('module', $this->getRequest()->getModuleName());
$logger->setEventItem('controller', $this->getRequest()->getControllerName());
$logger->log("Testovani chyba", $id);
$this->_helper->flashMessenger->addMessage('Log item saved');
$this->_helper->redirector('index');
}
}
</pre>
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 <a href="http://wiki.apache.org/couchdb/Getting_started_with_Futon">Futon</a>.
In controller i create two views.
First for priority, save as: logger/log_by_prior
<pre>
function(doc) {
if (doc.priority) {
emit(doc.priority, [doc.priorityName, doc.timestamp, doc.message, doc.module, doc.controller]);
}
}
</pre>
Second for timestamp, save as: logger/log_by_timestamp
<pre>
function(doc) {
if (doc.timestamp) {
emit(doc.timestamp, [doc.priorityName, doc.message, doc.module, doc.controller]);
}
}
</pre>
Whole example you can find on <a href="http://github.com/abtris/phplogger-couchdb">my github</a>. In example using CouchDb library make by <a href="http://github.com/weierophinney/phly">Matthew Weier O’Phinney</a> and I make some improvement for actual version CouchDb 1.0.1.
I think this is useful solution for many applications.