6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

改行を含むログをgrepフレンドリーにするPerlスクリプト

Posted at

1つのログメッセージ自体に改行が含まれているログファイルをgrepすると、ログメッセージの一部しか表示されません。各ログエントリーの先頭にフォーマット化されたテキストがあり、そのテキストでgrepしたときにはログメッセージ全体を見たいものです。それをなんとかするPerlスクリプトです。(なぜPerlなんか使うのかという疑問に対しては、この記事の最後に言い訳を書いておきました)

ちょっと意味が伝わりづらいと思うので、例を示します。

こんなようなログファイルがあったとします。

2023-08-09T11:27:15.418 [INFO][Thread-1]: log message message aaa
2023-08-09T11:27:15.421 [INFO][Thread-2]: log message message bbb
2023-08-09T11:27:15.422 [DEBUG][Thread-1]: SELECT
    id,
    name,
    ...

これを Thread-1 でgrepすると、こうなってしまいます。

2023-08-09T11:27:15.418 [INFO][Thread-1]: log message message aaa
2023-08-09T11:27:15.422 [DEBUG][Thread-1]: SELECT

SQLが1行目しか見れません。

ログメッセージごとにタイムスタンプやそのほかのメタ情報が先頭に付与され、そのあとにログメッセージ本体が続くフォーマットですが、ログメッセージ自体に改行が含まれると、このようにとても残念なことになります。

ログファイルを以下のように変換できれば、grepしても情報が失われずに済みます。grepする前にメタ情報を各行に追加してしまうのです。

2023-08-09T11:27:15.418 [INFO][Thread-1]: log message message aaa
2023-08-09T11:27:15.421 [INFO][Thread-2]: log message message bbb
2023-08-09T11:27:15.422 [DEBUG][Thread-1]: SELECT
2023-08-09T11:27:15.422 [DEBUG][Thread-1]|   id,
2023-08-09T11:27:15.422 [DEBUG][Thread-1]|   name,
2023-08-09T11:27:15.422 [DEBUG][Thread-1]|   ...

このログファイル変換をパイプで処理するPerlスクリプトを書きました。

Perlスクリプト

forgrep.pl などのファイル名で以下のスクリプトを作ります。

use strict;
use warnings;
use utf8;

my $currHead = "";

sub modifyLine {
    my ($line) = @_;
    chomp($line);
    if ($line =~ /^([-:\.0-9]{10}T[-:\.0-9]{12}\s+)(.*)$/) {
        $currHead = $1;
        $line = $2;
        while () {
            if ($line =~ /^(\[.+?\])(.*)$/) {
                $currHead .= $1;
                $line = $2;
            } else {
                last;
            }
        }
        if ($line =~ /^(:\s+)(.*)$/) {
            $line = $2;
        }
        return $currHead . ": " . $line;

    } else {
        return $currHead . "| " . $line;
    }
}
while(<STDIN>) {
    print modifyLine($_) . "\n";
}

使い方

$ cat log.txt | perl ./forgrep.pl | grep 'Thread-1' | less -S

lessコマンドの-Sオプションは、長い行があったときにターミナル上で折り返さずに、右にスクロールできるようにするものです。

なぜPerl?

Perlは多くの環境で使えるスクリプトです。明示的にインストールしなくても使えることが多いです。しかし、プロジェクトでメインの言語となっているケースは少ないです。プロジェクトでPerl自体のバージョン管理やパッケージ管理がされていることがないため、勝手に使ってもチームで管理しているコードと衝突することがほぼありません。なので、私はちょっとしたテキスト処理に使うスクリプトにPerlを使うことが多いです。今月私が一番書いたプログラミング言語はPerlです。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?