Aus Linux-Magazin 09/2013

Splunk filtert verschiedene Logdaten

© srapulsar38, 123RF

Die Kunst, in einer überbordenden Menge an Logdaten die wirklich relevanten zu finden, scheint Splunk bestens zu beherrschen. Auch Perlmeister Schilli wirft seine Systemmeldungen dem proprietären Analysewerkzeug vor, bringt der kostenfreien Variante aber einige Enterprise-Features bei.

Um Logdaten gewaltigen Ausmaßes und noch dazu aus sehr unterschiedlichen Quellen zu analysieren, bedarf es eines entsprechend mächtigen Werkzeugs. Es soll Textmeldungen von Web- und Applikationsservern sowie von Netzwerkroutern und anderen Systemen zusammenführen, indizieren und schnelle Suchabfragen zulassen.

Das kommerzielle Splunk ([2], [3]) hat sein Können auf diesem Gebiet selbst in den Rechenzentren großer Internetfirmen bewiesen, steht aber in der Basisversion auch kostenlos für den Hausgebrauch auf gängigen Linux-Plattformen bereit. Nach der Installation startet »splunk start« den Daemon sowie das Webinterface, in dem der User das System konfigurieren und Suchabfragen loslassen darf wie auf einer Internetsuchmaschine (Abbildung 1).

Abbildung 1: Mit einem Suchkommando präsentiert Splunk die verzeichneten Fehler aus allen dynamisch importierten Logdateien.

Abbildung 1: Mit einem Suchkommando präsentiert Splunk die verzeichneten Fehler aus allen dynamisch importierten Logdateien.

Gold im Fluss

Das Verfahren stellt dem Admin alle verteilt geloggten Daten zentral und indiziert bereit. Mit der mächtigen Suchsyntax gelingen nicht nur Volltextsuchen über den Datenbestand, sondern auch fundierte statistische Analysen à la “Welche sind die zehn häufigsten URLs, die alle meine Webserver zusammen in den letzten zwei Stunden ausgeliefert haben?”.

Außerdem dämpft Splunk die Geschwätzigkeit solcher Logs, bei denen interessante Nachrichten unterzugehen drohen. Der Benutzer definiert nach und nach Ereignistypen, an denen er nicht interessiert ist, und Splunk blendet sie aus dem Ergebnis aus. Ereignistypen lassen sich wiederum in übergeordneten Suchfunktionen kombinieren, sodass selbst Splunk-Neulinge ihre Abfragen nach kurzer Einarbeitungszeit ähnlich wie echte Programmierer durch neue Filter erweitern. Wenn sie eine Weile die Sedimente im Informationsfluss gewaschen haben, kommen die handlichen Informations-Goldklumpen zutage. Vorsicht: Bereits die kostenlose Basisversion birgt alle Gefahren eines kapitalen Goldrausches.

Online PLUS

In einem Screencast demonstriert Michael Schilli das Beispiel: https://www.linux-magazin.de/plus/2013/09.

Strukturiert importiert

Die Zeilen einer Logdatei interpretiert Splunk als Events und jede der Meldungen besteht aus Feldern (Fields). Steht im Accesslog eines Webservers zum Beispiel »GET /index.html« , dann setzt Splunk das Feld »method« auf »GET« und das Feld »uri« auf »/index.html« (siehe Abbildung 2).

Es versteht von Haus aus eine Reihe von Formaten wie Syslog, die Errorlogs von Webservern oder Json, sodass der User zum strukturierten Import dieser Daten keinen Finger rühren muss. Zum Importieren lokaler Logdateien konfiguriert er im Menü »Add data« nur ein Verzeichnis wie »/var/log« (Abbildung 3), woraufhin sich der Splunk-Indexer alle darunterliegenden Dateien einverleibt. Ändern sich diese dynamisch, schnappt sich der Splunk-Daemon auch die neuen Einträge, Suchabfragen berücksichtigen ab sofort die neuen Informationen.

