Syslog sink over http for logstash (or any json source) (#14424)

* inital commit of a new syslog sink over http

* cosmetics

* cosmetics fix...

* cosmetic fix again

* cosmetics fix again

* its nice now...

* add non blocking option

* Syslog Sink integrated as API PUT method

* lint fix

* Update includes/html/api_functions.inc.php

Co-authored-by: Tony Murray <murraytony@gmail.com>

* Update includes/html/api_functions.inc.php

Co-authored-by: Tony Murray <murraytony@gmail.com>

* Update includes/html/api_functions.inc.php

Co-authored-by: Tony Murray <murraytony@gmail.com>

* change to POST, fix decoding issue and json exception

* logstash/json documentation added. syslog documentation a bit re-structured

* lint fix

---------

Co-authored-by: Tony Murray <murraytony@gmail.com>
This commit is contained in:
Stef 2023-03-15 14:14:38 +01:00 committed by GitHub
parent 1173cf3161
commit 82bd437e47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 157 additions and 33 deletions

View File

@ -75,3 +75,34 @@ Output:
]
}
```
### `syslogsink`
Route: `/api/v0/logs/syslogsink`
Accept any json messages and passes to further syslog processing. single messages or an array of multiple messages is accepted. see [Syslog](../Extensions/Syslog.md) for more details and logstash integration
Example
```
curl -L -X POST 'https://sink.librenms.org/api/v0/syslogsink/' -H 'X-Auth-Token: xxxxxxxLibreNMSApiToken' --data-raw '[
{
"msg": "kernel: minimum Message",
"host": "mydevice.fqdn.com"
},
{
"msg": "Line protocol on Interface GigabitEthernet1/0/41, changed state to up",
"facility": 23,
"priority": "189",
"program": "LINEPROTO-5-UPDOWN",
"host": "172.29.10.24",
"@timestamp": "2022-12-01T20:14:28.257Z",
"severity": 5,
"level": "ERROR"
},
{
"msg": "kernel: a unknown host",
"host": "unknown.fqdn.com"
}
]'
```

View File

@ -68,7 +68,7 @@ This is achieved with `mkdocs`, a python package.
1. Install the required packages.
```
pip install mkdocs mkdocs-exclude mkdocs-material mkdocs-macros-plugin
pip install mkdocs mkdocs-exclude mkdocs-material mkdocs-macros-plugin mkdocs-minify-plugin mkdocs-redirects
```
If you encounter permissions issues, these might be reoslved by using the
user option, with whatever user you are building as, e.g. `-u librenms`

View File

@ -1,13 +1,18 @@
# Syslog support
This document will explain how to send syslog data to LibreNMS.
Please also refer to the file Graylog.md for an alternate way of
integrating syslog with LibreNMS.
## Syslog server installation
## Syslog integration variants
This section explain different ways to recieve and process syslog with LibreNMS.
Except of graylog, all Syslogs variants store their logs in the LibreNMS database. You need to enable the Syslog extension in `config.php`:
### syslog-ng
```php
$config['enable_syslog'] = 1;
```
A Syslog integration gives you a centralized view of information within the LibreNMS (device view, traps, event). Further more you can trigger alerts based on syslog messages (see rule collections).
### Traditional Syslog server
#### syslog-ng
=== "Debian / Ubuntu"
```ssh
apt-get install syslog-ng-core
@ -43,13 +48,6 @@ Next start syslog-ng:
service syslog-ng restart
```
Add the following to your LibreNMS `config.php` file to enable the Syslog extension:
```php
$config['enable_syslog'] = 1;
```
If no messages make it to the syslog tab in LibreNMS, chances are you experience an issue with SELinux. If so, create a file mycustom-librenms-rsyslog.te , with the following content:
```
@ -80,7 +78,7 @@ semodule -i mycustom-librenms-rsyslog.pp
```
### rsyslog
#### rsyslog
If you prefer rsyslog, here are some hints on how to get it working.
@ -141,13 +139,7 @@ that generated the message. The `fromhost` property is preferred as
it avoids problems caused by devices sending incorrect hostnames in
syslog messages.
Add the following to your LibreNMS `config.php` file to enable the Syslog extension:
```php
$config['enable_syslog'] = 1;
```
### logstash
### Local Logstash
If you prefer logstash, and it is installed on the same server as
LibreNMS, here are some hints on how to get it working.
@ -186,23 +178,91 @@ the incoming syslog port. Alternatively, if you already have a
logstash config file that works except for the LibreNMS export, take
only the "exec" section from output and add it.
Add the following to your LibreNMS `config.php` file to enable the Syslog extension:
### Remote Logstash (or any json source)
If you have a large logstash / elastic installation for collecting and filtering syslogs, you can simply pass the relevant logs as json to the LibreNMS API "syslog sink". This variant may be more flexible and secure in transport. It does not require any major changes to existing ELK setup. You can also pass simple json kv messages from any kind of application or script (example below) to this sink.
```ssh
$config['enable_syslog'] = 1;
For long term or advanced aggregation searches you might still use Kibana/Grafana/Graylog etc. It is recommended to keep `config['syslog_purge']` short.
A schematic setup can look like this:
```
┌──────┐
│Device├─►┌───────────────────┐ ┌──────────────┐
└──────┘ │Logstash Cluster ├┬──────────────►│ElasticSearch ├┐
│ RabbitMQ ││ │ Cluster ││
┌──────┬──►│ Filtering etc ││ ───────┐ └┬─────────────┼│
│Device│ └┬──────────────────┼│ │ └──────────────┘
└──────┘ └───────────────────┘ ▼
~~~WAN~~~
┌─┼─┐
│┼┼┼│ LB / Firewall / etc
└─┼─┘
┌────────────────────┐ ┌────────────────────┐
│LibreNMS Sink ├┬──►│LibreNMS Master │
│/api/v0/syslogsink/ ││ │ MariaDB │
└┬───────────────────┼│ └────────────────────┘
└────────────────────┘
```
## Syslog Clean Up
Can be set inside of `config.php`
```php
$config['syslog_purge'] = 30;
A minimal [Logstash http output](https://www.elastic.co/guide/en/logstash/current/plugins-outputs-http.html) configuration can look like this:
```
output {
....
#feed it to LibreNMS
http {
http_method => "post"
url => "https://sink.librenms.org/api/v0/syslogsink/ # replace with your librenms host
format => "json_batch" # put multiple syslogs in on HTTP message
retry_failed => false # if true, logstash is blocking if the API is unavailable, be careful!
headers => ["X-Auth-Token","xxxxxxxLibreNMSApiToken]
# optional if your mapping is not already done before or does not match. "msg" and "host" is mandatory.
# you might also use out the clone {} function to duplicate your log stream and a dedicated log filtering/mapping etc.
# mapping => {
# "host"=> "%{host}"
# "program" => "%{program}"
# "facility" => "%{facility_label}"
# "priority" => "%{syslog5424_pri}"
# "level" => "%{facility_label}"
# "tag" => "%{topic}"
# "msg" => "%{message}"
# "timestamp" => "%{@timestamp}"
# }
}
}
```
The cleanup is run by daily.sh and any entries over X days old are
automatically purged. Values are in days. See here for more Clean Up
Options [Link](../Support/Cleanup-options.md)
Sample test data:
```
curl -L -X POST 'https://sink.librenms.org/api/v0/syslogsink/' -H 'X-Auth-Token: xxxxxxxLibreNMSApiToken' --data-raw '[
{
"msg": "kernel: minimum Message",
"host": "mydevice.fqdn.com"
},
{
"msg": "Line protocol on Interface GigabitEthernet1/0/41, changed state to up",
"facility": 23,
"priority": "189",
"program": "LINEPROTO-5-UPDOWN",
"host": "172.29.10.24",
"@timestamp": "2022-12-01T20:14:28.257Z",
"severity": 5,
"level": "ERROR"
},
{
"msg": "kernel: a unknown host",
"host": "unknown.fqdn.com"
}
]'
```
`msg` and `host` are the minimum keys.
### Graylog
This mvariant ethod use a external Graylog installation and its database. Please refer to the dedicated [Graylog](Graylog.md) documentation.
## Client configuration
@ -398,6 +458,18 @@ $config['os']['procurve']['syslog_hook'][] = Array('regex' => '/Running Config C
```
## Configuration Options
### Syslog Clean Up
Can be set inside of `config.php`
```php
$config['syslog_purge'] = 30;
```
The cleanup is run by daily.sh and any entries over X days old are
automatically purged. Values are in days. See here for more Clean Up
Options [Link](../Support/Cleanup-options.md)
### Matching syslogs to hosts with different names

