Browse Source

Initial commit

Kai Kretschmann 3 years ago
commit
17360970da
18 changed files with 760 additions and 0 deletions
  1. 6
    0
      .htaccess
  2. 0
    0
      css/index.html
  3. 29
    0
      css/lggr.css
  4. 61
    0
      do.php
  5. 27
    0
      doc/db.sql
  6. BIN
      img/logo.png
  7. 1
    0
      inc/.htaccess
  8. 21
    0
      inc/config_class.php
  9. 0
    0
      inc/index.html
  10. 188
    0
      inc/lggr_class.php
  11. 70
    0
      inc/lggrstate_class.php
  12. 269
    0
      index.php
  13. 0
    0
      js/index.html
  14. 30
    0
      js/lggr.js
  15. 1
    0
      tpl/.htaccess
  16. 16
    0
      tpl/foot.inc.php
  17. 20
    0
      tpl/head.inc.php
  18. 21
    0
      tpl/paginate.inc.php

+ 6
- 0
.htaccess View File

@@ -0,0 +1,6 @@
1
+Options -indexes
2
+
3
+AuthType	Basic
4
+AuthName	"Restricted Area"
5
+AuthUserFile	/var/www/webuser
6
+Require		valid-user

+ 0
- 0
css/index.html View File


+ 29
- 0
css/lggr.css View File

@@ -0,0 +1,29 @@
1
+body > div {
2
+  margin-top: 3em;
3
+}
4
+
5
+.navbar-brand img {
6
+  height: 25px;
7
+}
8
+
9
+.datarow div {
10
+  white-space: nowrap;
11
+  overflow: hidden;
12
+}
13
+
14
+.datarow.even {
15
+ background-color: #e0e0e0;
16
+}
17
+.datarow.odd {
18
+ background-color: #c0c0c0;
19
+}
20
+
21
+.datarow .newlog-msg {
22
+	cursor: zoom-in;
23
+}
24
+
25
+p.debugfooter {
26
+	float: right;
27
+	color: #999999;
28
+	font-size: 75%;
29
+}

+ 61
- 0
do.php View File

@@ -0,0 +1,61 @@
1
+<?php
2
+
3
+require 'inc/lggr_class.php';
4
+require 'inc/lggrstate_class.php';
5
+
6
+session_start();
7
+
8
+if(!isset($_GET['a'])) {
9
+	header('Location: index.php');
10
+	exit;
11
+} // if
12
+
13
+if(isset($_SESSION[LggrState::SESSIONNAME])) {
14
+	$state = $_SESSION[LggrState::SESSIONNAME];
15
+} else {
16
+	$state = new LggrState();
17
+} // if
18
+
19
+
20
+switch($_GET['a']) {
21
+
22
+	case 'reset':
23
+		$state = new LggrState();
24
+		break;
25
+
26
+	case 'search':
27
+		$state = new LggrState();
28
+		$state->setSearch($_POST['q']);
29
+		break;
30
+
31
+	case 'host':
32
+		$state->setHost($_GET['host']);
33
+		$state->setPage(0);
34
+		break;
35
+
36
+	case 'level':
37
+		$state->setLevel($_GET['level']);
38
+		$state->setPage(0);
39
+		break;
40
+
41
+	case 'range':
42
+		$i = intval($_GET['range']);
43
+		$state->setRange($i);
44
+		$state->setPage(0);
45
+		break;
46
+	
47
+	case 'paginate':
48
+		if(isset($_GET['page'])) {
49
+			$i = intval($_GET['page']);
50
+			if($i<0) $i=0;
51
+
52
+			$page = $i;
53
+			$state->setPage($page);
54
+		} // if
55
+		break;
56
+
57
+} // switch
58
+
59
+$_SESSION[LggrState::SESSIONNAME] = $state;
60
+
61
+header('Location: index.php');

+ 27
- 0
doc/db.sql View File

