Browsed by
Tag: Log

Logování – vzdálený syslog

Logování – vzdálený syslog

Úvod

Loxone nabízí možnost využití vzdáleného logu, tedy odesílání zpráv logu do logu na jiném zařízení. Výhoda je jasná – logování na SD kartu Loxone snižuje životnost SD karty a navíc na vzdáleném stroji si můžete log analyzovat. K tomu, aby šlo vzdálený log využít, potřebujeme nějaký stroj s Linuxem, nainstalovaným balíčkem rsyslog, webovým serverem s PHP (volitelně s databází). V našem návodu použijeme stroj s nainstalovaným Debianem. Není třeba instalovat grafické prostředí – zbytečně zabírá operační paměť a reálně ho vůbec nepotřebujeme. Já osobně používám virtuální server na svém domácím serveru.

LoxBerry plugin

Od 4.4.2018 je celé řešení k dispozici jako plugin Syslog Server do LoxBerry.

Rsyslog

V Debianu by měl být rsyslog defaultně nainstalovaný. Pokud není, nainstaluje se pomocí:

sudo apt-get install rsyslog

Následně provedeme konfiguraci:

sudo nano /etc/rsyslog.conf

Odkomentujeme řádky týkající se přístupu přes UDP a TCP:

# provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
# provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514

Dále pak zakomentujeme řádek s definicí formátu datumu, abychom měli plný timestamp:

#
# Use traditional timestamp format.
# To enable high precision timestamps, comment out the following line.
#
#$ActionFileDefaultTemplate RSYSLOG_TraditionalFileFormat

Dále vytvoříme konfiguraci pro Loxone:

sudo nano /etc/rsyslog.d/loxone.conf

A vložíme do ní konfiguraci přesměrování zpráv z Loxone do samostatného Log souboru.
192.168.1.10 nahradíme adresou Loxone miniserveru:

# změnit skupinu vytvořeného logu na www-data, aby ji mohl číst LogAnalyzer
$FileGroup www-data

# zpracuj zprávy z Loxone do separátního souboru
:fromhost-ip, isequal, "192.168.1.10" /var/log/loxone.log
& ~
# pouze zprávy odjinud než z Loxone budou pokračovat dál

# Vrátit skupinu pro ostatní Logy na default
$FileGroup adm

Restartujeme Rsyslog:

sudo service rsyslog restart

Nastavení Loxone

V Loxone Configu si ve stromu rozbalíme položku Miniserveru, stoupneme na “Zprávy” a klikneme na ikonku Logger. Tím vložíme nový Logger. Přidělíme mu jméno dle libosti a adresu /dev/syslog/<ip_log_serveru>
Pak již běžně přiřazujeme Logger

Analyzování

Adiscon Log Analyzer

K provozování potřebujeme nainstalovat na logserver webserver a php:
(pokud používáte již existující stroj s PHP, zkontrolujte, že máte v apache2 nainstalovaný a aktivovaný mode php; na čisté instalaci se vše provede samo)

sudo apt-get install apache2 php

Stáhneme z oficiálních stránek: http://loganalyzer.adiscon.com/ Cestu za příkazem wget samozřejmě změníme na aktuální. Adekvátně k tomu pak všechny příkazy s loganalyzer-4.1.6 upravit na adekvátní název souboru / adresáře.
Pak rozbalíme a obsah adresáře src zkopírujeme do /var/www/loganalyzer
Pak změníme vlastníka:

wget http://download.adiscon.com/loganalyzer/loganalyzer-4.1.6.tar.gz
sudo tar -xvzf loganalyzer-4.1.6.tar.gz
sudo rm loganalyzer-4.1.6.tar.gz
sudo mkdir /var/www/loganalyzer
sudo cp -r loganalyzer-4.1.6/src/* /var/www/loganalyzer
sudo chown -Rv www-data:www-data /var/www/loganalyzer

Nyní si zkonfigurujeme webserver pro loganalyzer. Vytvoříme soubor /etc/apache2/conf-available/loganalyzer.conf:

sudo nano /etc/apache2/conf-available/loganalyzer.conf

a vložíme do něho následující:

Alias /loganalyzer "/var/www/loganalyzer/"

<Directory /var/www/loganalyzer/>
  Options +FollowSymlinks
  AllowOverride All
  Satisfy Any

 <IfModule mod_dav.c>
  Dav off
 </IfModule>

 SetEnv HOME /var/www/loganalyzer
 SetEnv HTTP_HOME /var/www/loganalyzer

</Directory>

Uděláme link pro aktivaci a restartneme webserver:

sudo ln -s /etc/apache2/conf-available/loganalyzer.conf /etc/apache2/conf-enabled/loganalyzer.conf
sudo service apache2 restart

Upravíme parser “misc” pro potřeby Loxone. Jedná se o upravený standardní parser pro syslog. Pro každý ze sedmi typů řádku v syslogu jsem přidal MESSAGETYPE Loxone1 – 7, aby bylo jednoduché určit, která část parseru je případně třeba upravit. V současné době je upravena Loxone2 a Loxone6 – to je log s jednoduchým datumem a precisním datumem, oba odpovídající tomu, co mi posílá Loxone. Pokud se někomu objeví jiný MESSAGETYPE, je třeba odladit další část parseru

sudo nano /var/www/loganalyzer/classes/logstreamlineparsermisc.class.php

A celý obsah nahradíme tímto:

<?php
/*
        *********************************************************************
        * LogAnalyzer - http://loganalyzer.adiscon.com
        * -----------------------------------------------------------------     *
        * Loxone Smart Home Miniserver Log Parser Class 
        *********************************************************************
*/