View File

@ -2924,6 +2924,26 @@ function edit_service_for_host(Illuminate\Http\Request $request)
return api_error(500, "Failed to update the service with id $service_id");
}
/**
* recieve syslog messages via json https://github.com/librenms/librenms/pull/14424
*/
function post_syslogsink(Illuminate\Http\Request $request)
{
$json = $request->json()->all();
if (is_null($json)) {
return api_success_noresult(400, 'Not valid json');
}
$logs = array_is_list($json) ? $json : [$json];
foreach ($logs as $entry) {
process_syslog($entry, 1);
}
return api_success_noresult(200, 'Syslog received: ' . count($logs));
}
/**
* Display Librenms Instance Info
*/

View File

@ -94,6 +94,7 @@ Route::group(['prefix' => 'v0', 'namespace' => '\App\Api\Controllers'], function
Route::delete('services/{id}', 'LegacyApiController@del_service_from_host')->name('del_service_from_host');
Route::patch('services/{id}', 'LegacyApiController@edit_service_for_host')->name('edit_service_for_host');
Route::post('bgp/{id}', 'LegacyApiController@edit_bgp_descr')->name('edit_bgp_descr');
Route::post('syslogsink', 'LegacyApiController@post_syslogsink')->name('post_syslogsink');
});
// restricted by access