User since
2007-08-21
6
Artikel
BenutzerIn
Hallo,
ich benötige eine Umformatierung eines Logfiles, in eine bestimmte Form. Die formatierte Datei soll allerdings nur gewisse Zeilen enthalten, welche in dem Logfile vorkommen.
z.B. eine Zeile mit dem Wort "failure", sollte in einer bestimmten Form "<timestamp>::<application>::<severity>::<node>::<err-msg>",
in ein neues File geschrieben werden.
Da nach mehreren Wörter, als "failure", gefiltert werden müsste, habe ich mir überlegt, die Suchkriterien/Schlagworte aus einer 3ten Datei abzufragen.
Meine Kenntnisse in Perl gehen leider nicht über Grundkenntnisse hinaus. Jedoch bin ich damit der geeigneste Mitarbeiter für diese Aufgabe in meiner Firma...
Kann mir jemand eine Art Gerüst bzw. Vorgehensweise aufklamüsern, wie ich dieses Problem angehen kann? Perfekt wäre natürlich ein ähnliches Skript bzw. Anschauungsmaterial, welches man nur noch anpassen müsste. Meine Suche war bisher erfolglos:-(
Zeit zur Implementierung habe ich bis Ende der Woche.... Ich hoffe das reicht aus, um meine Kenntnisse in Perl, soweit voran zu treiben, das Problem zu lösen.
Danke für jegliche Hilfe
User since
2003-08-04
14371
Artikel
ModeratorIn
Um die "Transformation" zu erklären, müsste man genauer wissen, wie die Zeile im Logfile aussieht und wie die Zeile hinterher aussehen soll.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
use strict;
use warnings;
my @filter = ("failure");
my $file = '/path/to/log.file';
my $outfile = '/path/to/result.file';
my $re = join '|', @filter;
open my $fh, '<', $file or die $!;
open my $out, '>', $outfile or die $!;
while( my $line = <$fh> ){
chomp $line;
if( $line =~ /$re/ ){
my $transformed_line = '';
print $out $transformed_line,"\n";
}
}
close $out or die $!;
close $fh;
User since
2007-08-21
6
Artikel
BenutzerIn
Hy + Danke!
Ein Eintrag in der orig. Logfile, seiht in etwa so aus:
===================================
Info PROC Sat Sep 09 15:42:53 2006
By: FT/Agent on Node: "Hostname"
MESSAGE: the client could not connected, blabla ....
node "HOSTNAME", State = DETACHED
... auch die Zeilenumbrüche sind so in der Datei vorzufinden. Die Daten aus diesem Log müssen, dann in jene Form gepresst werden:
14:00:23::Programmname::critical::Hostname::The client could not connected, blabla ....
User since
2007-08-21
6
Artikel
BenutzerIn
nachtrag:
hab mich gar nicht bedankt! ... DANKE ...
Eines ist mir aber schon aufgefallen, wenn ich das Skript ausführe, wird die Datei zwar angelegt, ist aber leer. Sprich keine Einträge. Dieses Problem hatte ich bei meinen "Lösungen" auch.
Gruss
zottel500
User since
2003-08-04
14371
Artikel
ModeratorIn
Wie sind die Einträge getrennt? Immer durch das '======='? Wo steht der "Programmname", der in der veränderten Zeile auftauchen soll? "critical" ist fest oder ist das ein Wert, der auch irgendwo im ursprünglichen Eintrag auftaucht?
User since
2007-08-21
6
Artikel
BenutzerIn
ok, Du hast Recht...vllt. war das nicht detailiert genug. Ein paar Vorüberlegen fehlten da wohl im Weiteren auch.
hier nochmal das Log:
===================================
Error NODE Sat Sep 09 15:42:48 2006
By: FT/Agent on Node: hostname
MESSAGE: Agent on Host has failed. Ping Node results: 192.168.1.1=ALIVE
===================================
Warning SEC Sat Sep 09 15:42:48 2006
By: FT/Agent on Node: hostname
MESSAGE: bla bla bla
===================================
Info NODE Sat Sep 09 15:42:50 2006
By: FT/Agent on Node: hostname
MESSAGE: bla Agent started on host
===================================
die veränderte Zeile soll wie beschrieben aussehen. Die Werte sind z.T. statisch, zum Teil aus dem Logfile zu entnehmen.
<timestamp> steht im Log
<application> ist statisch; hier: "ClusterService" oder so
<severity> ist statisch; immer "critical"
<node> steht im Log(Hostname); also immer nach "on Node: xyz"
<err-msg> ist im Log die Message; also alles nach "MESSAGE:"
Damit das ganze so funktioniert, wie ich mir das vorstelle, sollte das Skript, die "MESSAGE-Zeile" nach Worten wie "failed", "failure", "offline" durchsuchen. Ist diese Zeile gefunden, müssten die gesuchten Werte bzw. statische Werte, nebeneinader, getrennt durch "::" in die 2te Datei geschrieben werden. Also:
14:00:23::ClusterDienst::critical::Hostname::The client could not connected, blabla ....
Puhh, is das kompliziert, da Blick ich ja beim Aufschreiben nicht mehr durch, wie das zu lösen sein soll.
Jedenfalls, allein schonmal DANKESCHÖN für Deine Mühe bis hierher!
Gruss Peter
User since
2003-08-04
14371
Artikel
ModeratorIn
Mit der oben gezeigten Beispiel-Datei funktioniert das hier:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
use strict;
use warnings;
my @filter = ("failure","bla");
my $file = 'logbeispiel.txt';
my $outfile = 'logout.txt';
my $application = 'ClusterService';
my $severity = 'critical';
my @lines;
my $re = join '|', @filter;
{
local $/ = "\n=====";
open my $fh, '<', $file or die $!;
while( my $line = <$fh> ){
chomp $line;
if( $line =~ /MESSAGE: (?:$re)/ ){
my ($timestamp) = $line =~ /\n\w+\s\w+\s\w{3}\s\w{3}\s\d{2}\s(\d+:\d+:\d+)/;
my ($hostname) = $line =~ /on Node: (\w+)/;
my ($message) = $line =~ /MESSAGE: (.*)/;
my $entry = sprintf "%s::%s::%s::%s::%s", $timestamp, $application, $severity, $hostname, $message;
push @lines, $entry;
}
}
}
open my $out, '>', $outfile or die $!;
print $out $_,"\n" for @lines;
close $out or die $!;
User since
2007-08-21
6
Artikel
BenutzerIn
hi,
Dein Skript arbeitet Fehlerfrei bzw. lässt sich ausführen. Jedoch steht nichts in der neu angelegten Datei(0kb).
Ich habe auch nen test-log angelegt, wo ich in etwa "nur" folgendes reingeschrieben habe:
on Node: host1 Fri Aug 03 13:40:05 2007
dsjkjsafjklsadkfj failure sdfjksjfjksjfsf
MESSAGE: Started process
Die Erklärung hierfür habe ich natürlich nicht ;-)
Gruss
User since
2003-08-04
14371
Artikel
ModeratorIn
Was hast Du denn in dem Array @filter stehen? Wie gesagt, das letzte was ich gepostet habe funktioniert mit den Beispieldaten einwandfrei...