@@ -0,0 +1,27 @@
1
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
2
+/*!40101 SET NAMES utf8mb4 */;
3
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
4
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
5
+
6
+-- Exportiere Struktur von Tabelle lggrdev.newlogs
7
+CREATE TABLE IF NOT EXISTS `newlogs` (
8
+  `id` bigint(20) NOT NULL AUTO_INCREMENT,
9
+  `date` datetime NOT NULL,
10
+  `facility` enum('kern','user','mail','daemon','auth','syslog','lpr','news','uucp','authpriv','ftp','cron','local0','local1','local2','local3','local4','local5','local6','local7') NOT NULL,
11
+  `level` enum('emerg','alert','crit','err','warning','notice','info','debug') NOT NULL,
12
+  `host` char(16) NOT NULL,
13
+  `program` varchar(50) NOT NULL,
14
+  `pid` int(10) unsigned NOT NULL,
15
+  `message` text NOT NULL,
16
+  PRIMARY KEY (`id`),
17
+  KEY `level` (`level`),
18
+  KEY `host` (`host`)
19
+) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='New logging table';
20
+
21
+CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `LastHour` AS select `logger`.`newlogs`.`id` AS `id`,`logger`.`newlogs`.`date` AS `date`,`logger`.`newlogs`.`facility` AS `facility`,`logger`.`newlogs`.`level` AS `level`,`logger`.`newlogs`.`host` AS `host`,`logger`.`newlogs`.`program` AS `program`,`logger`.`newlogs`.`pid` AS `pid`,`logger`.`newlogs`.`message` AS `message` from `logger`.`newlogs` where (`logger`.`newlogs`.`date` >= (now() - interval 1 hour));
22
+CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `Today` AS select `logger`.`newlogs`.`id` AS `id`,`logger`.`newlogs`.`date` AS `date`,`logger`.`newlogs`.`facility` AS `facility`,`logger`.`newlogs`.`level` AS `level`,`logger`.`newlogs`.`host` AS `host`,`logger`.`newlogs`.`program` AS `program`,`logger`.`newlogs`.`pid` AS `pid`,`logger`.`newlogs`.`message` AS `message` from `logger`.`newlogs` where (cast(now() as date) = cast(`logger`.`newlogs`.`date` as date));
23
+CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `Week` AS select `logger`.`newlogs`.`id` AS `id`,`logger`.`newlogs`.`date` AS `date`,`logger`.`newlogs`.`facility` AS `facility`,`logger`.`newlogs`.`level` AS `level`,`logger`.`newlogs`.`host` AS `host`,`logger`.`newlogs`.`program` AS `program`,`logger`.`newlogs`.`pid` AS `pid`,`logger`.`newlogs`.`message` AS `message` from `logger`.`newlogs` where (`logger`.`newlogs`.`date` >= (now() - interval 168 hour));
24
+
25
+/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */;
26
+/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */;
27
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;

BIN
img/logo.png View File


+ 1
- 0
inc/.htaccess View File

@@ -0,0 +1 @@
1
+deny from all

+ 21
- 0
inc/config_class.php View File

@@ -0,0 +1,21 @@
1
+<?php
2
+
3
+class Config {
4
+
5
+	const DBUSER = 'lggr';
6
+	const DBPWD  = 'lggr';
7
+	const DBNAME = 'lggrdev';
8
+
9
+	public function getDbUser() {
10
+		return self::DBUSER;
11
+	}
12
+
13
+	public function getDbPwd() {
14
+		return self::DBPWD;
15
+	}
16
+
17
+	public function getDbName() {
18
+		return self::DBNAME;
19
+	}
20
+
21
+} // class

+ 0
- 0
inc/index.html View File


+ 188
- 0
inc/lggr_class.php View File

