Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Programmieren<br />
www.linux-magazin.de Perl-Snapshot 09/2013<br />
104<br />
alle Einträge, die ursprünglich aus der<br />
Datei »nagios.debug« stammen, mit dem<br />
Eventtyp. Hängt einer Suchabfrage der<br />
Ausdruck »NOT eventtype=nagios‐chatter«<br />
an, filtert die Eventsuche das Nagios-<br />
Geplapper aus.<br />
Als Nächstes fallen mir die Logevents aus<br />
einem nächtlich laufenden Backupprozess<br />
auf. Das dabei eingesetzte »rsync«-<br />
Kommando kann offenbar einige Dateien<br />
mangels hinreichender Zugriffsrechte<br />
nicht kopieren, was jede Nacht die Logdatei<br />
»backup.all.log« vollschreibt. Ein<br />
Eventtyp namens »rsync‐chatter« soll sie<br />
ausfiltern.<br />
Um die Suchbefehle kurz zu halten, definiere<br />
ich den Eventtyp »chatter«, der mit<br />
aus »/var/log/messages«, die von fehlgeschlagenen<br />
Passworteingaben berichten<br />
und manueller Analyse bedürfen.<br />
Mit Hadoop skalieren<br />
Klar, es wäre im Einzelfall einfacher, statt<br />
des Datenwusts in »/var/log« gleich die<br />
richtige Datei »/var/log/auth.log« zu lesen.<br />
Der große Vorteil von Splunk aber ist<br />
gerade, dass es alle (!) Logfiles und sogar<br />
die ganzer Serverfarmen speichert und<br />
Suchabfragen darauf zulässt. Damit dies<br />
auch in großen Rechenzentren klappt,<br />
nutzt Splunk im Backend einen Hadoop-<br />
Cluster ([4], [5]), der die aufwändige<br />
Berechnung der Suchergebnisse auf mehrere<br />
Knoten verteilt.<br />
eventtype="nagios‐chatter" OR<br />
eventtype="rsync‐error"<br />
beide Filter kombiniert, sodass Suchanfragen<br />
nur »NOT eventtype=chatter« anhängen<br />
müssen, um mit Hilfe weiterer,<br />
beliebig erweiterbarer Filter Loggeplapper<br />
auszublenden. Übrig bleiben bloß<br />
die in Abbildung 5 gezeigten Meldungen<br />
Abbildung 5: Ohne »nagios‐chatter« und »backup‐rsync‐error« bleiben nur die wichtigen Events übrig.<br />
Listing 1: »daily‐incidents«<br />
01 #!/usr/local/bin/perl ‐w<br />
02 use strict;<br />
03 use XML::Simple;<br />
04 use LWP::UserAgent;<br />
05 use JSON qw( from_json );<br />
06 use Text::ASCIITable;<br />
07 use Net::SMTP;<br />
08 use Email::MIME;<br />
09 use File::Basename;<br />
10<br />
11 my $host = "127.0.0.1";<br />
12 my $port = 8089;<br />
13 my $login_path =<br />
14 "servicesNS/admin/search/auth/login";<br />
15 my $user = "admin";<br />
16 my $password = "changeme";<br />
17 my $from_email = 'm@perlmeister.com';<br />
18 my $to_email = $from_email;<br />
19 my $subject = 'Daily Incidents';<br />
20 my $smtp_server = 'smtp.provider.net';<br />
21<br />
22 my $ua = LWP::UserAgent‐>new( ssl_opts =><br />
23 { verify_hostname => 0 } );<br />
24<br />
25 my $resp = $ua‐>post(<br />
26 "https://$host:$port/$login_path",<br />
27 { username => $user,<br />
28 password => $password } );<br />
29<br />
30 if( $resp‐>is_error() ) {<br />
31 die "Login failed: ", $resp‐>message();<br />
32 }<br />
33<br />
34 my $data = XMLin( $resp‐>content() );<br />
35 my $key = $data‐>{ sessionKey };<br />
36<br />
37 my $header = HTTP::Headers‐>new(<br />
38 Authorization => "Splunk $key" );<br />
39 $ua‐>default_headers( $header );<br />
40<br />
41 $resp = $ua‐>post(<br />
42 "https://$host:$port/servicesNS" .<br />
43 "/admin/search/search/jobs/export",<br />
44 { search => "search fail* OR error " .<br />
45 "NOT eventtype=chatter earliest=‐24h",<br />
46 output_mode => "json",<br />
47 },<br />
48 );<br />
49<br />
50 my $t = Text::ASCIITable‐>new( {<br />
51 headingText => $subject } );<br />
52 $t‐>setCols( "date", "source", "log" );<br />
53 $t‐>setColWidth( "date", 10 );<br />
54 $t‐>setColWidth( "log", 34 );<br />
55<br />
56 for my $line ( split /\n/,<br />
57 $resp‐>content() ) {<br />
58 my $data = from_json( $line );<br />
59 next if !exists $data‐>{ result };<br />
60 my $r = $data‐>{ result };<br />
61 $t‐>addRow( $r‐>{ _time },<br />
62 basename( $r‐>{ source } ),<br />
63 $r‐>{ _raw } );<br />
64 }<br />
65<br />
66 my $smtp = Net::SMTP‐>new( $smtp_server );<br />
67<br />
68 my $email = Email::MIME‐>create(<br />
69 header_str => [<br />
70 From => $from_email,<br />
71 To => $to_email,<br />
72 Subject => $subject,<br />
73 ],<br />
74 parts => [<br />
75 Email::MIME‐>create(<br />
76 attributes => {<br />
77 content_type => "text/html",<br />
78 disposition => "inline",<br />
79 charset => "UTF‐8",<br />
80 encoding => "quoted‐printable",<br />
81 },<br />
82 body_str =><br />
83 "$t",<br />
84 )<br />
85 ],<br />
86 );<br />
87<br />
88 $smtp‐>mail( $from_email );<br />
89 $smtp‐>to( $to_email );<br />
90 $smtp‐>data();<br />
91 $smtp‐>datasend( $email‐>as_string );<br />
92 $smtp‐>dataend();<br />
93 $smtp‐>quit();