1: <?php
2: // $Id: logger.php,v 1.1 2007/05/15 02:34:21 minahito Exp $
3: // ------------------------------------------------------------------------ //
4: // XOOPS - PHP Content Management System //
5: // Copyright (c) 2000 XOOPS.org //
6: // <http://www.xoops.org/> //
7: // ------------------------------------------------------------------------ //
8: // This program is free software; you can redistribute it and/or modify //
9: // it under the terms of the GNU General Public License as published by //
10: // the Free Software Foundation; either version 2 of the License, or //
11: // (at your option) any later version. //
12: // //
13: // You may not change or alter any portion of this comment or credits //
14: // of supporting developers from this source code or any supporting //
15: // source code which is considered copyrighted (c) material of the //
16: // original comment or credit authors. //
17: // //
18: // This program is distributed in the hope that it will be useful, //
19: // but WITHOUT ANY WARRANTY; without even the implied warranty of //
20: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //
21: // GNU General Public License for more details. //
22: // //
23: // You should have received a copy of the GNU General Public License //
24: // along with this program; if not, write to the Free Software //
25: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //
26: // ------------------------------------------------------------------------ //
27: // Author: Kazumi Ono (AKA onokazu) //
28: // URL: http://www.myweb.ne.jp/, http://www.xoops.org/, http://jp.xoops.org/ //
29: // Project: The XOOPS Project //
30: // ------------------------------------------------------------------------- //
31:
32: /**
33: * Collects information for a page request
34: *
35: * <b>Singelton:</b> There can be only one instance of this class and it must
36: * be accessed through the {@link instance()} method!
37: *
38: * records information about database queries, blocks, and execution time
39: * and can display it as HTML
40: *
41: * @author Kazumi Ono <onokazu@xoops.org>
42: * @copyright copyright (c) 2000-2003 XOOPS.org
43: *
44: * @package kernel
45: */
46: class XoopsLogger
47: {
48: /**#@+
49: * @var array
50: */
51: var $queries = array();
52: var $blocks = array();
53: var $extra = array();
54: var $logstart = array();
55: var $logend = array();
56: /**#@-*/
57:
58: /**
59: * constructor
60: *
61: * @access private
62: */
63: public function XoopsLogger()
64: {
65:
66: }
67:
68: /**
69: * get a reference to the only instance of this class
70: *
71: * @return object XoopsLogger reference to the only instance
72: */
73: public static function &instance()
74: {
75: static $instance;
76: if (!isset($instance)) {
77: $instance = new XoopsLogger();
78: }
79: return $instance;
80: }
81:
82: /**
83: * start a timer
84: *
85: * @param string $name name of the timer
86: *
87: */
88: function startTime($name = 'XOOPS')
89: {
90: $this->logstart[$name] = explode(' ', microtime());
91: }
92:
93: /**
94: * stop a timer
95: *
96: * @param string $name name of the timer
97: */
98: function stopTime($name = 'XOOPS')
99: {
100: $this->logend[$name] = explode(' ', microtime());
101: }
102:
103: /**
104: * log a database query
105: *
106: * @param string $sql SQL string
107: * @param string $error error message (if any)
108: * @param int $errno error number (if any)
109: */
110: function addQuery($sql, $error=null, $errno=null)
111: {
112: $this->queries[] = array('sql' => $sql, 'error' => $error, 'errno' => $errno);
113: }
114:
115: /**
116: * log display of a block
117: *
118: * @param string $name name of the block
119: * @param bool $cached was the block cached?
120: * @param int $cachetime cachetime of the block
121: */
122: function addBlock($name, $cached = false, $cachetime = 0)
123: {
124: $this->blocks[] = array('name' => $name, 'cached' => $cached, 'cachetime' => $cachetime);
125: }
126:
127: /**
128: * log extra information
129: *
130: * @param string $name name for the entry
131: * @param int $msg text message for the entry
132: */
133: function addExtra($name, $msg)
134: {
135: $this->extra[] = array('name' => $name, 'msg' => $msg);
136: }
137:
138: /**
139: * get the logged queries in a HTML table
140: *
141: * @return string HTML table with queries
142: */
143: function dumpQueries()
144: {
145: $ret = '<table class="outer" width="100%" cellspacing="1"><tr><th>Queries</th></tr>';
146: $class = 'even';
147: foreach ($this->queries as $q) {
148: if (isset($q['error'])) {
149: $ret .= '<tr class="'.$class.'"><td><span style="color:#ff0000;">'.htmlentities($q['sql']).'<br /><b>Error number:</b> '.$q['errno'].'<br /><b>Error message:</b> '.$q['error'].'</span></td></tr>';
150: } else {
151: $ret .= '<tr class="'.$class.'"><td>'.htmlentities($q['sql']).'</td></tr>';
152: }
153: $class = ($class == 'odd') ? 'even' : 'odd';
154: }
155: $ret .= '<tr class="foot"><td>Total: <span style="color:#ff0000;">'.count($this->queries).'</span> queries</td></tr></table><br />';
156: return $ret;
157: }
158:
159: /**
160: * get the logged blocks in a HTML table
161: *
162: * @return string HTML table with blocks
163: */
164: function dumpBlocks()
165: {
166: $ret = '<table class="outer" width="100%" cellspacing="1"><tr><th colspan="2">Blocks</th></tr>';
167: $class = 'even';
168: foreach ($this->blocks as $b) {
169: if ($b['cached']) {
170: $ret .= '<tr><td class="'.$class.'"><b>'.htmlspecialchars($b['name']).':</b> Cached (regenerates every '.intval($b['cachetime']).' seconds)</td></tr>';
171: } else {
172: $ret .= '<tr><td class="'.$class.'"><b>'.htmlspecialchars($b['name']).':</b> No Cache</td></tr>';
173: }
174: $class = ($class == 'odd') ? 'even' : 'odd';
175: }
176: $ret .= '<tr class="foot"><td>Total: <span style="color:#ff0000;">'.count($this->blocks).'</span> blocks</td></tr></table><br />';
177: return $ret;
178: }
179:
180: /**
181: * get the current execution time of a timer
182: *
183: * @param string $name name of the counter
184: * @return float current execution time of the counter
185: */
186: function dumpTime($name = 'XOOPS')
187: {
188: if (!isset($this->logstart[$name])) {
189: return 0;
190: }
191: if (!isset($this->logend[$name])) {
192: $stop_time = explode(' ', microtime());
193: } else {
194: $stop_time = $this->logend[$name];
195: }
196: return ((float)$stop_time[1] + (float)$stop_time[0]) - ((float)$this->logstart[$name][1] + (float)$this->logstart[$name][0]);
197: }
198:
199: /**
200: * get extra information in a HTML table
201: *
202: * @return string HTML table with extra information
203: */
204: function dumpExtra()
205: {
206: $ret = '<table class="outer" width="100%" cellspacing="1"><tr><th colspan="2">Extra</th></tr>';
207: $class = 'even';
208: foreach ($this->extra as $ex) {
209: $ret .= '<tr><td class="'.$class.'"><b>'.htmlspecialchars($ex['name']).':</b> '.htmlspecialchars($ex['msg']).'</td></tr>';
210: $class = ($class == 'odd') ? 'even' : 'odd';
211: }
212: $ret .= '</table><br />';
213: return $ret;
214: }
215:
216: /**
217: * get all logged information formatted in HTML tables
218: *
219: * @return string HTML output
220: */
221: function dumpAll()
222: {
223: $ret = $this->dumpQueries();
224: $ret .= $this->dumpBlocks();
225: if (count($this->logstart) > 0) {
226: $ret .= '<table class="outer" width="100%" cellspacing="1"><tr><th>Execution Time</th></tr>';
227: $class = 'even';
228: foreach ($this->logstart as $k => $v) {
229: $ret .= '<tr><td class="'.$class.'"><b>'.htmlspecialchars($k).'</b> took <span style="color:#ff0000;">'.$this->dumpTime($k).'</span> seconds to load.</td></tr>';
230: $class = ($class == 'odd') ? 'even' : 'odd';
231: }
232: $ret .= '</table><br />';
233: }
234: $ret .= $this->dumpExtra();
235: return $ret;
236: }
237: }
238: ?>