@@ -0,0 +1,188 @@
1
+<?php
2
+
3
+require_once 'config_class.php';
4
+
5
+class Lggr {
6
+
7
+	private $config=null;
8
+	private $db=null;
9
+	private $state=null;
10
+
11
+	function __construct(LggrState $state) {
12
+		$this->config = new Config();
13
+		$this->state = $state;
14
+		$this->db = new mysqli('localhost', $this->config->getDbUSer(), $this->config->getDbPwd(), $this->config->getDbName());
15
+
16
+		$this->checkSecurity();
17
+	} // constructor
18
+
19
+	function __destruct() {
20
+		if(null != $this->db) {
21
+			$this->db->close();
22
+		} // if
23
+	} // destructor
24
+
25
+	private function checkSecurity() {
26
+		if(!isset($_SERVER['REMOTE_USER'])) {
27
+			throw new Exception('You must enable basic authentication');
28
+		} // if
29
+	} // function
30
+
31
+	private function getViewName() {
32
+		switch($this->state->getRange()) {
33
+			case 1:   return 'LastHour'; break;
34
+			case 24:  return 'Today'; break;
35
+			case 168: return 'Week'; break;
36
+			default:  return 'Today'; break;
37
+		}
38
+	}
39
+
40
+	function getLevels() {
41
+		$v = $this->getViewName();
42
+		$a = array();
43
+		$sql = "
44
+SELECT level, COUNT(*) AS c FROM $v
45
+GROUP BY level
46
+";
47
+
48
+		$res = $this->db->query($sql);
49
+		if(false === $res) {
50
+			throw new Exception($this->db->error);
51
+		} // if
52
+		while($row = $res->fetch_object()) {
53
+			$a[] = $row;
54
+		} // while
55
+		$res->close();
56
+
57
+		$sum = 0;
58
+		foreach($a as $level) {
59
+			$sum += $level->c;
60
+		} // foreach
61
+		foreach($a as $level) {
62
+			$f = $level->c / $sum * 100;
63
+			$level->f = round($f, 2);
64
+		} // foreach
65
+
66
+		return $a;
67
+	} // function
68
+
69
+	function getServers() {
70
+		$v = $this->getViewName();
71
+		$a = array();
72
+		$sql = "
73
+SELECT host, COUNT(*) AS c FROM $v
74
+GROUP BY host
75
+ORDER BY c DESC
76
+";
77
+
78
+		$res = $this->db->query($sql);
79
+		if(false === $res) {
80
+			throw new Exception($this->db->error);
81
+		} // if
82
+		while($row = $res->fetch_object()) {
83
+			$a[] = $row;
84
+		} // while
85
+		$res->close();
86
+
87
+		$sum = 0;
88
+		foreach($a as $host) {
89
+			$sum += $host->c;
90
+		} // foreach
91
+		foreach($a as $host) {
92
+			$f = $host->c / $sum * 100;
93
+			$host->f = round($f, 2);
94
+		} // foreach
95
+
96
+		return $a;
97
+	} // function
98
+
99
+	function getLatest($from=0, $count=100) {
100
+		$v = $this->getViewName();
101
+		$sql = "
102
+SELECT * FROM $v
103
+ORDER BY `date` DESC
104
+LIMIT $from,$count";
105
+
106
+		return $this->sendResult($sql);
107
+	} // function
108
+
109
+	function getFiltered($host=null, $level=null, $from=0, $count=100) {
110
+		$v = $this->getViewName();
111
+
112
+		$sql = "SELECT * FROM $v";
113
+
114
+		$aWhere = array();
115
+		if(null != $host) {
116
+			$sTmp = $this->db->escape_string($host);
117
+			$aWhere[] = "host='$sTmp'";
118
+		} // if
119
+		if(null != $level) {
120
+			$sTmp = $this->db->escape_string($level);
121
+			$aWhere[] = "level='$sTmp'";
122
+		} // if
123
+
124
+		if(count($aWhere) > 0) {
125
+			$sql .= " WHERE " . implode(' AND ', $aWhere);
126
+		} // if
127
+
128
+		$sql .= " ORDER BY `date` DESC LIMIT $from,$count";
129
+
130
+		return $this->sendResult($sql);
131
+	} // function
132
+
133
+	function getByHost($host, $from=0, $count=100) {
134
+		$v = $this->getViewName();
135
+		$sTmp = $this->db->escape_string($host);
136
+
137
+		$sql = "
138
+SELECT * FROM $v
139
+WHERE host='$sTmp'
140
+ORDER BY `date` DESC
141
+LIMIT $from,$count";
142
+
143
+		return $this->sendResult($sql);
144
+	} // function
145
+
146
+	function getByLevel($level, $from=0, $count=100) {
147
+		$v = $this->getViewName();
148
+		$sTmp = $this->db->escape_string($level);
149
+
150
+		$sql = "
151
+SELECT * FROM $v
152
+WHERE level='$sTmp'
153
+ORDER BY `date` DESC
154
+LIMIT $from,$count";
155
+
156
+		return $this->sendResult($sql);
157
+	} // function
158
+
159
+	function getText($q, $from=0, $count=100) {
160
+		$v = $this->getViewName();
161
+		$sTmp = $this->db->escape_string($q);
162
+
163
+		$sql = "
164
+SELECT * FROM $v
165
+WHERE message LIKE '%{$sTmp}%'
166
+ORDER BY `date` DESC
167
+LIMIT $from,$count";
168
+
169
+		return $this->sendResult($sql);
170
+
171
+	} // function
172
+
173
+	private function sendResult($sql) {
174
+		$a = array();
175
+
176
+		$res = $this->db->query($sql);
177
+		if(false === $res) {
178
+			throw new Exception($this->db->error);
179
+		} // if
180
+		while($row = $res->fetch_object()) {
181
+			$a[] = $row;
182
+		} // while
183
+
184
+		$res->close();
185
+		return $a;
186
+	} // function
187
+
188
+} // class

