Setting up lggr requires some surrounding tools:

  • syslog-ng (with syslog-ng-mod-sql extension module)
  • stunnel
  • mysql
  • apache

And there is a difference betweeen setting up the central lggr server and configuring the multiple clients logging to it.



First create a database logger and run the db.sql script from the doc/db.sql source into it. It will create one table and three views. After that you have to create at least two mysql users with different rights: One for writing into the tble and one for reading out of it. An example script doc/user.sql is included.

# create the following three mysql users:

# used by syslog-ng for inserting new data, referenced in /etc/syslog-ng/conf.d/08lggr.conf
GRANT INSERT,SELECT,UPDATE ON logger.* TO logger@localhost IDENTIFIED BY ‘xxx’;

# used by the web gui for normal viewing, referenced in inc/config_class.php
GRANT SELECT ON logger.* TO logviewer@localhost IDENTIFIED BY ‘xxx’;

# used by clean up cron job and for archiving, referenced in inc/adminconfig_class.php
GRANT SELECT,UPDATE,DELETE ON logger.* TO loggeradmin@localhost IDENTIFIED BY ‘xxx’;

# activate changes

Be sure to use your own strong passwords.

Change the values in the inc/config_class.php and inc/adminconfig_class.php files.


Create a file /etc/syslog-ng/conf.d/08lggr.conf containing:

