Heute ein Folgebeitrag zum Artikel Einrichten eines Syslog Servers. In diesem wurden ja einige Schritte zur Einrichtung eines Syslogservers beschrieben, der eingehende Logs in eine MySQL-Datenbank schreibt. Das ist auch soweit toll, bis auf… Bis auf die Punkte Backup und Logrotation. Im dargestellten Artikel bin ich mit keinem Wort auf einen der beiden Punkte eingegangen. Das moechte ich nun nachholen.
Warum ueberhaupt Backup und Rotation?
Die Logs die ich einsammel enthalten Details, die mir im Fall eines Problems oder Vorfalls helfen koennen benoetigte Informationen auf die Schnelle zentral zu sichten. Wenn das Ereignis, ueber das ich mich informieren moechte, nun zwei Tage zurueck liegt, mir aber am Tag vorher die Daten verloren gegangen sind (Servercrash, etc.), waere das schon doof. Daher also Backup. Und die Rotation soll einfach helfen die anfallenden Datenmengen zu begrenzen. Denn Logs von vor zwei Tagen duerften mal helfen koennen. Aber ab einem bestimmten Alter sind Logs in der Regel nicht mehr interessant. Ich habe den Zeitraum fuer mich mal auf 90 Tage festgelegt.
Die Daten, um die es mir nachfolgend geht, liegen in der Datenbank Syslog in der Tabelle SystemEvents. Um ein „richtiges“ Backup zu haben uebernehme ich taeglich die Daten vom Vortag in eine neue Tabelle, exportiere diese und sicher die dann weg.
Also fangen wir an und erstellen eine Tabelle, die die anfallenden Daten aufnehmen kann.
mysql -u root -p -e "CREATE TABLE Syslog.SystemEventsBackup LIKE Syslog.SystemEvents" Syslog
Hiermit wird in der Datenbank Syslog
die neue Tabelle SystemEventsBackup
erstellt, die die gleichen Eigenschaften wie die Tabelle SystemEvents
hat. Moechte ich nun die Daten des Vortags sichern, fuege ich diese erst einmal in meine neue Tabelle ein, nachdem ich die vorher geleert habe.
mysql -u root -p -e "TRUNCATE Syslog.SystemEventsBackup" Syslog mysql -u root -p -e "INSERT INTO Syslog.SystemEventsBackup SELECT * FROM SystemEvents WHERE datediff( curdate() , ReceivedAt ) =1" Syslog
Habe ich die Abfrage nun ausgefuehrt kann ich hergehen und die Tabelle via mysqldump
exportieren.
root@server:~# mysqldump -u root -p Syslog SystemEventsBackup > test.sql Enter password:
Prima, die Sicherung klappt schon mal. Nun noch schauen, dass die Eintraege, die aelter als 90 Tage sind, entfernt werden. Fuer einen ersten Versuch schauen wir erst mal, ob die Anfrage korrekt laueft und nehmen alles, was aelter als 10 Tage ist.
mysql -u root -p -e "SELECT * FROM SystemEvents WHERE unix_timestamp(ReceivedAt) < unix_timestamp() - 10*24*60*60" Syslog
Ist das Resultat wie wir es erwarten koennen wir aus dem SELECT ein DELETE machen. Fuer die mit den schnellen Finger. Hiernach sind die Daten erst mal weg.
mysql -u root -p -e "DELETE FROM SystemEvents WHERE unix_timestamp(ReceivedAt) < unix_timestamp() - 10*24*60*60" Syslog
Somit haben wir also alles zusammen um uns ein Script zu schreiben, dass uns taeglich eine Sicherung der gestrigen Daten macht und anschliessend alle Daten in der Datenbank loescht, die aelter als 90 Tage sind.
#!/bin/bash logger -t backrotate.bash -i "Starting backrotate.bash" TIMESTAMP=$(date "+%Y%m%d-%H%M") TARGET_DIRECTORY="/var/tmp" DB_PREFIX="db." DB_USERNAME="username" DB_PASSWORD="password" DB_DATABASE="Syslog" DB_TABLE="SystemEvents" DB_BAKTABLE="SystemEventsBackup" DB_ENTRIES="`mysql -u $DB_USERNAME -p$DB_PASSWORD -e "SELECT COUNT(*) FROM SystemEvents WHERE unix_timestamp(ReceivedAt) < unix_timestamp() - 90*24*60*60" Syslog | egrep "[0-9]{1,}" -o`" logger -t backrotate.bash -i "creating backupfile" FILENAME=$TARGET_DIRECTORY/$DB_DATABASE-$TIMESTAMP.sql.bz2 mysql -u $DB_USERNAME -p$DB_PASSWORD -e "TRUNCATE $DB_BAKTABLE" $DB_DATABASE mysql -u $DB_USERNAME -p$DB_PASSWORD -e "INSERT INTO $DB_DATABASE.$DB_BAKTABLE SELECT * FROM $DB_TABLE WHERE datediff( curdate() , ReceivedAt ) =1" $DB_DATABASE mysqldump -u $DB_USERNAME -p$DB_PASSWORD $DB_DATABASE $DB_BAKTABLE | bzip2 -9 > $FILENAME logger -t backrotate.bash -i "backupfile $FILENAME created" logger -t backrotate.bash -i "deleting $DB_ENTRIES database-entries >90 days" mysql -u $DB_USERNAME -p$DB_PASSWORD -e "SELECT * FROM $DB_TABLE WHERE unix_timestamp(ReceivedAt) < unix_timestamp() - 90*24*60*60" $DB_DATABASE
Diejenigen von euch, die schon laenger mitlesen werden zu Recht anmerken, dass ich mich nicht an die eigenen Hinweis halte. Natuerlich mache ich das :) Obiger Job soll ja nur das Geruest sein. In „meiner“ Produktion habe ich das natuerlich entsprechend erweitert. ;)