+ 70
- 0
inc/lggrstate_class.php View File

@@ -0,0 +1,70 @@
1
+<?php
2
+
3
+class LggrState {
4
+
5
+	const SESSIONNAME = 'LggrState';
6
+
7
+	private $bSearch=false;
8
+	private $sSearch=null;
9
+	private $iPage=0;
10
+	private $sHost=null;
11
+	private $sLevel=null;
12
+	private $iRange=24; // default 24h = today, sort of
13
+
14
+	function __construct() {
15
+		$this->iPage=0;
16
+		$this->bSearch=false;
17
+		$this->sSearch=null;
18
+		$this->sHost=null;
19
+		$this->sLevel=null;
20
+		$this->iRange=24;
21
+	} // constructor
22
+
23
+	public function setSearch($s) {
24
+		if(null != $s) {
25
+			$this->bSearch = true;
26
+			$this->sSearch = $s;
27
+		}
28
+	}
29
+	public function isSearch() {
30
+		return $this->bSearch;
31
+	}
32
+	public function getSearch() {
33
+		return $this->sSearch;
34
+	}
35
+
36
+	public function setPage($i) {
37
+		$this->iPage = $i;
38
+	}
39
+	public function getPage() {
40
+		return $this->iPage;
41
+	}
42
+
43
+	public function setHost($s) {
44
+		$this->sHost = $s;
45
+	}
46
+	public function getHost() {
47
+		return $this->sHost;
48
+	}
49
+	public function isHost() {
50
+		return null != $this->sHost;
51
+	}
52
+
53
+	public function setLevel($s) {
54
+		$this->sLevel = $s;
55
+	}
56
+	public function getLevel() {
57
+		return $this->sLevel;
58
+	}
59
+	public function isLevel() {
60
+		return null != $this->sLevel;
61
+	}
62
+
63
+	public function setRange($i) {
64
+		$this->iRange = $i;
65
+	}
66
+	public function getRange() {
67
+		return $this->iRange;
68
+	}
69
+
70
+} // class

+ 269
- 0
index.php View File

