mirror of
https://github.com/librenms/librenms.git
synced 2024-10-07 16:52:45 +00:00
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
This commit is contained in:
@@ -122,13 +122,7 @@ class GraylogApi
|
||||
}
|
||||
|
||||
if ($device) {
|
||||
$ip = gethostbyname($device->hostname);
|
||||
$device_query = 'source:"' . $device->hostname . '" || source:"' . $ip . '"';
|
||||
if ($device->ip && $ip != $device->ip) {
|
||||
$device_query .= ' || source:"' . $device->ip . '"';
|
||||
}
|
||||
|
||||
$query[] = '(' . $device_query . ')';
|
||||
$query[] = 'source: ("' . $this->getAddresses($device)->implode('" OR "') . '")';
|
||||
}
|
||||
|
||||
if (empty($query)) {
|
||||
@@ -138,6 +132,22 @@ class GraylogApi
|
||||
return implode('&&', $query);
|
||||
}
|
||||
|
||||
public function getAddresses(Device $device)
|
||||
{
|
||||
$addresses = collect([
|
||||
gethostbyname($device->hostname),
|
||||
$device->hostname,
|
||||
$device->ip,
|
||||
]);
|
||||
|
||||
if (Config::get('graylog.match-any-address')) {
|
||||
$addresses = $addresses->merge($device->ipv4->pluck('ipv4_address'))
|
||||
->merge($device->ipv6->pluck('ipv6_address'));
|
||||
}
|
||||
|
||||
return $addresses->filter()->unique();
|
||||
}
|
||||
|
||||
public function isConfigured()
|
||||
{
|
||||
return isset($this->client->getConfig()['base_uri']);
|
||||
|
@@ -27,6 +27,7 @@ namespace App\Http\Controllers\Table;
|
||||
|
||||
use App\ApiClients\GraylogApi;
|
||||
use App\Models\Device;
|
||||
use App\Models\Port;
|
||||
use DateInterval;
|
||||
use DateTime;
|
||||
use DateTimeZone;
|
||||
@@ -37,6 +38,7 @@ use LibreNMS\Util\Url;
|
||||
class GraylogController extends SimpleTableController
|
||||
{
|
||||
private $timezone;
|
||||
private $deviceCache = [];
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
@@ -105,14 +107,17 @@ class GraylogController extends SimpleTableController
|
||||
$displayTime = $message['message']['timestamp'];
|
||||
}
|
||||
|
||||
$level = isset($message['message']['level']) ? $message['message']['level'] : '';
|
||||
$device = $this->deviceFromSource($message['message']['source']);
|
||||
$level = $message['message']['level'] ?? '';
|
||||
$facility = $message['message']['facility'] ?? '';
|
||||
|
||||
return [
|
||||
'severity' => $this->severityLabel($level),
|
||||
'timestamp' => $displayTime,
|
||||
'source' => '<a href="'.Url::generate(['page'=>'device', 'device'=>$message['message']['source']]).'">'.$message['message']['source'].'</a>',
|
||||
'message' => isset($message['message']['message']) ? $message['message']['message'] : '',
|
||||
'facility' => isset($message['message']['facility']) ? $message['message']['facility'] : '',
|
||||
'level' => $level,
|
||||
'source' => $device ? Url::deviceLink($device) : $message['message']['source'],
|
||||
'message' => $message['message']['message'] ?? '',
|
||||
'facility' => is_numeric($facility) ? "($facility) " . __("syslog.facility.$facility"): $facility,
|
||||
'level' => is_numeric($level) ? "($level) " . __("syslog.severity.$level") : $level,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -132,4 +137,18 @@ class GraylogController extends SimpleTableController
|
||||
$barColor = isset($map[$severity]) ? $map[$severity] : 'label-info';
|
||||
return '<span class="alert-status '.$barColor .'" style="margin-right:8px;float:left;"></span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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];
|
||||
}
|
||||
}
|
||||
|
@@ -476,6 +476,16 @@ class Device extends BaseModel
|
||||
return $this->belongsToMany('App\Models\DeviceGroup', 'device_group_device', 'device_id', 'device_group_id');
|
||||
}
|
||||
|
||||
public function ipv4()
|
||||
{
|
||||
return $this->hasManyThrough('App\Models\Ipv4Address', 'App\Models\Port', 'device_id', 'port_id', 'device_id', 'port_id');
|
||||
}
|
||||
|
||||
public function ipv6()
|
||||
{
|
||||
return $this->hasManyThrough('App\Models\Ipv6Address', 'App\Models\Port', 'device_id', 'port_id', 'device_id', 'port_id');
|
||||
}
|
||||
|
||||
public function location()
|
||||
{
|
||||
return $this->belongsTo('App\Models\Location', 'location_id', 'id');
|
||||
|
@@ -43,6 +43,10 @@ If you choose to use another user besides the admin user, please note that curre
|
||||
If you have enabled TLS for the Graylog API and you are using a self-signed certificate, please make sure that the certificate is trusted by your LibreNMS host, otherwise the connection will fail.
|
||||
Additionally, the certificate's Common Name (CN) has to match the FQDN or IP address specified in `$config['graylog']['server']`.
|
||||
|
||||
If you want to match the source address of the log entries against any IP address of a device instead of only against
|
||||
the primary address and the host name to assign the log entries to a device, you can activate this function using
|
||||
$config['graylog']['match-any-address'] = 'true';
|
||||
|
||||
## Suppressing/enabling the domain part of a hostname for specific platforms
|
||||
You should see if what you get in syslog/Graylog matches up with your configured hosts first. If you need to modify the syslog messages from specific platforms, this may be of assistance:
|
||||
|
||||
|
@@ -30,10 +30,10 @@ $tmp_output = '
|
||||
<tr>
|
||||
<th data-column-id="severity" data-sortable="false"></th>
|
||||
<th data-column-id="timestamp" data-formatter="browserTime">Timestamp</th>
|
||||
<th data-column-id="level" data-sortable="false">Level</th>
|
||||
<th data-column-id="level">Level</th>
|
||||
<th data-column-id="source">Source</th>
|
||||
<th data-column-id="message" data-sortable="false">Message</th>
|
||||
<th data-column-id="facility" data-sortable="false">Facility</th>
|
||||
<th data-column-id="facility">Facility</th>
|
||||
</tr>
|
||||
</thead>
|
||||
</table>
|
||||
@@ -43,7 +43,7 @@ $tmp_output = '
|
||||
|
||||
searchbar = "<div id=\"{{ctx.id}}\" class=\"{{css.header}}\"><div class=\"row\">"+
|
||||
"<div class=\"col-sm-8\"><form method=\"post\" action=\"\" class=\"form-inline\">"+
|
||||
' . addslashes(csrf_field()) . ' +
|
||||
"' . addslashes(csrf_field()) . '" +
|
||||
"Filter: "+
|
||||
';
|
||||
|
||||
|
40
resources/lang/en/syslog.php
Normal file
40
resources/lang/en/syslog.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
'severity' => [
|
||||
'0' => 'Emergency',
|
||||
'1' => 'Alert',
|
||||
'2' => 'Critical',
|
||||
'3' => 'Error',
|
||||
'4' => 'Warning',
|
||||
'5' => 'Notice',
|
||||
'6' => 'Informational',
|
||||
'7' => 'Debug',
|
||||
],
|
||||
'facility' => [
|
||||
'0' => 'kernel messages',
|
||||
'1' => 'user-level messages',
|
||||
'2' => 'mail-system',
|
||||
'3' => 'system daemons',
|
||||
'4' => 'security/authorization messages',
|
||||
'5' => 'messages generated internally by syslogd',
|
||||
'6' => 'line printer subsystem',
|
||||
'7' => 'network news subsystem',
|
||||
'8' => 'UUCP subsystem',
|
||||
'9' => 'clock daemon',
|
||||
'10' => 'security/authorization messages',
|
||||
'11' => 'FTP daemon',
|
||||
'12' => 'NTP subsystem',
|
||||
'13' => 'log audit',
|
||||
'14' => 'log alert',
|
||||
'15' => 'clock daemon (note 2)',
|
||||
'16' => 'local use 0 (local0)',
|
||||
'17' => 'local use 1 (local1)',
|
||||
'18' => 'local use 2 (local2)',
|
||||
'19' => 'local use 3 (local3)',
|
||||
'20' => 'local use 4 (local4)',
|
||||
'21' => 'local use 5 (local5)',
|
||||
'22' => 'local use 6 (local6)',
|
||||
'23' => 'local use 7 (local7)',
|
||||
]
|
||||
];
|
Reference in New Issue
Block a user