// --- Avoid directly accessing this file! 
if ( !defined('IN_PHPLOGCON') )
{
        die('Hacking attempt');
        exit;
}
// --- 

// --- Basic Includes
require_once($gl_root_path . 'classes/enums.class.php');
require_once($gl_root_path . 'include/constants_errors.php');
require_once($gl_root_path . 'include/constants_logstream.php');
// --- 


class LogStreamLineParsermisc extends LogStreamLineParser {
//      protected $_arrProperties = null;

        // Constructor
        public function __construct () {
                return; // Nothing
        }
        public function LogStreamLineParsermisc() {
                self::__construct();
        }

        /**
        * ParseLine
        *
        * @param arrArguments array in&out: properties of interest. There can be no guarantee the logstream can actually deliver them.
        * @return integer Error stat
        */
       public function ParseLine($szLine, &$arrArguments)
        {
                // Sample (Syslog): Mar 10 14:45:44 debandre anacron[3226]: Job `cron.daily' terminated (mailing output)
                if ( preg_match("/(...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) ([a-zA-Z0-9_\-\.]{1,256}) ([A-Za-z0-9_\-\/\.]{1,32})\[(.*?)\]:(.*?)$/", $szLine, $out ) )
                {
                        $arrArguments[SYSLOG_MESSAGETYPE] = 'Loxone1';
                        // Copy parsed properties!
                        $arrArguments[SYSLOG_DATE] = GetEventTime($out[1] . " " . $out[2]);
                        $arrArguments[SYSLOG_HOST] = $out[3];
                        $arrArguments[SYSLOG_SYSLOGTAG] = $out[4];
                        $arrArguments[SYSLOG_PROCESSID] = $out[5];
                        $arrArguments[SYSLOG_MESSAGE] = $out[6];
                }
                // Sample (Syslog): Mar 10 14:45:39 debandre syslogd 1.4.1#18: restart
                else if ( preg_match("/(...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) ([a-zA-Z0-9_\-\.]{1,256}) ([A-Za-z0-9_\-\/\.]{1,32}):(.*?)$/", $szLine, $out ) )
                {
                        $arrArguments[SYSLOG_MESSAGETYPE] = 'Loxone2';
                        $loxone = $out[3]. ';'. $out[4].':'.  $out[5]. $out[6];
                        $loxone = str_replace(': ',':',$loxone);
                        $loxone = str_replace('#015','',$loxone);
                        $loxone = str_replace('#01','',$loxone);
                        $loxout = explode(';',$loxone);
                        // Copy parsed properties!
                        $arrArguments[SYSLOG_DATE] = GetEventTime($loxout[0]. ' '. $loxout[1]);
                        $arrArguments[SYSLOG_PROCESSID] = $loxout[2];
                        $arrArguments[SYSLOG_MESSAGE] = $loxout[3];
                }
                // Sample (Syslog): Mar 10 14:45:39 debandre syslogd restart
                else if ( preg_match("/(...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) ([a-zA-Z0-9_\-\.]{1,256}) ([A-Za-z0-9_\-\/\.]{1,32}) (.*?)$/", $szLine, $out ) )
                {
                        $arrArguments[SYSLOG_MESSAGETYPE] = 'Loxone3';
                        // Copy parsed properties!
                        $arrArguments[SYSLOG_DATE] = GetEventTime($out[1] . " " . $out[2]);
                        $arrArguments[SYSLOG_HOST] = $out[3];
                        $arrArguments[SYSLOG_SYSLOGTAG] = $out[4];
                        $arrArguments[SYSLOG_MESSAGE] = $out[5];
                }
                // Sample (Syslog): Mar 7 17:18:35 debandre exiting on signal 15
                else if ( preg_match("/(...)(?:.|..)([0-9]{1,2} [0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}) (.*?) (.*?)$/", $szLine, $out ) )
                {
                        $arrArguments[SYSLOG_MESSAGETYPE] = 'Loxone4';
                        // Copy parsed properties!
                        $arrArguments[SYSLOG_DATE] = GetEventTime($out[1] . " " . $out[2]);
                        $arrArguments[SYSLOG_HOST] = $out[3];
                        $arrArguments[SYSLOG_MESSAGE] = $out[4];
                }
                // Sample (RSyslog): 2008-03-28T11:07:40+01:00 localhost rger: test 1
                else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}.[0-9]{1,2}:[0-9]{1,2}) (.*?) (.*?):(.*?)$/", $szLine, $out ) )
                {
                        $arrArguments[SYSLOG_MESSAGETYPE] = 'Loxone5';
                        // Copy parsed properties!
                        $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]);
                        $arrArguments[SYSLOG_HOST] = $out[2];
                        $arrArguments[SYSLOG_SYSLOGTAG] = $out[3];
                        $arrArguments[SYSLOG_MESSAGE] = $out[4];
                }
                // Sample (RSyslog): 2017-10-24T10:37:48.680031+02:00 2017-10-24 10:37:50;Kotel - spínání;Off#015
                else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}\.[0-9]{1,6}.[0-9]{1,2}:[0-9]{1,2}) (.*?) (.*?):(.*?)$/", $szLine, $out ) )
                {
                        $arrArguments[SYSLOG_MESSAGETYPE] = 'Loxone6';
                        $loxone = $out[2]. ';'. $out[3].':'.  $out[4]. $out[5];
                        $loxone = str_replace(': ',':',$loxone);
                        $loxone = str_replace('#015','',$loxone);
                        $loxone = str_replace('#01','',$loxone);
                        $loxout = explode(';',$loxone);
                        // Copy parsed properties!
                        $arrArguments[SYSLOG_DATE] = GetEventTime($loxout[0]. ' '. $loxout[1]);
                        $arrArguments[SYSLOG_PROCESSID] = $loxout[2];
                        $arrArguments[SYSLOG_MESSAGE] = $loxout[3];
                }
                // Sample: 2008-03-28T15:17:05.480876+01:00,**NO MATCH**
                else if ( preg_match("/([0-9]{4,4}-[0-9]{1,2}-[0-9]{1,2}T[0-9]{1,2}:[0-9]{1,2}:[0-9]{1,2}\.[0-9]{1,6}.[0-9]{1,2}:[0-9]{1,2}),(.*?)$/", $szLine, $out ) )
                {
                        $arrArguments[SYSLOG_MESSAGETYPE] = 'Loxone7';
                        // Some kind of debug message or something ...
                        $arrArguments[SYSLOG_DATE] = GetEventTime($out[1]);
                        $arrArguments[SYSLOG_MESSAGE] = $out[2];
                }
                else
                {
                        if ( isset($arrArguments[SYSLOG_MESSAGE]) && strlen($arrArguments[SYSLOG_MESSAGE]) > 0 ) 
                                OutputDebugMessage("Unparseable syslog msg - '" . $arrArguments[SYSLOG_MESSAGE] . "'", DEBUG_ERROR);
                }

                // If SyslogTag is set, we check for MessageType!
                if ( isset($arrArguments[SYSLOG_SYSLOGTAG]) )
                {
                        if ( strpos($arrArguments[SYSLOG_SYSLOGTAG], "EvntSLog" ) !== false ) 
                                $arrArguments[SYSLOG_MESSAGETYPE] = IUT_NT_EventReport;
                }

                // Return success!
                return SUCCESS;
        }


}
?>

Na závěr provedeme konfiguraci. Spustíme v prohlížeči http://<log_server>/loganalyzer Načte se stránka Critical Error occured, s odkazem Click here to Install Adiscon LogAnalyzer! Kliknete na “here” a spustí se průvodce. Během konfigurace zvolíme Logline type na Miscellaneous Logfiles a Syslog file na náš Log soubor z Loxone.
Konfigurace se uloží do souboru /var/www/loganalyzer/config.php Pokud chceme udělat celý proces konfigurace znovu, stačí tento soubor vymazat a znovu jít na stránku. Po konfiguraci je třeba pro podporu českých znaků změnit v config.php parametr $CFG[‘HeaderDefaultEncoding’] na ENC_UTF8 .

Autor článku: Zmáťa