Andere Formate importiert der User, indem er Splunk zum Beispiel mittels regulärer Ausdrücke anweist die Felder aus den Events zu extrahieren. Zu den im Logeintrag existierenden Feldern fügt Splunk interne Hinweise hinzu. So definieren die Felder »source« die Datei, aus der die Information stammt (falls sie denn aus einer Datei kommt), und »host« den Server, der das Event erzeugt, also den Logeintrag angelegt hat.

Abbildung 2: Die Zeilen im Accesslog eines Webservers nimmt Splunk an ihren Feldgrenzen auseinander.

Abbildung 2: Die Zeilen im Accesslog eines Webservers nimmt Splunk an ihren Feldgrenzen auseinander.

Abbildung 3: Der einigermaßen intuitiv gestaltete Dialog »Add new« fügt hier alle Logdateien unter »/var/log« zum Splunk-Index hinzu.

Abbildung 3: Der einigermaßen intuitiv gestaltete Dialog »Add new« fügt hier alle Logdateien unter »/var/log« zum Splunk-Index hinzu.

Bei mehr als 500 MByte nur gegen Dollar

In der kostenlosen Version verdaut der Splunk-Indexer bis zu 500 MByte Rohdaten pro Tag; wer mehr einfüttert, verstößt gegen die Lizenzbedingungen, und das funktioniert höchstens drei Tage im Monat. Wer’s dennoch riskiert, dem dreht Splunk die Suchfunktion ab und zwingt ihn so zum Erwerb einer Enterprise-Version. Deren Preis ist beachtlich hoch, insbesondere große Datenmengen reißen auch große Löcher ins Budget. Im Silicon Valley ist zu hören, dass Splunk trotzdem viele Großfirmen als Kunden habe, da der Nutzen, Nadeln in einem absurd großen Heuhaufen effizient zu finden, für sie sehr wertvoll sei.

Stetig verfeinert

Für diesen Snapshot habe ich Splunk zu Hause auf meinem Ubuntu-Rechner installiert. Abbildung 1 zeigt, wie ich die Logdaten von »/var/log« und per »rsync« kopierte Apache-Accesslogs meines Hostingproviders durchsuche. Ohne jeden Protest verspeist Splunk bei mir auch rotierte und gezipte Logs.

Als erste Suchabfrage gebe ich »fail* OR error« ein. Die Volltextsuche springt auf Meldungen an, die den Begriff »error« enthalten. (Splunk unterscheidet bei den Suchstrings Groß- und Kleinschreibung nicht, erwartet Schlüsselwörter wie »OR« aber versal.) Der reguläre Ausdruck »fail*« passt auf alle Begriffe, die mit “fail” beginnen, also auch “failed”. Ohne Schlüsselwörter verbindet Splunk die Strings mit einem logischen Und, »foo bar« findet also Logeinträge, die sowohl “foo” also auch “bar” enthalten.

Die Treffer in Abbildung 1 kommen aus dem Zeitrahmen, der rechts oben mit »last 7 days« eingestellt ist, sie stammen allesamt aus dem extrem geschwätzigen Nagios-Debuglog »nagios.debug« . Um sie auszufiltern, definiert der Dialog in Abbildung 4 den Eventtyp »nagios-chatter« mit der Suchfunktion »source=…/nagios.debug« (zu sehen im verdunkelten Hintergrund). Dann verbindet Splunk intern alle Einträge, die ursprünglich aus der Datei »nagios.debug« stammen, mit dem Eventtyp. Hängt einer Suchabfrage der Ausdruck »NOT eventtype=nagios-chatter« an, filtert die Eventsuche das Nagios-Geplapper aus.

Abbildung 4: Alle Zeilen aus der Logdatei »nagios.debug« (nachzulesen im abgedunkelten Bereich) bekommen den Eventtyp »nagios-chatter« zugeordnet.

Abbildung 4: Alle Zeilen aus der Logdatei »nagios.debug« (nachzulesen im abgedunkelten Bereich) bekommen den Eventtyp »nagios-chatter« zugeordnet.

Als Nächstes fallen mir die Logevents aus einem nächtlich laufenden Backupprozess auf. Das dabei eingesetzte »rsync« -Kommando kann offenbar einige Dateien mangels hinreichender Zugriffsrechte nicht kopieren, was jede Nacht die Logdatei »backup.all.log« vollschreibt. Ein Eventtyp namens »rsync-chatter« soll sie ausfiltern.

