Syslog server inrichten

Toen ik deze week voor het eerst na een paar maanden de syslog van de NSLU2 eens nakeek, ontdekte ik een paar kernel errors die er op wezen dat er fouten waren op het root filesystem. Nog die zelfde dag liep de NSLU2 vast omdat het operating systeem het root filesystem op read-only zette om verdere degradatie van de “schijf” te voorkomen.

Dat had ik graag eerder zien aankomen. Al langer had ik de wens om alle errors van mijn tasmota en ESPEasy devices op één centrale plek te kunnen inzien. Tijd om een syslog server in te richten zodat alle logs van de devices in mijn netwerk die daar toe in staat zijn op één centrale plek in te zien zijn. Op die centrale logging wil ik vervolgens wat controls inbouwen en Nagios die laten bewaken.

In deze tutorial richt ik een centrale syslog server in op mijn Raspberry PI. Configureer ik een rsyslog client op de NSLU2 (met Debian Jessy) en configureer ik zoveel mogelijk devices op mijn netwerk, waaronder Tasmota en ESPEasy devices om hun errors te loggen op de centrale syslog server.

Stap 1. Syslog installeren op Raspbian en/of Debian

Je kunt in beide gevallen simpelweg volstaan met één commando, namelijk

sudo apt install rsyslog

Stap 2. Centrale syslog server configureren

Dit staat uitgebreid beschreven op https://www.thegeekpub.com/269780/raspberry-pi-syslog-server-setup/, hieronder een korte samenvatting:

sudo vi /etc/rsyslog.conf