@@ -0,0 +1,269 @@
1
+<?php
2
+
3
+
4
+require_once 'inc/lggrstate_class.php';
5
+require_once 'inc/lggr_class.php';
6
+require 'tpl/head.inc.php';
7
+
8
+session_start();
9
+
10
+if(isset($_SESSION[LggrState::SESSIONNAME])) {
11
+	$state = $_SESSION[LggrState::SESSIONNAME];
12
+} else {
13
+	$state = new LggrState();
14
+} // if
15
+
16
+$l = null;
17
+try {
18
+	$l = new Lggr($state);
19
+
20
+	$aLevels = $l->getLevels();
21
+	$aServers = $l->getServers();
22
+} catch(Exception $e) {
23
+	echo '<div class="container"><div class="alert alert-danger" role="alert">' . $e->getMessage() . '</div></div>';
24
+
25
+	require 'tpl/foot.inc.php';
26
+
27
+	exit;
28
+}
29
+
30
+$aRanges = array(
31
+	'1' => 'This hour',
32
+	'24' => 'Today',
33
+	'168' => 'Week'
34
+);
35
+
36
+$page = $state->getPage();
37
+
38
+try {
39
+	if($state->isSearch()) {
40
+
41
+		$aEvents = $l->getText($state->getSearch(), $page*100, 100);
42
+		$searchvalue = htmlentities($state->getSearch());
43
+		$isSearch=true;
44
+		$sFilter = 'Full text search result <strong>' . $searchvalue . '</strong>';
45
+
46
+	} elseif($state->isHost() || $state->isLevel()) {
47
+
48
+		$host = $state->getHost();
49
+		$level = $state->getLevel();
50
+
51
+		$aEvents = $l->getFiltered($host, $level, $page*100, 100);
52
+		$searchvalue='';
53
+		$isSearch=false;
54
+		$sFilter='';
55
+		if($state->isHost())
56
+			$sFilter .= 'Filter by server <strong>' . htmlentities($state->getHost()) . '</strong>';
57
+		if($state->isLevel())
58
+			$sFilter .= 'Filter by level <strong>' . htmlentities($state->getLevel()) . '</strong>';
59
+
60
+	} else {
61
+
62
+		$sFilter = null;
63
+
64
+		$aEvents = $l->getLatest($page*100, 100);
65
+		$searchvalue='';
66
+		$isSearch=false;
67
+
68
+	} // if search
69
+} catch(Exception $e) {
70
+	echo '<div class="container"><div class="alert alert-danger" role="alert">' . $e->getMessage() . '</div></div>';
71
+
72
+	require 'tpl/foot.inc.php';
73
+
74
+	exit;
75
+}
76
+?>
77
+
78
+
79
+    <nav class="navbar navbar-inverse navbar-fixed-top">
80
+      <div class="container">
81
+        <div class="navbar-header">
82
+          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
83
+            <span class="sr-only">Toggle navigation</span>
84
+            <span class="icon-bar"></span>
85
+            <span class="icon-bar"></span>
86
+            <span class="icon-bar"></span>
87
+          </button>
88
+          <a class="navbar-brand" href="./do.php?a=reset"><img src="/img/logo.png" alt="Lggr.io" /></a>
89
+        </div>
90
+        <div style="height: 1px;" aria-expanded="false" id="navbar" class="navbar-collapse collapse">
91
+          <form method="post" action="./do.php?a=search" class="navbar-form navbar-right">
92
+            <div class="form-group">
93
+              <input name="q" placeholder="Search in messages" class="form-control" type="text" value="<?= $searchvalue ?>">
94
+            </div>
95
+            <button type="submit" class="btn btn-success">Search</button>
96
+          </form>
97
+        </div><!--/.navbar-collapse -->
98
+      </div>
99
+    </nav>
100
+
101
+    <div class="container">
102
+      <div class="row">
103
+        <div class="col-md-4">
104
+          <h2><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span> Levels</h2>
105
+          <div class="progress">
106
+<?php
107
+$aLevelCount = array();
108
+foreach($aLevels as $level) {
109
+	$aLevelCount[$level->level] = $level->c;
110
+	switch($level->level) {
111
+	case 'err':
112
+		$label='progress-bar-danger';
113
+		break;
114
+	case 'notice':
115
+		$label='progress-bar-warning';
116
+		break;
117
+	case 'info':
118
+		$label='progress-bar-success';
119
+		break;
120
+	default: $label='';
121
+	} // switch
122
+
123
+	echo <<<EOL
124
+<div class="progress-bar $label" style="width: {$level->f}%" title="{$level->level} {$level->f}%">
125
+<span class="sr-only">{$level->f}%</span>
126
+</div>
127
+EOL;
128
+} // foreach
129
+?>
130
+</div>
131
+          <p>Distribution of selected event levels.</p>
132
+<?php
133
+if(isset($aLevelCount['err'])) {
134
+	echo '<button class="btn btn-primary" type="button">Error <span class="badge">' . $aLevelCount['err'] . '</span></button>';
135
+}
136
+?>
137
+<?php
138
+if(isset($aLevelCount['notice'])) {
139
+	echo '<button class="btn btn-primary" type="button">Notice <span class="badge">' . $aLevelCount['notice'] . '</span></button>';
140
+}
141
+?>
142
+        </div>
143
+
144
+        <div class="col-md-4">
145
+          <h2><span class="glyphicon glyphicon-align-left" aria-hidden="true"></span> Servers</h2>
146
+<?php
147
+foreach($aServers as $server) {
148
+	if($server->f < 5) continue;
149
+
150
+        echo <<<EOL
151
+<div class="progress">
152
+	<div class="progress-bar" role="progressbar" aria-valuenow="{$server->f}" aria-valuemin="0" aria-valuemax="100" style="width: {$server->f}%; min-width: 3em" title="{$server->host} {$server->f}%">
153
+{$server->host} {$server->f}%
154
+	</div>
155
+</div>
156
+EOL;
157
+} // foreach
158
+?>
159
+          <p>Most reporting servers (5% or more).</p>
160
+        </div>
161
+
162
+        <div class="col-md-4">
163
+          <h2><span class="glyphicon glyphicon-filter" aria-hidden="true"></span> Filter</h2>
164
+<div class="dropdown">
165
+  <button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-expanded="true">
166
+    Server
167
+    <span class="caret"></span>
168
+  </button>
169
+  <ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
170
+<?php
171
+foreach($aServers as $server) {
172
+	echo '<li role="presentation"><a role="menuitem" tabindex="-1" href="./do.php?a=host&host=' . urlencode($server->host) . '">' . $server->host . '</a></li>';
173
+} // foreach
174
+?>
175
+  </ul>
176
+</div><!-- dropdown -->
177
+
178
+<p><div class="btn-group" role="group" aria-label="level">
179
+<?php
180
+foreach($aLevels as $level) {
181
+	if($state->isLevel() && ($level->level == $state->getLevel())) {
182
+		echo '<button type="button" class="btn btn-primary newlog-level">' . $level->level . '</button>';
183
+	} else {
184
+		echo '<button type="button" class="btn btn-default newlog-level">' . $level->level . '</button>';
185
+	}
186
+} // foreach
187
+?>
188
+</div></p>
189
+
190
+<p><div class="btn-group" role="group" aria-label="range">
191
+<?php
192
+foreach($aRanges as $rangeValue => $rangeText) {
193
+	if($state->getRange() == $rangeValue) {
194
+		echo '<button type="button" class="btn btn-primary newlog-range" data-range="' . $rangeValue . '">' . $rangeText . '</button>';
195
+	} else {
196
+		echo '<button type="button" class="btn btn-default newlog-range" data-range="' . $rangeValue . '">' . $rangeText . '</button>';
197
+	}
198
+} // foreach
199
+?>
200
+</div></p>
201
+<p><a type="button" role="button" href="./do.php?a=reset" class="btn btn-default">
202
+  <span class="glyphicon glyphicon-refresh" aria-hidden="true"></span> Reset
203
+</a></p>
204
+        </div>
205
+      </div>
206
+    </div> <!-- /container -->
207
+
208
+<div class="container">
209
+<?php
210
+
211
+if(null != $sFilter) {
212
+	echo '<div class="alert alert-info" role="alert">' . $sFilter . '</div>';
213
+} // if
214
+
215
+if(0 == count($aEvents)) {
216
+	echo '<div class="alert alert-danger" role="alert">empty result</div>';
217
+} // if
218
+
219
+?>
220
+</div>
221
+
222
+<div class="container datablock">
223
+<?php
224
+
225
+include 'tpl/paginate.inc.php';
226
+
227
+$i=0;
228
+foreach($aEvents as $event) {
229
+	$i++;
230
+
231
+	if(0 == $i % 2) {
232
+		$rowclass='even';
233
+	} else {
234
+		$rowclass='odd';
235
+	} // if
236
+
237
+	switch($event->level) {
238
+	case 'err': $label = '<span class="label label-danger">Error</span>'; break;
239
+	case 'notice': $label='<span class="label label-warning">Notice</span>'; break;
240
+	case 'info': $label = '<span class="label label-info">Info</span>'; break;
241
+	default: $label = '<span class="label label-default">' . $event->level . '</span>';
242
+	} // switch
243
+
244
+	$host = htmlentities($event->host);
245
+	$program = htmlentities($event->program);
246
+	$msg = htmlentities($event->message);
247
+
248
+	echo <<<EOL
249
+<div class="row datarow $rowclass" data-id="{$event->id}">
250
+	<div class="col-md-2 col-xs-6 newlog-date">{$event->date}</div>
251
+	<div class="col-md-1 col-xs-2">{$event->facility}</div>
252
+	<div class="col-md-1 col-xs-2">$label</div>
253
+	<div class="col-md-1 col-xs-2">$host</div>
254
+	<div class="col-md-2 col-xs-12">$program</div>
255
+	<div class="col-md-5 col-xs-12 newlog-msg" title="$msg"><tt>{$msg}</tt></div>
256
+</div><!-- row -->
257
+EOL;
258
+
259
+} // foreach
260
+?>
261
+<div id="dialog" title="Details">I'm a dialog</div>
262
+
263
+<?php
264
+include 'tpl/paginate.inc.php';
265
+?>
266
+
267
+</div>
268
+
269
+<?php require 'tpl/foot.inc.php' ?>