options {

source s_net {
tcp( ip(“”) port(514) max-connections(20) log-iw-size(2000) );

destination d_newmysql {
session-statements(“SET NAMES ‘utf8′”)
columns(“date”, “facility”, “level”, “host”, “program”, “pid”, “message”)
values(“${R_YEAR}-${R_MONTH}-${R_DAY} ${R_HOUR}:${R_MIN}:${R_SEC}”, “$FACILITY”, “$LEVEL”, “$HOST”, “$PROGRAM”, “$PID”, “$MSGONLY”)

log {
source(s_net); source(s_src); filter(f_no_debug); destination(d_newmysql);

With that configuration syslog-ng logs its own local messages and the ones it receives via TCP from the net. As you can see we don’t just accept any external tcp connection but use some stunnel construct to only allow athenticated clients. In case of a plain internal network you might skip that step and listen on IP to get direct access.

Debian users might need some additional packages:

apt-get install syslog-ng-core syslog-ng-mod-sql
apt-get install libdbi1 libdbd-mysql

Depending on the linux/debian/syslog-ng versions you might have to enable one line within the file /etc/default/syslog-ng:



Just extract the files into your root web folder, i.e. /var/www/lggr and create a virtual host configuration. You have to adjust the database connection within inc/config_class.php to your needs. Use the read only mysql user.

To secure access to the gui it requires a configured basic authentication. In the root .htaccess file it references an example user file /var/www/webuser. Create it using some command like that:

htpasswd -c /var/www/webuser lggr

and enter a secure password.

For more security use a SSL/https connection to access the web gui.

The cache directory within lggr needs write permissions for the web user.


You need at least version 5.4, I’m developing using 5.6.23.


Creating a tunnel is somewhat more complex. You have to create a CA infrastructure with keys and certificates, distribute them to the clients and configure it correct.

For detailed information have a look at

To give some hints:

Enable the stunnel within /etc/defaults/stunnel and create a configuration file /etc/stunnel/stunnel.conf:

CAfile = /etc/stunnel/cacert.pem
CApath = /etc/stunnel/certs/

cert = /etc/stunnel/logserver_cert.pem
key = /etc/stunnel/logserver_nopwd_key.pem
pid =  /var/run/

verify = 3
debug = 5
accept =
connect =

Where ist your public external IP. Now the stunnel should listen on port 5140 to external connects and forward the decrypted connection to the local syslog tcp port. The path to your pid file might differ.



Create a file /etc/syslog-ng/conf.d/10lggr.conf with

destination d_net { tcp(“” port(514) log_fifo_size(1000)); };
log { source(s_src); destination(d_net); };


You should have these files:

  • cacert.pem (the personal root certificate of the logging server structure)
  • client_cert.pem (the signed certificate request)
  • client_npwd_key.pem (the private key for that client without password)

Reference to that files within a new configuration file /etc/stunnel/syslog.conf:

client = yes
CAfile = /etc/stunnel/cacert.pem
cert = /etc/stunnel/client_cert.pem
key = /etc/stunnel/client_nopwd_key.pem
verify = 2
debug = 5
accept =
connect =

Where the IP is the public external IP of your logging server again.

Cron jobs

You might be interested only in current log entries. To purge old messages run the admin/cron.php in hourly or daily intervals. You can create the file /etc/cron.d/lggr containing:

30 1 * * * www-data /usr/bin/php /var/www/lggr/admin/cron.php

On default it keeps the last 4 weeks of entries. Otherwise just add the hours argument to the member function call within cron.php to your needs.


To use a localized view your server must have installed the right locales. calling locale -a should list at least en_US.utf8 and maybe de_DE.utf8, add your personal translation as you wish.

19 Comments on “howto

Matthias Krannich
July 19, 2015 at 12:13 pm

Hallo, Herr Kretschmann,

vielen vielen Dank für Ihren syslog-Gui.

Ich habe ihn eben in Betrieb genommen :),

und folgendes ist mir dabei aufgefallen:

In den Installationsvorraussetzungen wäre es m.E. noch sinnvoll,
libdbd-mysql und php5-mysql mit aufzunehmen.

in den Appache-Error-Logs kommen unwahrscheinlich viele Meldungen, ein Glück, dass das nicht ins syslog kommt:

ca. 20…30 dieser Zeilen pro Web-Aktion:
[Sun Jul 19 13:50:16 2015] [error] [client] PHP Notice: Use of undefined constant ENT_SUBSTITUTE – assumed ‘ENT_SUBSTITUTE’ in /var/www/lggr/index.php on line 280
[Sun Jul 19 13:50:16 2015] [error] [client] PHP Notice: Use of undefined constant ENT_HTML5 – assumed ‘ENT_HTML5’ in /var/www/lggr/index.php on line 278

das kommt nur einmal pro Web-Aktion:
[Sun Jul 19 13:50:17 2015] [error] [client 10.xx.yy.yy] File does not exist: /var/www/img, referer: http://10.xx.xx.xx/lggr/

das kommt evtl. durch Verwendung eines absoluten Pfades:
root@zzz:/var/www/lggr# grep -r img *
css/lggr.css:.navbar-brand img {
root@zzz:/var/www/lggr# cd tpl/
root@zzz:/var/www/lggr/tpl# vi
root@zzz:/var/www/lggr/tpl# grep -r img *

Nach Anpassung ist die Fehlermeldung weg und das Icon links oben da 🙂

Eine Frage habe ich (u.a.) noch: Könnte man evtl. das Feld mit der syslog-Message größer oder “aufziehbar” machen?

Vielen Dank

Matthias Krannich
July 19, 2015 at 12:37 pm

und noch 2..3 Gedanken:

bei dem oben aufgeführten Fehlern Use of undefined constant hilft höchstwahrscheinlich ein Update auf PHP 5.4

ich mußte außerdem für das cache-Verzeichnis die Permissions hochschrauben:

/var/www/lggr# ll -d cache/
drwxr-xr-x 2 root root 4096 Jul 19 14:27 cache//

chmod 777 cache/

drwxrwxrwx 2 root root 4096 Jul 19 14:28 cache//

vorher wurden die key_ files nicht angelegt:

root@goliat5:/var/www/lggr/cache# ll
total 20
drwxrwxrwx 2 root root 4096 Jul 19 14:28 ./
drwxr-xr-x 11 root root 4096 Jul 19 14:26 ../
-rw-r–r– 1 root root 14 Jul 18 18:09 .htaccess
-rw-r–r– 1 root root 0 Jul 18 18:09 index.html
-rw-r–r– 1 www-data www-data 255 Jul 19 14:28
-rw-r–r– 1 www-data www-data 180 Jul 19 14:28

Jetzt kommt nur noch eine Meldung:
[Sun Jul 19 14:28:20 2015] [error] [client xxx PHP Notice: Undefined index: warning in /var/www/lggr/index.php on line 144, referer:

außer den sql-Abfragen.
Kann man die evtl. auch nur im debugging-Fall einschalten?

Einen schönen Start in die Woche
M. Krannich

July 28, 2015 at 9:14 am

Danke für das Ausprobieren und die Hinweise. Ich hab ein paar Sachen nun ergänzt in Doku und Code.

david morrison
October 20, 2015 at 12:23 pm

Hi all,
What version of syslog-ng are you using for this project? I currently have version 3.5.6 installed and when I attempt to start the service with the above contents of the /etc/syslog-ng/conf.d/08lggr.conf I get the following error:

syslog conf.d # service syslog-ng restart
[ ok ] Stopping system logging: syslog-ng.
[….] Starting system logging: syslog-ngError parsing afsql, syntax error, unexpected ‘{‘, expecting ‘)’ in /etc/syslog-ng/conf.d/08lggr.conf at line 20, column 20:
included from /etc/syslog-ng/syslog-ng.conf line 163, column 1

values(“${R_YEAR}-${R_MONTH}-${R_DAY} ${R_HOUR}:${R_MIN}:${R_SEC}”, “$FACILITY”, “$LEVEL”, “$HOST”, “$PROGRAM”, “$PID”, “$MSGONLY”)
any ideas?

October 29, 2015 at 12:27 pm

I’m running version 3.5.6 too. It seems you might miss the afsql module of syslog-ng itself. It can be an extra package like under debian (syslog-ng-mod-sql)

~# syslog-ng –version
syslog-ng 3.5.6
Installer-Version: 3.5.6
Revision: 3.5.6-2+b1 [@416d315] (Debian/unstable)
Compile-Date: Oct 1 2014 18:23:11
Available-Modules: tfgeoip,afsmtp,afstomp,json-plugin,afprog,afamqp,afuser,afsql,linux-kmsg-format,afmongodb,csvparser,dbparser,afsocket-notls,afsocket,redis,cryptofuncs,system-source,confgen,affile,afsocket-tls,syslogformat,basicfuncs
Enable-Debug: off
Enable-GProf: off
Enable-Memtrace: off
Enable-IPv6: on
Enable-Spoof-Source: on
Enable-TCP-Wrapper: on
Enable-Linux-Caps: on
Enable-Pcre: on

October 20, 2016 at 9:27 am

Fehlende Hinweise in diesem “How-To”:
Im Apache müssen die Module “Headers” und “Expires” aktiviert werden, sonst wird immer in der .htaccess abgebrochen!

Die Seite lies sich bei mir nicht öffnen, da immer die Fehlermeldung kam, dass die redis__class.php nicht gefunden werden kann!
Ich musste in der inc/lggr_class.php die Zeile
$this->cache = new LggrCacheRedis();
$this->cache = new LggrCacheFile();
tauschen damit das funktioniert.

Es fehlt der gesamte Ordner “contrib”, daher sieht die Seite nicht so schön aus, wie auf den Bildern und es wird nichts an Daten angezeigt:

Kai Kretschmann
October 20, 2016 at 11:36 am

Die apache module stehen bei den System-Requirements drinnen. Ebenso ist dort der Download aller Fremdquellen als contrib-Archiv verlinkt. Alternativ kann man ja auch auf die live CDN Ablagen dieser Fremd-Lins verweisen.

Das Howto hier liefert mehr das Zusammenspiel der Komponenten, nicht ihre Abhängigkeiten.

Das Redis PHP Modul ist dann optional auch nötig, wenn man diese Art von Cache nutzen möchte.

Peter Schulz
December 16, 2016 at 6:15 pm

Servus, seit geraumer Zeut produziert der syslog doppelte Einträge in der Datenbank. Dabei ist mir aufgefallen, das ich eigentlich eine Konfiguration mit fast identischen Inhalt an zwei Orte habe:

Kann das der Grund sein? Mein System ist ein Centos 6. Welche der beiden Dateien soll ich umbenennen / verschieben, das es wieder nur eine Zeile pro Event gibt?

Beste Grüße vom Bodensee,


P.S.: an sich an tolles Produkt 🙂

Kai Kretschmann
December 19, 2016 at 7:21 am

Welcher Syslog ist denn gemeint? Der auf dem zentralen Logging-Server oder der auf den Clients die zentral loggen wollen?

bei den Clients habe ich die vorhandene /etc/syslog-ng/syslog-ng.conf eigentlich nie anpassen müssen. Dort habe ich nur in /etc/syslog-ng/conf.d/ eine z.B. 10syslognet.conf ergänzt mit

destination d_net { tcp(“” port(514) log_fifo_size(1000)); };
log { source(s_src); destination(d_net); };


Und in der zentralen Konfiguration habe dagegen auch im conf.d Ordner eine eigene Konfiguration, die im wesentlichen den SQL Connect definiert und dann auch für das Logging setzt:

filter f_no_debug { not level(debug); };

destination d_newmysql {

log {
source(s_net); source(s_src); filter(f_no_debug); destination(d_newmysql);

December 18, 2016 at 1:49 pm

Genau sowas habe ich gesucht, PERFEKT! Vielen Dank dafür. 🙂
Klein, schnell, schick und ressourcenschonend. Für ca. 10 Hosts benötige ich keinen ELK Stack mit Java.

Die Installation ist zwar etwas holprig, man bekommt es aber hin. 😉
(Debian 8.6, syslog-ng 3.5.6, PHP 5.6.29, MariaDB 10.0, Apache 2.4.10)

Anpassen musste ich aber:
** /etc/syslog-ng/conf.d/08lggr.conf
– als ersten Eintrag
filter f_no_debug { not level(debug); };

– hostname anstatt hostnames

– Vorsicht beim copy & paste
die ” und ‘ neu setzen

– falls syslog-ng nicht startet, manuell im debug Modus starten, dann sieht man wo es klemmt.
$ syslog-ng -Fevd

** inc/lggr_class.php
– Redis auf File ändern
$this->cache = new LggrCacheRedis();
$this->cache = new LggrCacheFile();

** stunnel
– nicht konfiguriert

** redis
– nicht konfiguriert

December 19, 2016 at 2:36 pm

Noch einen bug gefunden:
Unter Archived wird der export link nicht gefunden. Dort ist ein / zuviel. (URL /do.php not found)

In der archived.php muss der / entfernt werden.
# , export to csv.
, export to csv.

Kai Kretschmann
December 22, 2016 at 7:27 am

Der konnte mir nicht auffallen, da ich lggr als Subdomain laufen habe, die phps also alle in der root liegen. Da macht ein / mehr effektiv nichts aus. Ich werde es beim nächsten Checkin anpassen. Danke.

Kai Kretschmann
December 19, 2016 at 7:16 am

Danke für die Anmerkungen. Es ist halt noch kein Setup wie bei großen CMS Systemen vorhanden. Aber da es sich ja eher an Sys-Admins richtet, sollte die Schwelle nicht zu hoch sein.

Und diese dusseligen Gänsefüßchen haben mich auch schon mal erwischt.

March 12, 2017 at 4:45 pm

Hab heute mal unter Debian 9 mit PHP 7 installiert, läuft auch hier problemlos!
(Debian 9.0, syslog-ng 3.8.1, PHP 7.0.16, MariaDB 10.1.21, Apache 2.4.25)

Ich verstehe nur noch nicht ganz wie das mit dem Archivieren funktioniert. 🙁
Wird das mit dem Picker beim Label aktiviert?

Kai Kretschmann
March 13, 2017 at 7:37 am

Ja, das Archivieren setzt im Datenbankeintrag nur ein Flag, damit dieser nicht nach x Wochen aufgeräumt und weggelöscht wird. Ein Klick setzt das Flag per Ajax im Hintergrund, ein weiterer Klick setzt das wieder zurück. Die Archiv-Ansicht nutzt dann dieses Flag als Filter.

July 18, 2017 at 1:20 pm


kann man die Performance noch irgendwie verbessern? Bei >600k Einträge /h geht die Statistikfunktion nicht mehr … :o)

Ausstattung sollte hoch genug, Load des Server ist nicht so groß (4 x 2,7Ghz && 32GB RAM) – CPU bei 3% & RAM bei ~50% Auslastung / 10MB/sec HDD bei 0,4ms Latenz). Gibt es stellen wo man evtl. noch dran schrauben kann? Die Suche braucht ca. 20s bis die etwas gefunden hat.

Wir haben aktuell 2 x DC, 1 Fileserver (mit File-/Zugriffs-Audit), Exchange Server sowie einen Router der Daten an den Logserver liefert.

Hat vielleicht jemand einen Tipp ob oder wie man die Leistung verbessern könnte? Das ganze läuft auf Debian 9 als VM unter VMware 6.

Danke und Gruß

Kai Kretschmann
July 27, 2017 at 10:00 am

Wenn bei der Statistik nichts kommt, würde ich erst mal versuchen die erlaubte php Laufzeit oder ggf. den erlaubten Speicher zu erhöhen, je nach Fehlermeldung, falls die zu finden ist.

Ansonsten ist das lggr Tool noch eine sehr flache DB Struktur. Da werde ich ggf. mal (wenn wieder Zeit ist) was normalisieren.

Oliver Rüßel
July 27, 2017 at 5:56 am

Guten Morgen zusammen,
ich habe versucht die Anleitung entsprechend auf RHEL7 mit httpd, MariaDB und PHP 5.6 zu adaptieren. Hat soweit auch funktioniert.
Aktuell erhalte ich beim betreten der live.php folgende Meldung
PHP Notice: Undefined variable: searchvalueprog in /var/www/html/tpl/ on line 21

Die Programm Suche an sich funktioniert. Kennt von euch jemand den Fehler ?

Kai Kretschmann
July 27, 2017 at 10:01 am

Die “Notice” kann im aktuellen Stand noch kommen. Die optionalen Argumente muss ich noch durchgehender auf Existenz abfragen. Ist mir letztens auch aufgefallen.


Leave a Reply

Your email address will not be published. Required fields are marked *