Zoek vervolgens onderstaande 4 regels in deze configurartie file, en verwijder de hashtag (#) voor de regel om die uit te commentarieren.

#module(load="imudp")
#input(type="imudp" port="514") 
#module(load="imtcp")
#input(type="imtcp" port="514")

De regels zien er dan zo uit:

module(load="imudp")
input(type="imudp" port="514") 
module(load="imtcp")
input(type="imtcp" port="514")

De syslog server luistert nu, zowel met het udp als tcp protocol, op poort 514. Herstart nu de syslog server met:

sudo systemctl restart rsyslog

Met deze configuratie komt alle logging in de /var/log/syslog terecht op de Raspberry Pi. Dit is niet handig en overzichtelijk. Dus verderop in deze tutorial gaan we templates inrichten zodat de logging van verschillende types devices netjes in aparte logfiles terechtkomen. Dit om het wat overzichtelijk te houden. Maar eerst configureren we diverse devices zodat ze hun logging gaan spugen naar de centrale syslog server.

Stap 3. NSLU2 (Debian Jessie) linux server inrichten als Syslog client

Na het installeren van rsyslog is er maar een wijziging in de configuratie file nodig om de syslog logentry’s op de centrale Syslog server te laten terechtkomen, namelijk:

sudo vi /etc/rsyslog.conf

Voeg nu onderstaande regel toe boven in de file, net onder de eerste uitgecommentarieerde regels:

@@<ip-address syslog server>:<poortnummer>

In mijn geval dus @@192.168.2.29:514, de eerste 5 regels van de file ziet er dan zo uit:

nslu2:~# cat /etc/rsyslog.conf
# /etc/rsyslog.conf    Configuration file for rsyslog.
#
#                      For more information see
#                      /usr/share/doc/rsyslog-doc/html/rsyslog_conf.html
@@192.168.2.29:514

Herstart ook daar de rsyslog deamon met:

sudo systemctl restart rsyslog

Check de /var/log/syslog file op je Raspberry Pi om te checken of de NSLU2 (of willekeurige andere Linux server) zijn logging doorstuurt naar de centrale Syslog server.

Stap 4. Tasmota device configureren

Ga in het hoofdmenu naar Configuration

En vervolgens naar Configure Logging

Het volgende scherm verschijnt:

Kies bij Syslog level, level ‘1 Error’ en vul bij Syslog host het ip-address van je centrale Syslog server in. In mijn geval dus 192.168.2.29. Het poortnummer is reeds voor ingevuld, en is goed. De configuratie ziet er dan zo uit:

Klik op Save, en je bent klaar.

Tip: Als je meerdere Tasmota devices hebt, kun je het proces versnellen door een lijstje aan te leggen met de ip-adressen van je Tasmota devices. En vervolgens de volgende url hergebruiken door steeds het ip-address te wijzigen.

http://<ip-address>/lg?l0=2&l1=2&l2=0&l3=1&lh=<ip-address syslog server>&lp=514&lt=300&save=

Stap 5. ESPEasy device configureren

In het hoofdmenu kies voor Tools

en vervolgens voor Advanced:

het volgende scherm verschijnt:

scroll naar beneden, en onder het kopje ‘Log Settings’ vul je bij Syslog IP het ip-adress in van je centrale Syslog server, de Syslog UDP port staat al goed voor ingevuld. Selecteer bij Syslog Log Level ‘Error’ in. Syslog Facility kan op de default waarde blijven staan.

Klik op Save en je bent klaar.

Stap 6. Shelly devices configureren

Shelly devices beschikken helaas nog niet over de functionaliteit om hun logging naar een syslog server te sturen. Wel beschikken de shelly’s vanaf firmware 20210723-153500/v1.11.0-Dimmer-g1d5998d voor Shelly dimmer 2 en 20210720-184522/v1.11.0-g6abd92e voor Shelly1 over de optie om Debug aan te zetten en weg te schrijven naar een logfile. Debugging zet je aan door onder Settings, Device Info op de knop ‘Enable Debug Log’ te klikken.

Via de knoppen Download previous log en Download current log kun je vervolgens de logfiles inzien. Echter het is ook mogelijk om rechtstreeks de log in te zien via http://<ip address shelly>/debug/log

Shelly waarschuwt er overigens voor om de debugging alleen aan te zetten wanneer dit nodig is, dit om “slijtage” van het flash geheugen te voorkomen. Ik heb er daarom voor gekozen om wel iedere avond om 00:00 uur de eventuele beschikbare logfiles te verzamen in één logfile. Als geen van de shellies in debug mode staat zal die leeg blijven. Pas als ik één of meerdere shellies in debug mode zet door onder Settings, Device Info de knop ‘Enable Debug Log” te activeren zal er zich debug info verzamelen in de logfile.

Voor het verzamelen van de logfiles van alle shellies heb ik het volgende script gemaakt (Noot: Zorg er eerst wel voor dat alle shellies over de meest recente firmware beschikken)

#! /bin/bash
# script to collect Debug logfiles from all shellies
#
# Author: Syds Post
# Version: 1.0

shellies=$(arp -n | awk '{print $1}' | nslookup | grep shelly | awk '{print $4}')

for shelly in $shellies
do
  status=$(wget $shelly/debug/log 2>&1)
  echo $status >> shelly_logs.log
  cat log | sed "s/^/$shelly $(date '+%Y%m%d ')/g" >> /var/log/shelly.log
  rm log
done

Voorbeeld van de genereerde log file (/var/log/shelly.log)

root@raspberrypi:/home/pi/scripts# cat /var/log/shelly.log
shelly1-E8DB84D44487.sydspost.nl. 20210802 623644671 mgos_sys_config.c:174   Saved to conf9.json
shelly1-E8DB84D44487.sydspost.nl. 20210802 623756901 mgos_http_server.c:180  0x3fff24f4 HTTP connection from 192.168.2.123:60897
shelly1-E8DB84D44487.sydspost.nl. 20210802 623770934 json.c:420              RAM: 50896 total, 37232 free
shelly1-E8DB84D44487.sydspost.nl. 20210802 623786955 mgos_http_server.c:180  0x3fff247c HTTP connection from 192.168.2.123:57040
shelly1-E8DB84D44487.sydspost.nl. 20210802 628753218 mgos_http_server.c:180  0x3fff24f4 HTTP connection from 192.168.2.123:53456
shelly1-E8DB84D44487.sydspost.nl. 20210802 628765472 json.c:420              RAM: 50896 total, 37048 free
shelly1-E8DB84D44487.sydspost.nl. 20210802 634407188 mgos_http_server.c:180  0x3fff243c HTTP connection from 192.168.2.123:63856
shelly1-E8DB84D44487.sydspost.nl. 20210802 634422126 json.c:420              RAM: 50896 total, 37604 free
shelly1-E8DB84D44487.sydspost.nl. 20210802 638212044 mgos_http_server.c:180  0x3fff24f4 HTTP connection from 192.168.2.29:41326

Vervolgens de executie van dit script toegevoegd aan de crontab van root:

root@raspberrypi:/home/pi/scripts# crontab -l
# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
#
# m h  dom mon dow   command
0 0 * * * /home/pi/scripts/shelly_logs.sh

Stap 7. OpenWRT routers configureren

Open LUCI, de web user interface van je router in de browser, en log in. Kies vervolgens voor System -> System, en daarna voor het tabblad Logging:

Vul bij External system log server het IP-address in van je syslog server, in mijn geval 192.168.2.29. De overige instellingen zijn default. Klik op Save & Apply, en de router/accesspoint stuurt zijn logging naar je syslog server.

Stap 8. Templates maken om de logentry’s op te splitsen

Met deze configuratie komen alle logentry’s in de /var/log/syslog file terecht op je centrale Syslog server. Dit kan erg onoverzichtelijk zijn. Ik heb er voor gekozen om de Tasmota en ESPEasy logentry’s in een aparte file op te slaan, namelijk /var/log/tasmota.log. Ook de logentry’s van de OpenWRT routers/accesspoint laat ik in een aparte file terechtkomen, namelijk /var/log/routers.log. De logentry’s van de NSLU2 laat ik gewoon in de syslog file terechtkomen.

Voor het afsplitsen van de logentry’s van de Tasmota en ESPEasy devices de volgende template file gemaakt en deze in de map /etc/rsyslog.d geplaatst:

pi@raspberrypi:/etc/rsyslog.d $ cat tasmota.conf
 $template tasmotalog, "/var/log/tasmota.log"
 if ($programname contains 'ESP') \
     or ($programname contains 'EspEasy') \
     or ($rawmsg contains 'ESP Unit') \
     or ($hostname == 'weerstation1.sydspost.nl') \
     or ($hostname == 'bel.sydspost.nl') \
     or ($hostname == 'filterindicatie.sydspost.nl') \
     or ($hostname == 'bewegingsmeldergang.sydspost.nl') \
 then -?tasmotalog
 & stop

Toelichting:

De verschillende Tasmota en ESPEasy versies genereren verschillende syslog messages. Vandaar dat ik of filter op “programname”, de rawmsg of hostname. Indien een logentry voldoet aan één van de gestelde criteria’s, dan wordt de logentry weggeschreven naar de file /var/log/tasmota.log, en niet langer naar de /var/log/syslog file.

Voor het afsplitsen van de logentry’s van de OpenWRT routers/accesspoints de volgende template file gemaakt en deze in de map /etc/rsyslog.d geplaatst:

pi@raspberrypi:/etc/rsyslog.d $ cat routers.conf
$template routerslog, "/var/log/routers.log"

if ($hostname == 'accesspoint2') \
   or ($hostname == 'accesspoint3') \
then -?routerslog
& stop

Toelichting:

De filtering van de routers kan simpelweg op hostname (zonder domeinnaam), in mijn geval accesspoint2 en accesspoint3. Indien een logentry voldoet aan één van de gestelde criteria’s, dan wordt de logentry weggeschreven naar de file /var/log/routers.log, en niet langer naar de /var/log/syslog file. Na een herstart van de rsyslog deamon wordt de template file actief, en worden de logentry’s van de routers/accesspoints weggeschreven naar /var/log/routers.log

sudo systemctl restart rsyslog

Stap 9. Log rotation geconfigureerd voor /var/log/tasmota.log, /var/log/shelly.log en /var/log/routers.log

Om te voorkomen dat de log-file oneindig doorgroeit, en uiteindelijk je file-system doet vollopen nog log rotation geconfigureerd. Dit zorgt elke dag voor een verse schone logfile en archiveert de huidige logfile. Deze blijven vervolgens 7 dagen bewaard. Dit doe je als volgt:

sudo vi /etc/logrotate.d/tasmota

Kopieer onderstaande configuratie in dit file, en sla deze op

/var/log/tasmota.log
{
        rotate 4
        weekly
        missingok
        notifempty
        compress
        delaycompress
}

Doe hetzelfde voor de logfile /var/log/shelly.log en /var/log/routers.log. Test de logrotation met

sudo logrotate -f /etc/logrotate.conf

ls -lia /var/log/tasmota.* /var/log/routers.* /var/log/shelly.*


Als het goed is zie je nu onderstaande listing

pi@raspberrypi:/etc/rsyslog.d $ ls -lia /var/log/tasmota.* /var/log/routers.* /var/log/shelly.*
12546 -rw-r----- 1 root adm     194 jul 29 16:17 /var/log/routers.log
 7012 -rw-r----- 1 root adm   49907 jul 29 16:16 /var/log/routers.log.1
20518 -rw-r--r-- 1 root root      0 jul 29 16:17 /var/log/tasmota.log
41227 -rw-r--r-- 1 root root  73509 jul 29 16:17 /var/log/tasmota.log.1
11549 -rw-r--r-- 1 root root    0 aug  2 15:37 /var/log/shelly.log
14358 -rw-r--r-- 1 root root 1059 aug  2 15:32 /var/log/shelly.log.1

Stap 10. Critical errors filteren en weergeven in Nagios

Hiervoor gebruik ik de nagios plugin check_log (Wordt standaard meegeleverd). Aan de /usr/local/nagios/etc/objects/commands.cfg file de volgende commando definitie toegevoegd:

define command {
    command_name    check_log
    command_line    $USER1$/check_log -F $ARG1$ -O $ARG1$.old -q $ARG2$

}

Toelichting:

$ARG1$: Naam logfile (bijv. /var/log/tasmota.log)

$ARG2$: Uit te voeren query (bijv. ‘Error’)

Voor de controle van de verschillende logfiles heb ik een nieuwe configuratie file logging.cfg in het leven geroepen. Om deze te activeren dient deze toegevoegd te worden aan /usr/local/nagios/etc/nagios.cfg:

# You can specify individual object config files as shown below:
cfg_file=/usr/local/nagios/etc/objects/commands.cfg
cfg_file=/usr/local/nagios/etc/objects/logging.cfg

Om de notificaties rondom de logfiles te groeperen, tevens een servicegroup “logfiles” aangemaakt, hiervoor de file /usr/local/nagios/etc/objects/servicegroups.cfg aangemaakt met de volgende inhoud:

pi@raspberrypi:/usr/local/nagios/etc/objects $ cat servicegroups.cfg
define servicegroup {
    servicegroup_name  logfiles
    alias              Logfiles
}

Ook deze configuratiefile dient bekend gemaakt te worden in /usr/local/nagios/etc/nagios.cfg:

# You can specify individual object config files as shown below:
cfg_file=/usr/local/nagios/etc/objects/commands.cfg
cfg_file=/usr/local/nagios/etc/objects/servicegroups.cfg
cfg_file=/usr/local/nagios/etc/objects/logging.cfg

Vervolgens het uitlezen van de verschillende logfiles uitgewerkt in /usr/local/nagios/etc/objects/logging.cfg:

###############################################################################
# LOGGING.CFG
#
###############################################################################



###############################################################################
#
# HOST DEFINITION
#
###############################################################################

define host {

    use                     linux-server            ; Name of host template to use
                                                    ; This host definition will inherit all variables that are defined
                                                    ; in (or inherited by) the linux-server host template definition.
    host_name               raspberrypi.sydspost.nl
    display_name            Pi
    address                 192.168.2.29
    contacts                nagiosadmin
    ; check_interval          60
}

###############################################################################
#
# LOGGING DEFINITION
#
###############################################################################

define service {
    use                     local-service
    host_name               raspberrypi.sydspost.nl
    service_description     Domoticz logging
    check_command           check_log!/var/log/domoticz.log!Error
    servicegroup            logfiles
}

define service {
    use                     local-service
    host_name               raspberrypi.sydspost.nl
    service_description     Router logging
    check_command           check_log!/var/log/routers.log!Failed
    servicegroups           logfiles
}

Test de juistheid van de configuratiefiles met het volgende commando

sudo /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg

Dit geeft de volgende output:

pi@raspberrypi:/usr/local/nagios/etc/objects $ sudo /usr/local/nagios/bin/nagios -v /usr/local/nagios/etc/nagios.cfg

Nagios Core 4.4.6
Copyright (c) 2009-present Nagios Core Development Team and Community Contributors
Copyright (c) 1999-2009 Ethan Galstad
Last Modified: 2020-04-28
License: GPL

Website: https://www.nagios.org
Reading configuration data...
   Read main config file okay...
   Read object config files okay...

Running pre-flight check on configuration data...

Checking objects...
        Checked 69 services.
        Checked 58 hosts.
        Checked 5 host groups.
        Checked 1 service groups.
        Checked 1 contacts.
        Checked 1 contact groups.
        Checked 30 commands.
        Checked 6 time periods.
        Checked 0 host escalations.
        Checked 0 service escalations.
Checking for circular paths...
        Checked 58 hosts
        Checked 0 service dependencies
        Checked 0 host dependencies
        Checked 6 timeperiods
Checking global event handlers...
Checking obsessive compulsive processor commands...
Checking misc settings...

Total Warnings: 0
Total Errors:   0

Things look okay - No serious problems were detected during the pre-flight check

Indien er geen warning en/of errors in voorkomen, dan heb je een en ander goed geconfigureerd.

Om het uitlezen van de logfiles door Nagios mogelijk te maken dient deze leesrechten te krijgen op de files, voer het volgende commando uit om dit te bewerkstelligen:

sudo chmod 644 /var/log/routers.log /var/log/tasmota.log

Herstart Nagios nu met:

sudo service nagios restart

Ga vervolgens met je browser naar http://<ip address van je nagios server>>/nagios en log in, de servicegroup “logfiles” vindt je onder Servicegroups

Klik op “Logfiles” om de details van deze servicegroup te kunnen inzien

Geef een antwoord

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *