1 <?php
3 class logview extends plugin
4 {
5 /* Definitions */
6 var $plHeadline= "System logs";
7 var $plDescription= "This does something";
9 /* attribute list for save action */
10 var $attributes= array();
11 var $objectclasses= array();
12 var $start= 0;
13 var $sort= 2;
14 var $sort_direction= "down";
15 var $hostlist= array();
16 var $loglevellist= array();
17 var $tilist= array();
18 var $fields= array("log_level", "host", "time_stamp", "message");
19 var $last= array("log_level", "host", "time", "regex");
20 var $range = 25;
21 var $view_logged = FALSE;
23 function logview (&$config, $dn= NULL)
24 {
25 /* Include config object */
26 $this->config= &$config;
28 /* Get global filter config */
29 if (!session::is_set("logfilter")){
30 $logfilter= array(
31 "time" => "1",
32 "log_level" => "!All",
33 "host" => "!All",
34 "regex" => "*");
36 session::set("logfilter", $logfilter);
37 }
39 $this->ui = get_userinfo();
40 }
42 function execute()
43 {
44 /* Call parent execute */
45 plugin::execute();
47 /* Log view */
48 if(!$this->view_logged){
49 $this->view_logged = TRUE;
50 new log("view","logview/".get_class($this),$this->dn);
51 }
53 $logfilter= session::get("logfilter");
54 $smarty= get_smarty();
55 $smarty->assign("search_result", "");
56 $smarty->assign("plug", "?plug=".validate($_GET['plug']));
57 $smarty->assign("search_image", get_template_path('images/search.png'));
58 $smarty->assign("time_image", get_template_path('images/time.png'));
59 $smarty->assign("server_image", get_template_path('images/server.png'));
60 $smarty->assign("log_image", get_template_path('images/log_warning.png'));
61 $smarty->assign("ruleset_image", get_template_path('images/edit.png'));
62 $smarty->assign("launchimage", get_template_path('images/launch.png'));
63 $smarty->assign("hostlist", $this->hostlist);
64 $smarty->assign("loglevellist", $this->loglevellist);
65 $smarty->assign("tilist", $this->tilist);
66 $smarty->assign("mode0", "");
67 $smarty->assign("mode1", "");
68 $smarty->assign("mode2", "");
69 $smarty->assign("mode3", "");
71 /* Assign select option content */
72 foreach( array("host", "log_level", "time", "regex") as $type){
73 $smarty->assign("$type", $logfilter[$type]);
74 }
76 /* Test connection to log database */
77 if (!isset($this->config->data['SERVERS']['LOG'])){
78 msg_dialog::display(_("Warning"), msgPool::noserver("syslog"), WARNING_DIALOG);
79 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
81 }elseif(!is_callable("mysql_connect")){
82 msg_dialog::display(_("Configuration error"), sprintf(_("Missing %s PHP extension!"), "mysql"), WARNING_DIALOG);
83 new log("debug","logview","Missing MYSQL extension.");
84 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
86 }else{
88 /* Cehck connection informations */
89 $cfg= $this->config->data['SERVERS']['LOG'];
91 /* Open link to database and check if it is valid */
92 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
93 if ($link === FALSE){
94 msg_dialog::display(_("Error"), msgPool::dbconnect($cfg['SERVER'],@mysql_error(),"Log view"), ERROR_DIALOG);
95 new log("debug","log view","dbconnect",array(),@mysql_error());
96 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
97 }
99 /* check of log database is available */
100 if (! @mysql_select_db("gomon")){
101 msg_dialog::display(_("Error"), msgPool::dbselect("gomon",@mysql_error(),"Log view"), ERROR_DIALOG);
102 new log("debug","log view","dbselect",array(),@mysql_error());
103 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
104 }
106 /* Get Host list, if still empty */
107 if(count($this->hostlist) == 0){
109 /* Query database and check results */
110 $query= "SELECT DISTINCT host FROM golog LIMIT 200;";
111 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__, $query, "Database query");
112 $result = @mysql_query($query);
113 if ($result === false){
114 msg_dialog::display(_("Error"), msgPool::dbquery("golog",@mysql_error(),"Log view"), ERROR_DIALOG);
115 new log("debug","log view","dbquery",array(),@mysql_error());
116 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
117 }
119 /* Add hostnames to list */
120 while ($line = mysql_fetch_array($result, MYSQL_ASSOC)){
121 $this->hostlist[$line['host']]= $line['host'];
122 }
123 $this->hostlist['!All']= _("All");
124 ksort($this->hostlist);
125 $smarty->assign("hostlist", $this->hostlist);
126 }
128 /* Get log level list */
129 if(count($this->loglevellist) == 0){
131 /* Try to get all used log level types */
132 $query= "SELECT DISTINCT log_level FROM golog LIMIT 200;";
133 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__, $query, "Database query");
134 $result = @mysql_query($query);
135 if ($result === false){
136 msg_dialog::display(_("Error"), msgPool::dbquery("golog",@mysql_error(),"Log view"), ERROR_DIALOG);
137 new log("debug","log view","dbquery",array(),@mysql_error());
138 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
139 }
141 /* Add each etry to log level list */
142 while ($line = mysql_fetch_array($result, MYSQL_ASSOC)){
143 $this->loglevellist[$line['log_level']]= $line['log_level'];
144 }
145 $this->loglevellist['!All']= _("All");
146 ksort($this->loglevellist);
147 $smarty->assign("loglevellist", $this->loglevellist);
148 }
149 }
151 /* Set list of available time sequences */
152 if(count($this->tilist) == 0){
154 /* Time interval */
155 $this->tilist= array("0" => _("one hour"), "1" => _("6 hours"),
156 "2" => _("12 hours"), "3" => _("24 hours"),
157 "4" => _("2 days"), "5" => _("one week"),
158 "6" => _("2 weeks"), "7" => _("one month"));
159 $smarty->assign("tilist", $this->tilist);
160 }
162 $smarty->assign("regex", $logfilter['regex']);
165 /* Get acls */
167 $tmp_cat_bases = $this->ui->get_module_departments("logview");
168 $all_acls = "";
169 foreach($tmp_cat_bases as $acl_base){
170 $all_acls .= $this->ui->get_permissions($acl_base,"logview/logview");
171 }
172 if(count($tmp_cat_bases) == 0 || !preg_match("/r/",$all_acls)){
173 $res = "<tr>
174 <td colspan=4>
175 ".msgPool::permView()."
176 </td>
177 </tr>";
179 /* Show main page */
180 $smarty->assign("range_selector", "");
181 $smarty->assign("search_result", $res);
182 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
183 }
185 /* Query stuff */
186 $res= "";
187 $cfg = $this->config->data['SERVERS']['LOG'];
188 $tmp = set_error_handler('dummy_error_handler');
189 $link = @mysql_pconnect($cfg['SERVER'], $cfg['LOGIN'], $cfg['PASSWORD']);
190 set_error_handler($tmp);
192 /* Test connection object && create up query string */
193 if ($link === FALSE){
194 msg_dialog::display(_("Error"), msgPool::dbconnect($cfg['SERVER'],@mysql_error(),"Log view"), ERROR_DIALOG);
195 new log("debug","log view","dbconnect",array(),@mysql_error());
196 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
197 } else {
198 if (! @mysql_select_db("gomon")){
199 msg_dialog::display(_("Error"), msgPool::dbselect("gomon",@mysql_error(),"Log view"), ERROR_DIALOG);
200 new log("debug","log view","dbselect",array(),@mysql_error());
201 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
202 } else {
204 /* Assemble time query */
205 switch ($logfilter['time']){
206 case '0':
207 $start= date ("YmdHis", time() - 3600);
208 break;
209 ;;
210 case '1':
211 $start= date ("YmdHis", time() - 21600);
212 break;
213 ;;
214 case '2':
215 $start= date ("YmdHis", time() - 43200);
216 break;
217 ;;
218 case '3':
219 $start= date ("YmdHis", time() - 86400);
220 break;
221 ;;
222 case '4':
223 $start= date ("YmdHis", time() - 172800);
224 break;
225 ;;
226 case '5':
227 $start= date ("YmdHis", time() - 604800);
228 break;
229 ;;
230 case '6':
231 $start= date ("YmdHis", time() - 1209600);
232 break;
233 ;;
234 case '7':
235 $start= date ("YmdHis", time() - 2419200);
236 break;
237 ;;
238 }
240 /* Assemble log level query */
241 if ($logfilter['log_level'] == '!All'){
242 $ll= "";
243 } else {
244 $ll= "AND log_level='".$logfilter['log_level']."'";
245 }
246 if ($logfilter['host'] == '!All'){
247 $hf= "";
248 } else {
249 $hf= "AND host='".$logfilter['host']."'";
250 }
252 /* Order setting */
253 if ($this->sort_direction == "down"){
254 $desc= "DESC";
255 $sort_sign = "\\/";
256 } else {
257 $desc= "";
258 $sort_sign="/\\";
259 }
260 $end= date ("YmdHis");
261 $query_base= " FROM
262 golog
263 WHERE
264 message like '".preg_replace("/\*/","%",$logfilter['regex'])."'
265 $ll
266 $hf
267 AND
268 time_stamp <= $end AND time_stamp >= $start";
270 /* Get number of entries */
271 $query= "SELECT COUNT(*)".$query_base.";";
272 $result = @mysql_query($query);
273 if(!$result){
274 msg_dialog::display(_("Error"), msgPool::dbquery("golog",@mysql_error(),"Log view"), ERROR_DIALOG);
275 new log("debug","log view","dbquery",array(),@mysql_error());
276 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
277 }
278 $line= mysql_fetch_array($result, MYSQL_ASSOC);
279 $count= $line['COUNT(*)'];
280 if ($count > 25){
281 $smarty->assign("range_selector", range_selector($count, $this->start, $this->range,"EntriesPerPage"));
282 } else {
283 $smarty->assign("range_selector", "");
284 }
286 /* Query results */
287 $query= "SELECT *".$query_base." ORDER BY ".$this->fields[$this->sort]." $desc LIMIT ".$this->start.",".$this->range.";";
288 @DEBUG (DEBUG_MYSQL, __LINE__, __FUNCTION__, __FILE__, $query, "Database query");
289 $result = @mysql_query($query);
290 if(!$result){
291 msg_dialog::display(_("Error"), msgPool::dbquery("golog",@mysql_error(),"Log view"), ERROR_DIALOG);
292 new log("debug","log view","dbquery",array(),@mysql_error());
293 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
294 }
295 /* Display results */
296 $mod= 0;
298 /* Add entries to result str */
299 while ($line = mysql_fetch_array($result, MYSQL_ASSOC)){
301 /* Toggle background color */
302 if ( ($mod++) & 1){
303 $col= "background-color: #ECECEC;";
304 } else {
305 $col= "background-color: #F5F5F5;";
306 }
308 $res.=" <tr style=\"$col\">\n";
309 $res.=" <td style=\"text-align:center\">
310 <img alt=\"".$line['log_level']."\"
311 src=\"".get_template_path('images/log_'.strtolower($line['log_level'])).".png\"
312 title=\"Log level is '".$line['log_level']."'\">
313 </td>";
314 $res.=" <td>".
315 $line['host']."
316 </td>";
317 $res.=" <td>".
318 $line['time_stamp']."
319 </td>";
320 $res .= "<td width=\"100%\">".
321 $line['message']."
322 </td>";
323 $res.=" </tr>\n";
324 }
325 mysql_close($link);
326 $smarty->assign("mode".$this->sort, $sort_sign);
327 $smarty->assign("host", $logfilter['host']);
328 $smarty->assign("log_level", $logfilter['log_level']);
330 $smarty->assign("search_result", $res);
331 }
332 }
334 /* Show main page */
335 return ($smarty->fetch (get_template_path('contents.tpl', TRUE)));
336 }
339 function save_object()
340 {
341 /* Get submitted range */
342 if(isset($_POST['EntriesPerPage'])){
343 if(is_numeric($_POST['EntriesPerPage'])){
344 $this->range = $_POST['EntriesPerPage'];
345 }
346 }
348 /* Save data */
349 $logfilter= session::get("logfilter");
351 /* Get actual select boxe values */
352 $logfilter_changed = 0;
353 foreach( array("host", "time", "log_level", "regex") as $type){
355 /* Set new value and test if value has changed */
356 $last[$type] = $logfilter[$type];
357 if (isset($_POST[$type])){
358 $logfilter[$type]= $_POST[$type];
359 }
361 if ($last[$type] != $logfilter[$type]){
362 $logfilter_changed = 1;
363 }
364 }
366 /* Filter regex values */
367 if ($logfilter['regex'] == ""){
368 $logfilter['regex']= '%';
369 } else {
370 $new = preg_replace('/\*\**/', '*', $logfilter['regex']);
371 $logfilter['regex']= $new;
372 }
374 /* Store filter values */
375 session::set("logfilter", $logfilter);
377 /* Set start value */
378 if (isset($_GET['start'])){
379 $this->start= (int)$_GET['start'];
380 }
382 /* Reset page number if filter has changed */
383 if ($logfilter_changed > 0){
384 $this->start= 0;
385 }
387 /* Adapt sorting */
388 if (isset($_GET['sort'])){
389 if ($this->sort == (int)$_GET['sort']){
390 if ($this->sort_direction == "down"){
391 $this->sort_direction= "up";
392 } else {
393 $this->sort_direction= "down";
394 }
395 }
396 $this->sort= (int)$_GET['sort'];
397 if ($this->sort < 0 || $this->sort > 3){
398 $this->sort= 0;
399 }
400 }
401 }
404 /* Return plugin informations for acl handling
405 #FIXME You can only read attributes within this report plugin */
406 static function plInfo()
407 {
408 return (array(
409 "plShortName" => _("Log view"),
410 "plDescription" => _("Log view addon"),
411 "plSelfModify" => FALSE,
412 "plDepends" => array(),
413 "plPriority" => 0,
414 "plSection" => array("addon"),
415 "plCategory" => array("logview" => array("objectClass" => "none", "description" => _("System logs"))),
417 "plProvidedAcls" => array()
418 ));
419 }
420 }
421 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
422 ?>