Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]10160[/thread]

Datei durchsuchen; Ergebnisse formatieren



<< |< 1 2 >| >> 13 Einträge, 2 Seiten
zottel500
 2007-08-21 14:15
#98465 #98465
User since
2007-08-21
6 Artikel
BenutzerIn
[default_avatar]
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
renee
 2007-08-21 14:31
#98467 #98467
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Um die "Transformation" zu erklären, müsste man genauer wissen, wie die Zeile im Logfile aussieht und wie die Zeile hinterher aussehen soll.


Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/perl

use strict; # sollte Pflicht sein, siehe auch im Wiki (FAQ)
use warnings;

my @filter = ("failure"); # hier noch weiter Filterworte eintragen
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 $!;
# gehe durch die ganze Datei
while( my $line = <$fh> ){
    chomp $line;
    # wenn eines der gesuchten Worte in der Zeile steht
    if( $line =~ /$re/ ){
        my $transformed_line = ''; # hier die Transformation machen
        print $out $transformed_line,"\n";
    }
}
close $out or die $!;
close $fh;
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
zottel500
 2007-08-21 15:11
#98471 #98471
User since
2007-08-21
6 Artikel
BenutzerIn
[default_avatar]
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 ....
zottel500
 2007-08-21 15:14
#98472 #98472
User since
2007-08-21
6 Artikel
BenutzerIn
[default_avatar]
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
renee
 2007-08-21 15:18
#98475 #98475
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
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?
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
zottel500
 2007-08-21 16:52
#98483 #98483
User since
2007-08-21
6 Artikel
BenutzerIn
[default_avatar]
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
renee
 2007-08-21 17:09
#98484 #98484
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
ungetestet...

Code (perl): (dl )
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
#!/usr/bin/perl

use strict; # sollte Pflicht sein, siehe auch im Wiki (FAQ)
use warnings;

my @filter      = ("failure"); # hier noch weiter Filterworte eintragen
my $file        = '/path/to/log.file';
my $outfile     = '/path/to/result.file';
my $application = 'ClusterService';
my $severity    = 'critical';
my @lines;

my $re = join '|', @filter;

{
    # aendere den "input_separator" (siehe perldoc perlvar)
    local $/ = "\n=====";
    open my $fh, '<', $file or die $!; 
    # gehe durch die ganze Datei
    while( my $line = <$fh> ){
        chomp $line;
        # wenn eines der gesuchten Worte in der Zeile steht
        if( $line =~ /MESSAGE: (?:$re)/ ){
            my ($timestamp) = $line =~ /=+\r?\n\w+\s\w+\s\w{3}\s\w{3}\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;
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
renee
 2007-08-21 17:16
#98485 #98485
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Mit der oben gezeigten Beispiel-Datei funktioniert das hier:
Code (perl): (dl )
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
#!/usr/bin/perl

use strict; # sollte Pflicht sein, siehe auch im Wiki (FAQ)
use warnings;

my @filter      = ("failure","bla"); # hier noch weiter Filterworte eintragen
my $file        = 'logbeispiel.txt';
my $outfile     = 'logout.txt';
my $application = 'ClusterService';
my $severity    = 'critical';
my @lines;

my $re = join '|', @filter;

{
    # aendere den "input_separator" (siehe perldoc perlvar)
    local $/ = "\n=====";
    open my $fh, '<', $file or die $!; 
    # gehe durch die ganze Datei
    while( my $line = <$fh> ){
        chomp $line;
        # wenn eines der gesuchten Worte in der Zeile steht
        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 $!;
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
zottel500
 2007-08-21 17:27
#98486 #98486
User since
2007-08-21
6 Artikel
BenutzerIn
[default_avatar]
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
renee
 2007-08-21 17:29
#98487 #98487
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Was hast Du denn in dem Array @filter stehen? Wie gesagt, das letzte was ich gepostet habe funktioniert mit den Beispieldaten einwandfrei...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
<< |< 1 2 >| >> 13 Einträge, 2 Seiten



View all threads created 2007-08-21 14:15.