+ 0
- 0
js/index.html View File


+ 30
- 0
js/lggr.js View File

@@ -0,0 +1,30 @@
1
+/* */
2
+
3
+$(document).ready(function() {
4
+
5
+$("#dialog").dialog({
6
+	autoOpen: false,
7
+	width: 500
8
+});
9
+
10
+$('div.datarow tt').on('click', function() {
11
+	var sTxt = $(this).html();
12
+	var sTitle = $(this).parent().parent().find('.newlog-date').text();
13
+
14
+	$('#dialog').html(sTxt).
15
+		dialog("option", "title", sTitle).
16
+		dialog("open");
17
+});
18
+
19
+$('button.newlog-level').on('click', function() {
20
+	var sLevel = $(this).text();
21
+	window.location.href = "./do.php?a=level&level=" + sLevel;
22
+});
23
+
24
+$('button.newlog-range').on('click', function() {
25
+	var iRange = $(this).attr('data-range');
26
+	window.location.href = "./do.php?a=range&range=" + iRange;
27
+});
28
+
29
+
30
+});

+ 1
- 0
tpl/.htaccess View File

@@ -0,0 +1 @@
1
+deny from all

+ 16
- 0
tpl/foot.inc.php View File

@@ -0,0 +1,16 @@
1
+    <div class="container">
2
+      <hr>
3
+      <footer>
4
+        <p class="debugfooter">Session: <?= $_COOKIE['PHPSESSID'] ?> by <?= htmlentities($_SERVER['REMOTE_USER']) ?></p>
5
+        <p>&copy; <a href="http://lggr.io" target="_blank">lggr.io</a> 2015</p>
6
+      </footer>
7
+    </div> <!-- /container -->
8
+
9
+    <!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
10
+    <script src="//code.jquery.com/jquery-1.11.3.min.js"></script>
11
+    <script src="//code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
12
+    <!-- Include all compiled plugins (below), or include individual files as needed -->
13
+    <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
14
+    <script src="js/lggr.js"></script>
15
+  </body>
16
+</html>

