The web based syslog https://lggr.io
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.php 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. <?php
  2. require 'inc/pre.inc.php';
  3. define('TITLE', 'overview');
  4. require 'tpl/head.inc.php';
  5. define('INC_FOOTER', 'tpl/foot.inc.php');
  6. define('TAG_STRONG_OPEN', '<strong>');
  7. define('TAG_STRONG_CLOSE', '</strong>');
  8. define('TAG_BUTTON_CLOSE', '</button>');
  9. define('TAG_SPANBUTTON_CLOSE', '</span></button>');
  10. $l = null;
  11. try {
  12. $l = new Lggr($state, $config);
  13. $aLevels = $l->getLevels();
  14. $aServers = $l->getServers();
  15. $aAllServers = $l->getAllServers();
  16. }
  17. catch (LggrException $e) {
  18. echo '<div class="container"><div class="alert alert-danger" role="alert">' . $e->getMessage() . '</div></div>';
  19. require INC_FOOTER;
  20. exit();
  21. }
  22. $aRanges = array(
  23. '1' => _('This hour'),
  24. '24' => _('Today'),
  25. '168' => _('Week'),
  26. '8760' => _('Year')
  27. );
  28. $page = $state->getPage();
  29. try {
  30. if ($state->isSearch()) {
  31. $aEvents = $l->getText($state->getSearch(), $state->getSearchProg(),
  32. $page * LggrState::PAGELEN, LggrState::PAGELEN);
  33. $searchvalue = htmlentities($state->getSearch(),
  34. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES);
  35. $searchvalueprog = htmlentities($state->getSearchProg(),
  36. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES);
  37. $isSearch = true;
  38. $sFilter = _('Text search for');
  39. if ('' != $state->getSearch()) {
  40. $sFilter .= ' message ' . TAG_STRONG_OPEN . $searchvalue . TAG_STRONG_CLOSE;
  41. }
  42. if ('' != $state->getSearchProg()) {
  43. $sFilter .= ' program ' . TAG_STRONG_OPEN . $searchvalueprog . TAG_STRONG_CLOSE;
  44. }
  45. } elseif ($state->isFromTo() && $state->isHost()) {
  46. $host = $state->getHostName();
  47. $aEvents = $l->getHostFromTo($page * LggrState::PAGELEN,
  48. LggrState::PAGELEN);
  49. $sFilter = _('Filter by time range between') . ' ' . TAG_STRONG_CLOSE .
  50. htmlentities($state->getFrom(),
  51. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES) . TAG_STRONG_CLOSE . ' ' .
  52. _('and') . ' ' . TAG_STRONG_OPEN .
  53. htmlentities($state->getTo(),
  54. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES) . TAG_STRONG_CLOSE . ', ';
  55. $sFilter .= _('Filter by server') . ' ' . TAG_STRONG_OPEN .
  56. htmlentities($state->getHostName(),
  57. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES) . TAG_STRONG_CLOSE;
  58. $searchvalue = '';
  59. $searchvalueprog = '';
  60. $isSearch = false;
  61. } elseif ($state->isHost() || $state->isLevel()) {
  62. $host = $state->getHostName();
  63. $level = $state->getLevel();
  64. $aEvents = $l->getFiltered($host, $level, $page * LggrState::PAGELEN,
  65. LggrState::PAGELEN);
  66. $searchvalue = '';
  67. $searchvalueprog = '';
  68. $isSearch = false;
  69. $sFilter = '';
  70. if ($state->isHost()) {
  71. $sFilter .= _('Filter by server') . ' ' . TAG_STRONG_OPEN .
  72. htmlentities($state->getHostName(),
  73. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES) . TAG_STRONG_CLOSE;
  74. }
  75. if ($state->isLevel()) {
  76. $sFilter .= _('Filter by level') . ' ' . TAG_STRONG_OPEN .
  77. htmlentities($state->getLevel(),
  78. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES) . TAG_STRONG_CLOSE;
  79. }
  80. } elseif ($state->isFromTo()) {
  81. $aEvents = $l->getFromTo($page * LggrState::PAGELEN, LggrState::PAGELEN);
  82. $sFilter = _('Filter by time range between') . ' ' . TAG_STRONG_OPEN .
  83. htmlentities($state->getFrom(),
  84. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES) . TAG_STRONG_CLOSE . ' ' .
  85. _('and') . ' ' . TAG_STRONG_OPEN .
  86. htmlentities($state->getTo(),
  87. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES) . TAG_STRONG_CLOSE;
  88. $searchvalue = '';
  89. $searchvalueprog = '';
  90. $isSearch = false;
  91. } else {
  92. $sFilter = null;
  93. $aEvents = $l->getLatest($page * LggrState::PAGELEN, LggrState::PAGELEN);
  94. $searchvalue = '';
  95. $searchvalueprog = '';
  96. $isSearch = false;
  97. } // if search
  98. }
  99. catch (LggrException $e) {
  100. echo '<div class="container"><div class="alert alert-danger" role="alert">' . $e->getMessage() . '</div></div>';
  101. require INC_FOOTER;
  102. exit();
  103. }
  104. if (version_compare(phpversion(), '5.4', '<')) {
  105. echo '<div class="container"><div class="alert alert-danger" role="alert">Your PHP version ' .
  106. phpversion() . ' might be too old, expecting at least 5.4</div></div>';
  107. } // if
  108. require 'tpl/nav.inc.php';
  109. ?>
  110. <div class="container" id="infoheader">
  111. <div id="accordion" class="panel-group">
  112. <div class="panel panel-default">
  113. <div class="panel-heading">
  114. <h4 class="panel-title">
  115. <span class="glyphicon glyphicon-circle-arrow-down"
  116. aria-hidden="true"></span><a
  117. data-toggle="collapse" data-parent="#accordion"
  118. href="#collapseOne"><?= _('Server status and filter') ?> ...</a>
  119. </h4>
  120. </div>
  121. <div id="collapseOne"
  122. class="panel-collapse collapse <?= $state->isPanelOpen()?'in':'' ?>">
  123. <div class="panel-body">
  124. <div class="row">
  125. <div class="col-md-4 lggr-col-level">
  126. <h2
  127. title="Levels of last up to <?= Lggr::LASTSTAT ?> entries">
  128. <span class="glyphicon glyphicon-tasks"
  129. aria-hidden="true"></span> <?= _('Levels') ?></h2>
  130. <div class="progress">
  131. <?php
  132. $aLevelCount = array();
  133. foreach ($aLevels as $level) {
  134. $aLevelCount[$level->level] = $level->c;
  135. $level->f = round($level->f);
  136. switch ($level->level) {
  137. case MessageLevel::EMERG:
  138. case MessageLevel::CRIT:
  139. case MessageLevel::ERR:
  140. $label = 'progress-bar-danger';
  141. break;
  142. case MessageLevel::WARNING:
  143. $label = 'progress-bar-warning';
  144. break;
  145. case MessageLevel::NOTICE:
  146. $label = 'progress-bar-primary';
  147. break;
  148. case MessageLevel::INFO:
  149. $label = 'progress-bar-success';
  150. break;
  151. default:
  152. $label = '';
  153. } // switch
  154. echo <<<EOL
  155. <div class="progress-bar $label" role="progressbar" aria-valuenow="{$level->f}" style="width: {$level->f}%" title="{$level->level} {$level->f}%">
  156. <span class="sr-only">{$level->f}%</span>
  157. </div>
  158. EOL;
  159. } // foreach
  160. ?>
  161. </div>
  162. <p><?= _('Distribution of selected event levels.') ?></p>
  163. <p class="lggr-level-buttons">
  164. <?php
  165. if (isset($aLevelCount[MessageLevel::EMERG])) {
  166. echo '<button class="btn btn-sm btn-danger" type="button">Emergency <span class="badge">' .
  167. $aLevelCount[MessageLevel::EMERG] . TAG_SPANBUTTON_CLOSE . ' ';
  168. }
  169. if (isset($aLevelCount[MessageLevel::CRIT])) {
  170. echo '<button class="btn btn-sm btn-danger" type="button">Critical <span class="badge">' .
  171. $aLevelCount[MessageLevel::CRIT] . TAG_SPANBUTTON_CLOSE . ' ';
  172. }
  173. if (isset($aLevelCount[MessageLevel::ERR])) {
  174. echo '<button class="btn btn-sm btn-danger" type="button">Error <span class="badge">' .
  175. $aLevelCount[MessageLevel::ERR] . TAG_SPANBUTTON_CLOSE . ' ';
  176. }
  177. if (isset($aLevelCount[MessageLevel::WARNING])) {
  178. echo '<button class="btn btn-sm btn-warning" type="button">Warning <span class="badge">' .
  179. $aLevelCount[MessageLevel::WARNING] . TAG_SPANBUTTON_CLOSE . ' ';
  180. }
  181. if (isset($aLevelCount[MessageLevel::NOTICE])) {
  182. echo '<button class="btn btn-sm btn-primary" type="button">Notice <span class="badge">' .
  183. $aLevelCount[MessageLevel::NOTICE] . TAG_SPANBUTTON_CLOSE . ' ';
  184. }
  185. ?>
  186. </p>
  187. </div>
  188. <div class="col-md-4 lggr-col-server">
  189. <h2
  190. title="Reporting servers of last up to <?= Lggr::LASTSTAT ?> entries">
  191. <span
  192. class="glyphicon glyphicon-align-left"
  193. aria-hidden="true"></span> <?= _('Servers') ?></h2>
  194. <?php
  195. foreach ($aServers as $server) {
  196. if ($server->f < 5) {
  197. continue;
  198. }
  199. $server->f = round($server->f);
  200. echo <<<EOL
  201. <div class="progress">
  202. <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}%">
  203. {$server->host} {$server->f}%
  204. </div>
  205. </div>
  206. EOL;
  207. } // foreach
  208. ?>
  209. <p><?= _('Most reporting servers (5% or more).') ?></p>
  210. </div>
  211. <div class="col-md-4 lggr-col-filter">
  212. <h2>
  213. <span class="glyphicon glyphicon-filter"
  214. aria-hidden="true"></span> Filter
  215. </h2>
  216. <div class="dropdown lggr-formelement">
  217. <button
  218. class="btn btn-default dropdown-toggle"
  219. type="button" id="dropdownMenu1"
  220. data-toggle="dropdown"
  221. aria-expanded="true">
  222. Server <span class="caret"></span>
  223. </button>
  224. <ul class="dropdown-menu" role="menu"
  225. aria-labelledby="dropdownMenu1">
  226. <?php
  227. $aServerList = array();
  228. foreach ($aAllServers as $server) {
  229. $aServerList[$server->host] = $server->id;
  230. } // foreach
  231. ksort($aServerList);
  232. foreach ($aServerList as $servername => $serverid) {
  233. echo '<li role="presentation"><a role="menuitem" tabindex="-1" href="./do.php?a=host&hostid=' .
  234. $serverid . '">' . $servername . '</a></li>';
  235. } // foreach
  236. ?>
  237. </ul>
  238. </div>
  239. <!-- dropdown -->
  240. <div
  241. class="btn-group btn-group-xs lggr-formelement"
  242. role="group" aria-label="level">
  243. <?php
  244. foreach ($aLevels as $level) {
  245. if ($state->isLevel() && ($level->level == $state->getLevel())) {
  246. echo '<button type="button" class="btn btn-primary newlog-level">' .
  247. $level->level . TAG_BUTTON_CLOSE;
  248. } else {
  249. echo '<button type="button" class="btn btn-default newlog-level">' .
  250. $level->level . TAG_BUTTON_CLOSE;
  251. }
  252. } // foreach
  253. ?>
  254. </div>
  255. <div class="btn-group lggr-formelement"
  256. role="group" aria-label="range">
  257. <?php
  258. foreach ($aRanges as $rangeValue => $rangeText) {
  259. if ($state->getRange() == $rangeValue) {
  260. echo '<button type="button" class="btn btn-primary newlog-range" data-range="' .
  261. $rangeValue . '">' . $rangeText . TAG_BUTTON_CLOSE;
  262. } else {
  263. echo '<button type="button" class="btn btn-default newlog-range" data-range="' .
  264. $rangeValue . '">' . $rangeText . TAG_BUTTON_CLOSE;
  265. }
  266. } // foreach
  267. if ($state->isFromTo()) {
  268. echo '<button type="button" class="btn btn-primary newlog-range" id="btnspecialrange">' .
  269. _('Special') . TAG_BUTTON_CLOSE;
  270. } else {
  271. echo '<button type="button" class="btn btn-default newlog-range" id="btnspecialrange">' .
  272. _('Special') . TAG_BUTTON_CLOSE;
  273. } // if
  274. ?>
  275. </div>
  276. <form action="./do.php" method="post"
  277. id="tsfromto">
  278. <input type="hidden" name="a"
  279. value="fromto"> <input type="text"
  280. name="tsfrom" id="tsfrom"
  281. class="tspick" placeholder="from"> <input
  282. type="text" name="tsto" id="tsto"
  283. class="tspick" placeholder="to">
  284. <button type="submit"
  285. class="btn btn-default">filter</button>
  286. </form>
  287. <p>
  288. <a type="button" role="button"
  289. href="./do.php?a=reset"
  290. class="btn btn-default"> <span
  291. class="glyphicon glyphicon-refresh"
  292. aria-hidden="true"></span> <?= _('Reset') ?></a>
  293. </p>
  294. </div>
  295. </div>
  296. <!-- row -->
  297. </div>
  298. <!-- panel-body -->
  299. </div>
  300. <!-- collapseOne -->
  301. </div>
  302. <!-- panel -->
  303. </div>
  304. <!-- panel-group -->
  305. </div>
  306. <!-- /container -->
  307. <div class="container">
  308. <?php
  309. if (null != $sFilter) {
  310. echo '<div class="alert alert-info" role="alert">' . $sFilter . '</div>';
  311. } // if
  312. if (0 == count($aEvents)) {
  313. echo '<div class="alert alert-danger" role="alert">' . _('empty result') .
  314. '</div>';
  315. } // if
  316. ?>
  317. </div>
  318. <!-- class container for fixed max width, or container-fluid for maximum width -->
  319. <div class="container-fluid datablock">
  320. <?php
  321. if (! $isSearch && (0 < count($aEvents))) {
  322. include 'tpl/paginate.inc.php';
  323. }
  324. if (0 < count($aEvents)) {
  325. include 'tpl/containerhead.inc.php';
  326. }
  327. $i = 0;
  328. foreach ($aEvents as $event) {
  329. $i ++;
  330. if (0 == $i % 2) {
  331. $rowclass = 'even';
  332. } else {
  333. $rowclass = 'odd';
  334. } // if
  335. switch ($event->level) {
  336. case 'emerg':
  337. $label = '<span class="label label-danger">Emergency</span>';
  338. break;
  339. case 'crit':
  340. $label = '<span class="label label-danger">Critical</span>';
  341. break;
  342. case 'err':
  343. $label = '<span class="label label-danger">Error</span>';
  344. break;
  345. case 'warning':
  346. $label = '<span class="label label-warning">Warning</span>';
  347. break;
  348. case 'notice':
  349. $label = '<span class="label label-primary">Notice</span>';
  350. break;
  351. case 'info':
  352. $label = '<span class="label label-success">Info</span>';
  353. break;
  354. default:
  355. $label = '<span class="label label-default">' . $event->level .
  356. '</span>';
  357. } // switch
  358. switch ($event->archived) {
  359. case 'Y':
  360. $archived = '<span id="arch' . $event->id .
  361. '" class="lggr-archived glyphicon glyphicon-warning-sign" aria-hidden="true" title="archived"></span>';
  362. break;
  363. case 'N':
  364. $archived = '<span id="arch' . $event->id .
  365. '" class="lggr-notarchived glyphicon glyphicon-pushpin" aria-hidden="true" title=""></span>';
  366. break;
  367. default:
  368. $archived = '?';
  369. } // switch
  370. $host = htmlentities($event->host, ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES);
  371. $program = htmlentities($event->program,
  372. ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES);
  373. $msg = htmlentities($event->message, ENT_HTML5 | ENT_SUBSTITUTE | ENT_QUOTES);
  374. echo <<<EOL
  375. <div class="row datarow $rowclass" data-id="{$event->id}">
  376. <div class="col-md-2 col-xs-6 newlog-date">{$event->date}</div>
  377. <div class="col-md-1 col-xs-2">{$event->facility}</div>
  378. <div class="col-md-1 col-xs-2">$archived $label</div>
  379. <div class="col-md-1 col-xs-2">$host</div>
  380. <div class="col-md-2 col-xs-12">$program</div>
  381. <div class="col-md-5 col-xs-12 newlog-msg" title="$msg"><tt>{$msg}</tt></div>
  382. </div><!-- row -->
  383. EOL;
  384. } // foreach
  385. if (0 < count($aEvents)) {
  386. include 'tpl/containerhead.inc.php';
  387. }
  388. ?>
  389. <div id="dialog" title="Details">I'm a dialog</div>
  390. <?php
  391. if (! $isSearch && (0 < count($aEvents))) {
  392. include 'tpl/paginate.inc.php';
  393. }
  394. ?>
  395. </div>
  396. <?php
  397. $aPerf = $l->getPerf();
  398. require INC_FOOTER;
  399. ?>
Social stuff:
Mastodon