mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
17
doc/Extensions/Graylog.md
Normal file
17
doc/Extensions/Graylog.md
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
# Graylog integration
|
||||||
|
|
||||||
|
We have simple integration for Graylog, you will be able to view any logs from within LibreNMS that have been parsed by the syslog input from within
|
||||||
|
Graylog itself. This includes logs from devices which aren't in LibreNMS still, you can also see logs for a sepcific device under the logs section
|
||||||
|
for the device.
|
||||||
|
|
||||||
|
Graylog itself isn't included within LibreNMS, you will need to install this separately either on the same infrastructure as LibreNMS or as a totally
|
||||||
|
standalone appliance.
|
||||||
|
|
||||||
|
Config is simple, here's an example:
|
||||||
|
|
||||||
|
```php
|
||||||
|
$config['graylog']['server'] = 'http://127.0.0.1';
|
||||||
|
$config['graylog']['port'] = 12900;
|
||||||
|
$config['graylog']['username'] = 'admin';
|
||||||
|
$config['graylog']['password'] = 'admin';
|
||||||
|
```
|
@@ -33,6 +33,8 @@ if ($type == 'placeholder') {
|
|||||||
}
|
}
|
||||||
elseif (is_file('includes/common/'.$type.'.inc.php')) {
|
elseif (is_file('includes/common/'.$type.'.inc.php')) {
|
||||||
|
|
||||||
|
$results_limit = 10;
|
||||||
|
$no_form = true;
|
||||||
include 'includes/common/'.$type.'.inc.php';
|
include 'includes/common/'.$type.'.inc.php';
|
||||||
$output = implode('', $common_output);
|
$output = implode('', $common_output);
|
||||||
$status = 'ok';
|
$status = 'ok';
|
||||||
|
125
html/includes/common/graylog.inc.php
Normal file
125
html/includes/common/graylog.inc.php
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LibreNMS
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version. Please see LICENSE.txt at the top level of
|
||||||
|
* the source code distribution for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (empty($results_limit)) {
|
||||||
|
$results_limit = 25;
|
||||||
|
}
|
||||||
|
$tmp_output = '<h3>Graylog</h3>
|
||||||
|
|
||||||
|
<div class="table-responsive">
|
||||||
|
<table id="graylog" class="table table-hover table-condensed graylog">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th data-column-id="timestamp">Timestamp</th>
|
||||||
|
<th data-column-id="source">Source</th>
|
||||||
|
<th data-column-id="message">Message</th>
|
||||||
|
<th data-column-id="facility" data-visible="false">Facility</th>
|
||||||
|
<th data-column-id="level" data-visible="false">Level</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
searchbar = "<div id=\"{{ctx.id}}\" class=\"{{css.header}}\"><div class=\"row\">"+
|
||||||
|
"<div class=\"col-sm-8\"><form method=\"post\" action=\"\" class=\"form-inline\">"+
|
||||||
|
"Filter: "+
|
||||||
|
';
|
||||||
|
|
||||||
|
if (!empty($filter_device)) {
|
||||||
|
$tmp_output .= '
|
||||||
|
"<input type=\"hidden\" name=\"hostname\" id=\"hostname\" value=\"'. $filter_device .'\">"+
|
||||||
|
';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$tmp_output .= '
|
||||||
|
"<div class=\"form-group\"><select name=\"hostname\" id=\"hostname\" class=\"form-control input-sm\">"+
|
||||||
|
"<option value=\"\">All devices</option>"+
|
||||||
|
';
|
||||||
|
|
||||||
|
if (is_admin() === true || is_read() === true) {
|
||||||
|
$results = dbFetchRows("SELECT `hostname` FROM `devices` GROUP BY `hostname` ORDER BY `hostname`");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$results = dbFetchRows("SELECT `D`.`hostname` FROM `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` GROUP BY `hostname` ORDER BY `hostname`", array($_SESSION['user_id']));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($results as $data) {
|
||||||
|
$tmp_output .= '"<option value=\"'.$data['hostname'].'\""+';
|
||||||
|
if ($data['hostname'] == $vars['hostname']) {
|
||||||
|
$tmp_output .= '"selected"+';
|
||||||
|
}
|
||||||
|
$tmp_output .= '">'.$data['hostname'].'</option>"+';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmp_output .= '
|
||||||
|
"</select> </div>"+
|
||||||
|
';
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($filter_device)) {
|
||||||
|
$filter_device = mres($_POST['hostname']);
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmp_output .= '
|
||||||
|
"<div class=\"form-group\"><select name=\"range\" class=\"form-group input-sm\">"+
|
||||||
|
"<option value=\"300\">Search last 5 minutes</option>"+
|
||||||
|
"<option value=\"900\">Search last 15 minutes</option>"+
|
||||||
|
"<option value=\"1800\">Search last 30 minutes</option>"+
|
||||||
|
"<option value=\"3600\">Search last 1 hour</option>"+
|
||||||
|
"<option value=\"7200\">Search last 2 hours</option>"+
|
||||||
|
"<option value=\"28800\">Search last 8 hours</option>"+
|
||||||
|
"<option value=\"86400\">Search last 1 day</option>"+
|
||||||
|
"<option value=\"172800\">Search last 2 days</option>"+
|
||||||
|
"<option value=\"432000\">Search last 5 days</option>"+
|
||||||
|
"<option value=\"604800\">Search last 7 days</option>"+
|
||||||
|
"<option value=\"1209600\">Search last 14 days</option>"+
|
||||||
|
"<option value=\"2592000\">Search last 30 days</option>"+
|
||||||
|
"<option value=\"0\">Search all time</option>"+
|
||||||
|
"</select> </div>"+
|
||||||
|
"<button type=\"submit\" class=\"btn btn-success btn-sm\">Filter</button> "+
|
||||||
|
"</form></div>"+
|
||||||
|
"<div class=\"col-sm-4 actionBar\"><p class=\"{{css.search}}\"></p><p class=\"{{css.actions}}\"></p></div></div></div>"
|
||||||
|
|
||||||
|
var graylog_grid = $("#graylog").bootgrid({
|
||||||
|
ajax: true,
|
||||||
|
rowCount: ['. $results_limit .', 25,50,100,250,-1],
|
||||||
|
';
|
||||||
|
|
||||||
|
if ($no_form !== true) {
|
||||||
|
$tmp_output .= '
|
||||||
|
templates: {
|
||||||
|
header: searchbar
|
||||||
|
},
|
||||||
|
';
|
||||||
|
}
|
||||||
|
|
||||||
|
$tmp_output .= '
|
||||||
|
post: function ()
|
||||||
|
{
|
||||||
|
return {
|
||||||
|
id: "graylog",
|
||||||
|
hostname: "' . $filter_device . '",
|
||||||
|
range: "' . mres($_POST['range']) . '"
|
||||||
|
};
|
||||||
|
},
|
||||||
|
url: "/ajax_table.php",
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
';
|
||||||
|
|
||||||
|
$common_output[] = $tmp_output;
|
@@ -77,9 +77,17 @@ if ($_SESSION['userlevel'] >= '10') {
|
|||||||
</li>
|
</li>
|
||||||
<li role="presentation" class="divider"></li>
|
<li role="presentation" class="divider"></li>
|
||||||
<li><a href="<?php echo(generate_url(array('page'=>'eventlog'))); ?>"><i class="fa fa-book fa-fw fa-lg"></i> Eventlog</a></li>
|
<li><a href="<?php echo(generate_url(array('page'=>'eventlog'))); ?>"><i class="fa fa-book fa-fw fa-lg"></i> Eventlog</a></li>
|
||||||
<?php if (isset($config['enable_syslog']) && $config['enable_syslog']) {
|
<?php
|
||||||
echo(' <li><a href="'.generate_url(array('page'=>'syslog')).'"><i class="fa fa-book fa-fw fa-lg"></i> Syslog</a></li>');
|
|
||||||
} ?>
|
if (isset($config['enable_syslog']) && $config['enable_syslog']) {
|
||||||
|
echo ' <li><a href="'.generate_url(array('page'=>'syslog')).'"><i class="fa fa-book fa-fw fa-lg"></i> Syslog</a></li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($config['graylog']['server']) && isset($config['graylog']['port'])) {
|
||||||
|
echo ' <li><a href="'.generate_url(array('page'=>'graylog')).'"><i class="fa fa-book fa-fw fa-lg"></i> Graylog</a></li>';
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
<li><a href="<?php echo(generate_url(array('page'=>'inventory'))); ?>"><i class="fa fa-cube fa-fw fa-lg"></i> Inventory</a></li>
|
<li><a href="<?php echo(generate_url(array('page'=>'inventory'))); ?>"><i class="fa fa-cube fa-fw fa-lg"></i> Inventory</a></li>
|
||||||
<li role="presentation" class="divider"></li>
|
<li role="presentation" class="divider"></li>
|
||||||
<li role="presentation" class="dropdown-header"> Search</li>
|
<li role="presentation" class="dropdown-header"> Search</li>
|
||||||
|
71
html/includes/table/graylog.inc.php
Normal file
71
html/includes/table/graylog.inc.php
Normal file
@@ -0,0 +1,71 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* LibreNMS
|
||||||
|
*
|
||||||
|
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version. Please see LICENSE.txt at the top level of
|
||||||
|
* the source code distribution for details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
$filter_hostname = mres($_POST['hostname']);
|
||||||
|
$filter_range = mres($_POST['range']);
|
||||||
|
|
||||||
|
if (isset($searchPhrase) && !empty($searchPhrase)) {
|
||||||
|
$query = 'message:"'.$searchPhrase.'"';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$query = '*';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($current)) {
|
||||||
|
$offset = ($current * $rowCount) - ($rowCount);
|
||||||
|
$limit = $rowCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($rowCount != -1) {
|
||||||
|
$extra_query = "&limit=$limit&offset=$offset";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($filter_hostname)) {
|
||||||
|
if (!empty($query)) {
|
||||||
|
$query .= ' && ';
|
||||||
|
}
|
||||||
|
$ip = gethostbyname($filter_hostname);
|
||||||
|
$query .= 'source:"'.$filter_hostname.'" || source:"'.$ip.'"';
|
||||||
|
}
|
||||||
|
|
||||||
|
$graylog_url = $config['graylog']['server'] . ':' . $config['graylog']['port'] . '/search/universal/relative?query=' . urlencode($query) . '&range='. $filter_range . $extra_query;
|
||||||
|
|
||||||
|
$context = stream_context_create(array(
|
||||||
|
'http' => array(
|
||||||
|
'header' => "Authorization: Basic " . base64_encode($config['graylog']['username'].':'.$config['graylog']['password']) . "\r\n" .
|
||||||
|
"Accept: application/json",
|
||||||
|
)
|
||||||
|
));
|
||||||
|
|
||||||
|
$messages = json_decode(file_get_contents($graylog_url, false, $context),true);
|
||||||
|
|
||||||
|
foreach ($messages['messages'] as $message) {
|
||||||
|
$response[] = array(
|
||||||
|
'timestamp' => $message['message']['timestamp'],
|
||||||
|
'source' => '<a href="'.generate_url(array('page'=>'device', 'device'=>$message['message']['source'])).'">'.$message['message']['source'].'</a>',
|
||||||
|
'message' => $message['message']['message'],
|
||||||
|
'facility' => $message['message']['facility'],
|
||||||
|
'level' => $message['message']['level'],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($messages['total_results'])) {
|
||||||
|
$total = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$total = $messages['total_results'];
|
||||||
|
}
|
||||||
|
|
||||||
|
$output = array('current'=>$current,'rowCount'=>$rowCount,'rows'=>$response,'total'=>$total);
|
||||||
|
echo _json_encode($output);
|
@@ -30,9 +30,21 @@ if (isset($config['enable_syslog']) && $config['enable_syslog'] == 1) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($config['graylog']['server']) && isset($config['graylog']['port'])) {
|
||||||
|
echo ' | ';
|
||||||
|
if ($vars['section'] == 'graylog') {
|
||||||
|
echo '<span class="pagemenu-selected">';
|
||||||
|
}
|
||||||
|
echo generate_link('Graylog', $vars, array('section' => 'graylog'));
|
||||||
|
if ($vars['section'] == 'graylog') {
|
||||||
|
echo '</span>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch ($vars['section']) {
|
switch ($vars['section']) {
|
||||||
case 'syslog':
|
case 'syslog':
|
||||||
case 'eventlog':
|
case 'eventlog':
|
||||||
|
case 'graylog':
|
||||||
include 'pages/device/logs/'.$vars['section'].'.inc.php';
|
include 'pages/device/logs/'.$vars['section'].'.inc.php';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
5
html/pages/device/logs/graylog.inc.php
Normal file
5
html/pages/device/logs/graylog.inc.php
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
$filter_device = $device['hostname'];
|
||||||
|
require_once 'includes/common/graylog.inc.php';
|
||||||
|
echo implode('',$common_output);
|
4
html/pages/graylog.inc.php
Normal file
4
html/pages/graylog.inc.php
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
require_once 'includes/common/graylog.inc.php';
|
||||||
|
echo implode('',$common_output);
|
1
sql-schema/063.sql
Normal file
1
sql-schema/063.sql
Normal file
@@ -0,0 +1 @@
|
|||||||
|
INSERT INTO `widgets` (`widget_title`, `widget`, `base_dimensions`) VALUES ('Graylog', 'graylog', '9,7');
|
Reference in New Issue
Block a user