+ 20
- 0
tpl/head.inc.php View File

@@ -0,0 +1,20 @@
1
+<!DOCTYPE html>
2
+<html lang="en">
3
+  <head>
4
+    <meta charset="utf-8">
5
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+    <meta name="viewport" content="width=device-width, initial-scale=1">
7
+    <!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
8
+    <title>Lggr.io</title>
9
+    <!-- Bootstrap -->
10
+    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" rel="stylesheet">
11
+    <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
12
+    <link href="css/lggr.css" rel="stylesheet">
13
+    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
14
+    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
15
+    <!--[if lt IE 9]>
16
+      <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
17
+      <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
18
+    <![endif]-->
19
+  </head>
20
+  <body>

+ 21
- 0
tpl/paginate.inc.php View File

@@ -0,0 +1,21 @@
1
+<nav>
2
+  <ul class="pagination">
3
+<?php
4
+if($page>0) {
5
+        echo '<li><a href="./do.php?a=paginate&page=' . ($page-1) . '" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>';
6
+} else {
7
+        echo '<li class="disabled"><a href="#" aria-label="Previous"><span aria-hidden="true">&laquo;</span></a></li>';
8
+} // if
9
+
10
+for($i=0; $i<9; $i++) {
11
+        if($page == $i) {
12
+                echo '<li class="active"><a href="./do.php?a=paginate&page=' . $i . '">' . ($i+1) . '</a></li>';
13
+        } else {
14
+                echo '<li><a href="./do.php?a=paginate&page=' . $i . '">' . ($i+1) . '</a></li>';
15
+        } // if
16
+} // for i
17
+
18
+echo '<li><a href="./do.php?a=paginate&page=' . ($page+1) . '" aria-label="Next"><span aria-hidden="true">&raquo;</span></a></li>';
19
+?>
20
+  </ul>
21
+</nav>

Loading…
Cancel
Save
Social stuff:
Mastodon