Um die Suchbefehle kurz zu halten, definiere ich den Eventtyp »chatter« , der mit

eventtype="nagios-chatter" OR
eventtype="rsync-error"

beide Filter kombiniert, sodass Suchanfragen nur »NOT eventtype=chatter« anhängen müssen, um mit Hilfe weiterer, beliebig erweiterbarer Filter Loggeplapper auszublenden. Übrig bleiben bloß die in Abbildung 5 gezeigten Meldungen aus »/var/log/messages« , die von fehlgeschlagenen Passworteingaben berichten und manueller Analyse bedürfen.

Abbildung 5: Ohne »nagios-chatter« und »backup-rsync-error« bleiben nur die wichtigen Events übrig.

Abbildung 5: Ohne »nagios-chatter« und »backup-rsync-error« bleiben nur die wichtigen Events übrig.

Mit Hadoop skalieren

Klar, es wäre im Einzelfall einfacher, statt des Datenwusts in »/var/log« gleich die richtige Datei »/var/log/auth.log« zu lesen. Der große Vorteil von Splunk aber ist gerade, dass es alle (!) Logfiles und sogar die ganzer Serverfarmen speichert und Suchabfragen darauf zulässt. Damit dies auch in großen Rechenzentren klappt, nutzt Splunk im Backend einen Hadoop-Cluster ([4], [5]), der die aufwändige Berechnung der Suchergebnisse auf mehrere Knoten verteilt.

Die Weboberfläche lässt Endbenutzer ohne Programmierabsichten grafisch Felder auswählen und einschränkende Filter definieren. Splunk legt alle Usereingaben in Konfigurationsdateien im Splunk-Installationsverzeichnis unter »etc« dauerhaft ab (Abbildung 6). Wer seine Definitionen stetig weiterentwickelt, tut gut daran, diese Dateien mit einem Source-Control-System wie Git hin und wieder zu sichern, damit er sie nach geistigen Aussetzern zurückrollen kann.

Abbildung 6: Splunk speichert auf der Weboberfläche angelegte Definitionen in lesbaren Konfigurationsdateien ab.

Abbildung 6: Splunk speichert auf der Weboberfläche angelegte Definitionen in lesbaren Konfigurationsdateien ab.

Splunk-Alarm für Arme

Anders als die Enterprise-Version bietet die kostenlose Splunk-Variante keine Alarme, die den User benachrichtigen, falls Suchabfragen eingestellte Grenzwerte überschreiten. Sparfüchsen hält das Skript in Listing 1 den Pelz trocken, das auf demselben Rechner läuft und Splunks Web-API periodisch anzapft. Die per Json zurückgelieferten Ergebnisse verschickt es per E-Mail. So darf Splunk auch auf dem heimischen Rechner hinter einer Firewall laufen, während ein Cronjob periodisch Abfragen abfeuert und die Ergebnisse ins Internet schickt.

Zunächst muss sich das Skript gegenüber dem Splunk-REST-API identifizieren. In einer frischen Installation sind fürs Web-GUI »admin« (Kennung) und »changeme« (Passwort) voreingestellt. Das Skript führt den Login per HTTPS-Request aus. Zeile 11 definiert den »localhost« mit 127.0.0.1, Zeile 12 den Port des Splunk-Servers mit 8089. Die in Zeile 25 abgesetzte Methode »post()« schickt die Logindaten per SSL an Splunk. Da dem Useragent LWP::UserAgent keine Browserzertifikate beiliegen, setzt Zeile 22 die Option »verify_ hostname« auf 0, was die Zertifikatprüfung unterbindet.

Das Ergebnis des Login liefert Splunk als XML zurück, das die Funktion »XMLin()« aus dem CPAN-Modul XML::Simple im Skript in eine Datenstruktur umwandelt. In ihr liegt nach einer erfolgreichen Anmeldung ein Schlüssel namens »sessionKey« . Der enthält eine hexadezimale Zahl, die jeder folgenden REST-Anfrage beiliegen muss, damit Splunk sie als einem angemeldeten User zugehörig erkennt. Die Useragent-Methode »default_headers()« erledigt dies für alle folgenden Anfragen automatisch.

