-1

tomcatログからエラー|例外を抽出しようとしています。Tomcatログには、複数行にエラーの詳細が含まれているためです。すべての新しいログエントリを私のレコードと見なしたいと思います。つまり、日付がレコードの区切り文字として機能する可能性があります。

Oct 4, 2012 4:00:38 PM org.apache.catalina.loader.WebappClassLoader loadClass
INFO: Illegal access: this web application instance has been stopped already.  Could not load com.google.common.base.Stopwatch.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.
java.lang.IllegalStateException
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1531)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)
        at com.myweb.ontest.stats.RpcInterceptor.intercept(RpcInterceptor.java:45)
        at com.myweb.ontest.platform.SupplySource$Iface$$EnhancerByCGLIB$$6b5e8142.finalize()
        at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)
        at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)
        at java.lang.ref.Finalizer.access$100(Finalizer.java:14)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)
Oct 4, 2012 4:00:38 PM Org.apache.catalina.loader .... 

awk/perlスクリプトを使用してそれを行う方法を教えてください。

ありがとう

4

3 に答える 3

1

最初に次のようにレコード間に空白行を追加します。

awk '/^[A-Z][a-z]/ && f++{print ""}1' file

そのため、空白行をレコード セパレータとして使用することで、後続の awk スクリプトで簡単に処理できます。

awk '/^[A-Z][a-z]/ && f++{print ""}1' file |
awk -v RS= -F'\n' '{print "Record #" NR; for (i=1;i<=NF;i++) print "Field #" i, "[" $i "]"}'
Record #1
Field #1 [Oct 4, 2012 4:00:38 PM org.apache.catalina.loader.WebappClassLoader loadClass]
Field #2 [INFO: Illegal access: this web application instance has been stopped already.  Could not load com.google.common.base.Stopwatch.  The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact.]
Field #3 [java.lang.IllegalStateException]
Field #4 [        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1531)]
Field #5 [        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)]
Field #6 [        at com.myweb.ontest.stats.RpcInterceptor.intercept(RpcInterceptor.java:45)]
Field #7 [        at com.myweb.ontest.platform.SupplySource$Iface$$EnhancerByCGLIB$$6b5e8142.finalize()]
Field #8 [        at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)]
Field #9 [        at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)]
Field #10 [        at java.lang.ref.Finalizer.access$100(Finalizer.java:14)]
Field #11 [        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)]
Record #2
Field #1 [Oct 7, 2012 4:00:38 PM org.apache.catalina.loader.WebappClassLoader loadClass]
Field #2 [INFO: just a dummy record]
Field #3 [java.lang.IllegalStateException]
Field #4 [        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1531)]
Field #5 [        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1491)]
Field #6 [        at com.myweb.ontest.stats.RpcInterceptor.intercept(RpcInterceptor.java:45)]
Field #7 [        at com.myweb.ontest.platform.SupplySource$Iface$$EnhancerByCGLIB$$6b5e8142.finalize()]
Field #8 [        at java.lang.ref.Finalizer.invokeFinalizeMethod(Native Method)]
Field #9 [        at java.lang.ref.Finalizer.runFinalizer(Finalizer.java:83)]
Field #10 [        at java.lang.ref.Finalizer.access$100(Finalizer.java:14)]
Field #11 [        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:160)]

出力をどのように表示したいかを投稿していないため、上記で十分な情報が得られない場合は、サンプル入力の予想される出力を投稿してください

于 2012-12-02T16:26:11.383 に答える
1

これらのエラーをMySQLデータベースに入れると仮定すると、私はこのようにします。

#!/usr/bin/perl -Tw

use strict;
use warnings;
use English qw( -no_match_vars $OS_ERROR );
use Readonly;
use DBI;

Readonly my $LOG_FILENAME => '/var/log/tomcat.log';

Readonly my $DATE_REGEX => qr{
    \w{3} \s \d+, \s        # Oct 4,
    \d{4}         \s        # 2012
    \d+:\d+:\d+   \s \w{2}  # 4:00:38 PM
}xms;

my $sth;
{
    my $dbh = DBI->connect(
        'DBI:mysql:database=errors;host=localhost',
        'error_monitor',
        '*********',
        { 'RaiseError' => 1 }
    );

    die $DBI::errstr
        if !$dbh;

    $sth = $dbh->prepare_cached( q{
        INSERT INTO error (
            date,
            text
        ) VALUES (
            ?,
            ?
        )
    } );

    die $DBI::errstr
        if !$sth;
}

my $fh;
{
    open $fh, '<', $LOG_FILENAME
        or die "open $LOG_FILENAME: $OS_ERROR";
}

my ( $count, %record ) = ( 0, () );

while ( my $line = <$fh> ) {

    if ( $line =~ m{\A ( $DATE_REGEX ) \s ( .+ ) }xms ) {

        my ( $date, $text ) = ( $1, $2 );

        if (%record) {
            $sth->execute( @record{qw( date text )} );
            %record = ();
            $count++;
        }

        @record{qw( date text )} = ( $date, $text );
    }
    elsif ( exists $record{date} ) {

        $record{text} .= $line;
    }
    else {

        warn "malformed message: $line";
    }
}

if (%record) {
    $sth->execute( @record{qw( date text )} );
    $count++;
}

close $fh
    or die "close $LOG_FILENAME: $OS_ERROR";

print "inserted $count error records\n"
    or die "print: $OS_ERROR";

__END__
于 2012-12-02T21:52:33.373 に答える
0

そしてperlでは、次のようにすることができます:-

use strict;
my $log = join('', <STDIN>);
my %entries = split(/([\r\n]*\w{3} \d+, \d+ \d+:\d+:\d+ [AP]M )/m, $log);

foreach my $key(keys %entries)
{
    print "$key\n";
    print "$entries{$key}\n";
}

上記のコードは、stdin からログ全体を読み取り、日付で分割して日付を格納し、エントリをハッシュに格納して、最後にハッシュを出力します。

于 2012-12-02T16:32:26.730 に答える