Files
librenms-librenms/app/Http/Controllers/Table/GraylogController.php

159 lines
5.2 KiB
PHP
Raw Normal View History

<?php
/**
* GraylogController.php
*
* -Description-
*
* 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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* @package LibreNMS
* @link http://librenms.org
* @copyright 2018 Tony Murray
* @author Tony Murray <murraytony@gmail.com>
*/
namespace App\Http\Controllers\Table;
use App\ApiClients\GraylogApi;
use App\Models\Device;
Graylog entry matching device if source is not hostname or primary ip (#10458) * Added findByHostnameOrIp($hostnameOrIp) for devices. Returns Device or null Fixed Graylog device links, "device" parameter in URL was IP or Hostname instead of device id before Added Severity number to name conversion. Can be activated by setting $config['graylog']['severity-names'] = "true" in config Added Facility number to name conversion. Can be activated by setting $config['graylog']['facility-names'] = "true" in config * Added $config['graylog']['match-any-address']. To enable matching Graylog entries by any interface address set to "true" Added code to match Graylog entries by any interface address instead of only hostname or primary address * Fixed missing quotation marks in <script> block in includes/html/common/graylog.inc.php:46, causing graylog page only load header with empty table. Introduced in https://github.com/librenms/librenms/pull/10447 * Modified code to reduce complexity as mentioned by codeclimate * Changed findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Added Language File "syslog.php" for Syslog Severity and Facility Merged functions "levelName($level)" and "facilityName($facility)" to "syslogPrioParser($type, $value)" where $type should be "facility" or "severity" and $value the numeric or text facility or severity. Returns "NUMBER (NAME)" if possible, otherwhise returns $value * Shortened findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Add shortcut ipv4 and ipv6 device relationships Better code for adding source addresses Only translate level and facility if they are numeric Allow level and facility to be sortable No need for device link if we know it won't work. Before the code was punting to save sql queries. * Cache devices Took queries from 69 to 6 in my quick test. * Added Documentation for $config['graylog']['match-any-address'] * Fixed missing quotation marks in app/ApiClients/GraylogApi.php:125
2019-07-26 22:13:35 +02:00
use App\Models\Port;
use DateInterval;
use DateTime;
use DateTimeZone;
use Illuminate\Http\Request;
use LibreNMS\Config;
use LibreNMS\Util\Url;
class GraylogController extends SimpleTableController
{
private $timezone;
Graylog entry matching device if source is not hostname or primary ip (#10458) * Added findByHostnameOrIp($hostnameOrIp) for devices. Returns Device or null Fixed Graylog device links, "device" parameter in URL was IP or Hostname instead of device id before Added Severity number to name conversion. Can be activated by setting $config['graylog']['severity-names'] = "true" in config Added Facility number to name conversion. Can be activated by setting $config['graylog']['facility-names'] = "true" in config * Added $config['graylog']['match-any-address']. To enable matching Graylog entries by any interface address set to "true" Added code to match Graylog entries by any interface address instead of only hostname or primary address * Fixed missing quotation marks in <script> block in includes/html/common/graylog.inc.php:46, causing graylog page only load header with empty table. Introduced in https://github.com/librenms/librenms/pull/10447 * Modified code to reduce complexity as mentioned by codeclimate * Changed findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Added Language File "syslog.php" for Syslog Severity and Facility Merged functions "levelName($level)" and "facilityName($facility)" to "syslogPrioParser($type, $value)" where $type should be "facility" or "severity" and $value the numeric or text facility or severity. Returns "NUMBER (NAME)" if possible, otherwhise returns $value * Shortened findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Add shortcut ipv4 and ipv6 device relationships Better code for adding source addresses Only translate level and facility if they are numeric Allow level and facility to be sortable No need for device link if we know it won't work. Before the code was punting to save sql queries. * Cache devices Took queries from 69 to 6 in my quick test. * Added Documentation for $config['graylog']['match-any-address'] * Fixed missing quotation marks in app/ApiClients/GraylogApi.php:125
2019-07-26 22:13:35 +02:00
private $deviceCache = [];
public function __construct()
{
$timezone = Config::get('graylog.timezone');
$this->timezone = $timezone ? new DateTimeZone($timezone) : null;
}
public function __invoke(Request $request, GraylogApi $api)
{
if (!$api->isConfigured()) {
return response()->json([
'error' => 'Graylog is not configured',
], 503);
}
$this->validate($request, [
'stream' => 'nullable|alpha_num',
'device' => 'nullable|int',
'range' => 'nullable|int',
'loglevel' => 'nullable|int|min:0|max:7',
]);
$search = $request->get('searchPhrase');
$device_id = $request->get('device');
$device = $device_id ? Device::find($device_id) : null;
$range = $request->get('range', 0) ;
$limit = $request->get('rowCount', 10);
$page = $request->get('current', 1);
$offset = ($page - 1) * $limit;
$loglevel = $request->get('loglevel') ?? Config::get('graylog.loglevel');
$query = $api->buildSimpleQuery($search, $device).
($loglevel !== null ? ' AND level: <='. $loglevel : '');
$sort = null;
foreach ($request->get('sort', []) as $field => $direction) {
$sort = "$field:$direction";
}
$stream = $request->get('stream');
$filter = $stream ? "streams:$stream" : null;
try {
$data = $api->query($query, $range, $limit, $offset, $sort, $filter);
return $this->formatResponse(
array_map([$this, 'formatMessage'], $data['messages']),
$page,
count($data['messages']),
$data['total_results']
);
} catch (\Exception $se) {
$error = $se->getMessage();
}
return response()->json([
'error' => $error,
], 500);
}
private function formatMessage($message)
{
if ($this->timezone) {
$graylogTime = new DateTime($message['message']['timestamp']);
$offset = $this->timezone->getOffset($graylogTime);
$timeInterval = DateInterval::createFromDateString((string)$offset . 'seconds');
$graylogTime->add($timeInterval);
$displayTime = $graylogTime->format('Y-m-d H:i:s');
} else {
$displayTime = $message['message']['timestamp'];
}
Graylog entry matching device if source is not hostname or primary ip (#10458) * Added findByHostnameOrIp($hostnameOrIp) for devices. Returns Device or null Fixed Graylog device links, "device" parameter in URL was IP or Hostname instead of device id before Added Severity number to name conversion. Can be activated by setting $config['graylog']['severity-names'] = "true" in config Added Facility number to name conversion. Can be activated by setting $config['graylog']['facility-names'] = "true" in config * Added $config['graylog']['match-any-address']. To enable matching Graylog entries by any interface address set to "true" Added code to match Graylog entries by any interface address instead of only hostname or primary address * Fixed missing quotation marks in <script> block in includes/html/common/graylog.inc.php:46, causing graylog page only load header with empty table. Introduced in https://github.com/librenms/librenms/pull/10447 * Modified code to reduce complexity as mentioned by codeclimate * Changed findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Added Language File "syslog.php" for Syslog Severity and Facility Merged functions "levelName($level)" and "facilityName($facility)" to "syslogPrioParser($type, $value)" where $type should be "facility" or "severity" and $value the numeric or text facility or severity. Returns "NUMBER (NAME)" if possible, otherwhise returns $value * Shortened findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Add shortcut ipv4 and ipv6 device relationships Better code for adding source addresses Only translate level and facility if they are numeric Allow level and facility to be sortable No need for device link if we know it won't work. Before the code was punting to save sql queries. * Cache devices Took queries from 69 to 6 in my quick test. * Added Documentation for $config['graylog']['match-any-address'] * Fixed missing quotation marks in app/ApiClients/GraylogApi.php:125
2019-07-26 22:13:35 +02:00
$device = $this->deviceFromSource($message['message']['source']);
$level = $message['message']['level'] ?? '';
$facility = $message['message']['facility'] ?? '';
return [
'severity' => $this->severityLabel($level),
'timestamp' => $displayTime,
Graylog entry matching device if source is not hostname or primary ip (#10458) * Added findByHostnameOrIp($hostnameOrIp) for devices. Returns Device or null Fixed Graylog device links, "device" parameter in URL was IP or Hostname instead of device id before Added Severity number to name conversion. Can be activated by setting $config['graylog']['severity-names'] = "true" in config Added Facility number to name conversion. Can be activated by setting $config['graylog']['facility-names'] = "true" in config * Added $config['graylog']['match-any-address']. To enable matching Graylog entries by any interface address set to "true" Added code to match Graylog entries by any interface address instead of only hostname or primary address * Fixed missing quotation marks in <script> block in includes/html/common/graylog.inc.php:46, causing graylog page only load header with empty table. Introduced in https://github.com/librenms/librenms/pull/10447 * Modified code to reduce complexity as mentioned by codeclimate * Changed findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Added Language File "syslog.php" for Syslog Severity and Facility Merged functions "levelName($level)" and "facilityName($facility)" to "syslogPrioParser($type, $value)" where $type should be "facility" or "severity" and $value the numeric or text facility or severity. Returns "NUMBER (NAME)" if possible, otherwhise returns $value * Shortened findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Add shortcut ipv4 and ipv6 device relationships Better code for adding source addresses Only translate level and facility if they are numeric Allow level and facility to be sortable No need for device link if we know it won't work. Before the code was punting to save sql queries. * Cache devices Took queries from 69 to 6 in my quick test. * Added Documentation for $config['graylog']['match-any-address'] * Fixed missing quotation marks in app/ApiClients/GraylogApi.php:125
2019-07-26 22:13:35 +02:00
'source' => $device ? Url::deviceLink($device) : $message['message']['source'],
'message' => $message['message']['message'] ?? '',
'facility' => is_numeric($facility) ? "($facility) " . __("syslog.facility.$facility"): $facility,
2019-08-27 12:45:28 -05:00
'level' => (is_numeric($level) && $level >= 0) ? "($level) " . __("syslog.severity.$level") : $level,
];
}
private function severityLabel($severity)
{
$map = [
"0" => "label-danger",
"1" => "label-danger",
"2" => "label-danger",
"3" => "label-danger",
"4" => "label-warning",
"5" => "label-info",
"6" => "label-info",
"7" => "label-default",
"" => "label-info",
];
$barColor = isset($map[$severity]) ? $map[$severity] : 'label-info';
return '<span class="alert-status '.$barColor .'" style="margin-right:8px;float:left;"></span>';
}
Graylog entry matching device if source is not hostname or primary ip (#10458) * Added findByHostnameOrIp($hostnameOrIp) for devices. Returns Device or null Fixed Graylog device links, "device" parameter in URL was IP or Hostname instead of device id before Added Severity number to name conversion. Can be activated by setting $config['graylog']['severity-names'] = "true" in config Added Facility number to name conversion. Can be activated by setting $config['graylog']['facility-names'] = "true" in config * Added $config['graylog']['match-any-address']. To enable matching Graylog entries by any interface address set to "true" Added code to match Graylog entries by any interface address instead of only hostname or primary address * Fixed missing quotation marks in <script> block in includes/html/common/graylog.inc.php:46, causing graylog page only load header with empty table. Introduced in https://github.com/librenms/librenms/pull/10447 * Modified code to reduce complexity as mentioned by codeclimate * Changed findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Added Language File "syslog.php" for Syslog Severity and Facility Merged functions "levelName($level)" and "facilityName($facility)" to "syslogPrioParser($type, $value)" where $type should be "facility" or "severity" and $value the numeric or text facility or severity. Returns "NUMBER (NAME)" if possible, otherwhise returns $value * Shortened findByHostnameOrIp($hostnameOrIp) as mentioned by https://github.com/murrant * Add shortcut ipv4 and ipv6 device relationships Better code for adding source addresses Only translate level and facility if they are numeric Allow level and facility to be sortable No need for device link if we know it won't work. Before the code was punting to save sql queries. * Cache devices Took queries from 69 to 6 in my quick test. * Added Documentation for $config['graylog']['match-any-address'] * Fixed missing quotation marks in app/ApiClients/GraylogApi.php:125
2019-07-26 22:13:35 +02:00
/**
* Cache device lookups so we don't lookup for every entry
* @param $source
* @return mixed
*/
private function deviceFromSource($source)
{
if (!isset($this->deviceCache[$source])) {
$this->deviceCache[$source] = Device::findByIp($source) ?: Device::findByHostname($source);
}
return $this->deviceCache[$source];
}
}