Das Tutorial unter [6] beschreibt die Details des REST-API. Während dem Splunk-SDK Client-Libraries für Python, Java, Javascript, PHP, Ruby und C# beiliegen, fehlt ihm ein Perl-Kit. Auf dem CPAN lagert zwar ein Modul, es arbeitet jedoch nicht mit der Splunk-Version 5 zusammen. REST-Abfragen sind zum Glück einfach zu programmieren, deshalb setzt Listing 1 auf dieser Schicht auf.

Listing 1

daily-incidents

01 #!/usr/local/bin/perl -w
02 use strict;
03 use XML::Simple;
04 use LWP::UserAgent;
05 use JSON qw( from_json );
06 use Text::ASCIITable;
07 use Net::SMTP;
08 use Email::MIME;
09 use File::Basename;
10
11 my $host        = "127.0.0.1";
12 my $port        = 8089;
13 my $login_path  =
14      "servicesNS/admin/search/auth/login";
15 my $user        = "admin";
16 my $password    = "changeme";
17 my $from_email  = 'm@perlmeister.com';
18 my $to_email    = $from_email;
19 my $subject     = 'Daily Incidents';
20 my $smtp_server = 'smtp.provider.net';
21
22 my $ua = LWP::UserAgent->new( ssl_opts =>
23   { verify_hostname => 0 } );
24
25 my $resp = $ua->post(
26   "https://$host:$port/$login_path",
27   { username => $user,
28     password => $password } );
29
30 if( $resp->is_error() ) {
31   die "Login failed: ", $resp->message();
32 }
33
34 my $data = XMLin( $resp->content() );
35 my $key  = $data->{ sessionKey };
36
37 my $header = HTTP::Headers->new(
38   Authorization => "Splunk $key" );
39 $ua->default_headers( $header );
40
41 $resp = $ua->post(
42   "https://$host:$port/servicesNS" .
43   "/admin/search/search/jobs/export",
44   { search => "search fail* OR error " .
45      "NOT eventtype=chatter earliest=-24h",
46     output_mode => "json",
47   },
48 );
49
50 my $t = Text::ASCIITable->new( {
51   headingText => $subject } );
52 $t->setCols( "date", "source", "log" );
53 $t->setColWidth( "date", 10 );
54 $t->setColWidth( "log",  34 );
55
56 for my $line ( split /\n/,
57                      $resp->content() ) {
58   my $data = from_json( $line );
59   next if !exists $data->{ result };
60   my $r = $data->{ result };
61   $t->addRow( $r->{ _time },
62               basename( $r->{ source } ),
63               $r->{ _raw } );
64 }
65
66 my $smtp = Net::SMTP->new( $smtp_server );
67
68 my $email = Email::MIME->create(
69   header_str => [
70     From    => $from_email,
71     To      => $to_email,
72     Subject => $subject,
73   ],
74   parts => [
75     Email::MIME->create(
76       attributes => {
77         content_type => "text/html",
78         disposition  => "inline",
79         charset      => "UTF-8",
80         encoding     => "quoted-printable",
81       },
82       body_str =>
83         "<html><pre>$t</pre></html>",
84     )
85   ],
86 );
87
88 $smtp->mail( $from_email );
89 $smtp->to( $to_email );
90 $smtp->data();
91 $smtp->datasend( $email->as_string );
92 $smtp->dataend();
93 $smtp->quit();

Suchen mit Fernbedienung

Die »post()« -Methode in Zeile 41 setzt eine Suche beim Splunk-Server ab. Im Gegensatz zum Web-GUI leitet »search« hier das Kommando an den Server ein. Neben dem schon erläuterten Filter »NOT eventtype=chatter« definiert es die Einschränkung »earliest=-24h« , fragt also nur nach Events der letzten 24 Stunden. Das Ergebnis möge Splunk dem Parameter »output_mode« gemäß im Json-Format liefern. Wer ellenlange E-Mails vermeiden will, sollte die Zahl der Treffer mit »limit=« auf 50 begrenzen.

Die Funktion »from_json()« aus dem CPAN-Modul JSON wandelt in Zeile 58 die Ergebnisse zeilenweise in Perl-Datenstrukturen um. Für die auszusendende Mail sind drei Felder zentral: Der Zeitstempel des Logeintrags mit dem Schlüssel »_time« , die Logdatei unter »source« und die ursprüngliche Logzeile in »_raw« . Das CPAN-Modul Net::SMTP schickt die Mail mit dem Suchergebnis an den unter »$to_email« eingetragenen Empfänger. Den SMTP-Server »$smtp_server« hat Zeile 20 vorher gesetzt.

Für Dinosaurier und Hipster

Aufwändige HTML-Nachrichten verärgern alte Zausel wie mich, die einen textbasierten E-Mail-Reader wie Pine verwenden. Umgekehrt ist für jung-dynamische Outlook- und Thunderbird-Klicker eine Plaintext-E-Mail alte Schule.

Um zwischen beiden Welten zu vermitteln, formatiert Listing 1 das tabellenartige Ergebnis der Suchanfrage mit Hilfe des CPAN-Moduls Text::ASCIITable als Ascii-Text. Damit die Zeitstempel-Spalte nicht ausufert, sondern umbrochen wird, begrenzt Zeile 53 ihre Breite auf maximal zehn Zeichen. Ähnliches gilt für die Spalte mit dem gefundenen Logeintrag, die bei einer Zeilenlänge von 34 umbricht, damit die Nachrichten auf Mobiltelefonen gut lesbar bleiben.

Moderne Mailmänner und -frauen bevorzugen dagegen HTML, und um sie zu befriedigen, ruft Zeile 68 das CPAN-Modul Email::MIME zu Hilfe. Es verpackt den vorhandenen Ascii-Text als Inline-HTML, umrankt von einfachen »pre« -Tags. So sieht das Ergebnis sowohl unter Pine (Abbildung 7) als auch mit Gmail (Abbildung 8) passabel aus.

Abbildung 8: HTML-Formatierung für moderne Mail-Leser, hier dargestellt in Gmail.

Abbildung 8: HTML-Formatierung für moderne Mail-Leser, hier dargestellt in Gmail.

Abbildung 7: Textbasierte Formatierung für einen ehrwürdigen Mailer wie Alpine.

Abbildung 7: Textbasierte Formatierung für einen ehrwürdigen Mailer wie Alpine.

Das Skript lässt sich leicht um einige Vergleiche erweitern, die gefundene Werte mit dem eingestellten Limit vergleichen und nur dann eine Mail senden, wenn der Grenzwert überschritten ist. Das kann einmal pro Tag als Zusammenfassung passieren oder im Fünf-Minuten-Takt für zügige Alarm-E-Mails.

Zu Splunk gibt es einige Open-Source-Alternativen wie Logstash ([7], [8]) und Graylog [9], die jedoch in puncto Bedienfreundlichkeit und Skalierbarkeit bislang nicht an Splunk heranreichen.

Infos

  1. Listings zu diesem Artikel: ftp://www.linux-magazin.de/pub/listings/magazin/2013/09/Perl
  2. Splunk: http://www.splunk.com
  3. Konstantin Agouros, “Nicht suchen, finden!”: Linux-Magazin 03/13, S. 60
  4. Hadoop: http://hadoop.apache.org
  5. A. Schätzle, Thomas Hornung, M. Przyjaciel-Zablocki, “Große Datenmengen mit Map Reduce und Hadoop verwalten”: Linux-Magazin 04/12, S. 38
  6. “Splunk: Intro REST API Tutorial”: http://dev.splunk.com/view/SP-CAAADQT
  7. Logstash: http://logstash.net
  8. Martin Loschwitz, “Alle Systeme im Blick”: Linux-Magazin 05/13, S. 68
  9. Graylog2: http://graylog2.org

Der Autor

Michael Schilli arbeitet als Software-Engineer bei Yahoo in Sunnyvale, Kalifornien. In seiner seit 1997 laufenden Kolumne forscht er jeden Monat nach praktischen Anwendungen der Skriptsprache Perl. Unter mailto:mschilli@perlmeister.com beantwortet er gerne Fragen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 5 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben