日付範囲内のログ検索

日付範囲内のログ検索

私のログ ファイルは次のサンプルのようになります。

10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 14/Aug/2020:23:33:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74

以下のように日付範囲を指定して上記のエントリを検索します。

./Logsearch.sh 10/Aug/2020 13/Aug/2020

期待される結果:

10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74

これどうやってするの?


クエリのスクリプトの書き方について何かアイデアはありますか。OS は Solaris 11 です。サンプル スクリプトをいくつか提供してください。

答え1

これは標準の HTTP アクセス ログのように見えますが、grep必要な日付のパターンを一致させるために使用しないのはなぜでしょうか?

$ grep '1[0-3]/Aug/2020' access_log

10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74

grep パターン '1[0-3]/Aug/2020' は、範囲式 [0-3] を使用します。この式は、0、1、2、3 の値を取ることができる単一の文字と一致します。これを式の残りの部分と組み合わせると、10/Aug/2020、11/Aug/2020、12/Aug/2020、13/Aug/2020 が可能なパターンとして得られます。grepこれらのパターンに一致するログの行を出力します。

答え2

ミラーのような特殊な構造化テキストツールを使うこともできます(https://github.com/johnkerl/miller)を実行して

mlr --nidx then filter 'strftime(strptime($4,"%d/%b/%Y:%H:%M:%S"),"%Y-%m-%d") >="2020-08-11" && strftime(strptime($4,"%d/%b/%Y:%H:%M:%S"),"%Y-%m-%d") <="2020-08-13"' input.txt

持つため

10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74

フィルターを適用して、その間のすべて2020-08-112020-08-13

いくつかの注意点:

  • --nidx入力と出力のフォーマットを設定する(https://bit.ly/3h3UvN3
  • filterフィルターを適用するには;
  • strftime(strptime($4,"%d/%b/%Y:%H:%M:%S"),"%Y-%m-%d") >="2020-08-11"はフィルターの1つです。を使用して、4番目のフィールド( )のstrptime入力日付形式( )を設定します。を使用して、%d/%b/%Y:%H:%M:%S$4strftime%Y-%m-%d

答え3

使用(旧称 Perl_6)

~$ raku -e 'my $start_date = DateTime.new("2020-08-11").in-timezone(28800);   \
            my $stop_date  = DateTime.new("2020-08-13").in-timezone(28800);   \
            my @a = lines.map: *.words; my @b = do for @a {  \
                  .[0..2],   \
                  .[3..4].join.subst(/^ (\d**2) \/ (Aug) \/ (\d**4) \: /, {"$2-08-$0T"} )   \
                  .subst(/ (\+\d**2) (\d**2) $/, {"$0:$1"} ).DateTime,  \
                  .[5..*] }; \
            .put if .[1] ~~ $start_date .. $stop_date for @b;'   file

#または:

~$ raku -e 'my $start_date = DateTime.new("2020-08-11").in-timezone(28800);  \
            my $stop_date  = DateTime.new("2020-08-13").in-timezone(28800);  \
            my @a = lines.map(*.words).map({   \
                  .[0..2], (   \
                  .[3].subst(/^ (\d**2) \/ (Aug) \/ (\d**4) \: /, {"$2-08-$0T"} ),  \
                  .[4].subst(/ (\+\d**2) (\d**2) $ /, {"$0:$1"} )).join.DateTime,   \ 
                  .[5..*] });  \ 
            .put if .[1] ~~ $start_date .. $stop_date for @a;'   file 

上記は、Perl ファミリーのプログラミング言語の 1 つである Raku で書かれた回答です。Raku にはISO 8601DateTime オブジェクトが組み込まれています。

簡単に言うと、各行の日付/時刻はISO 8601DateTime オブジェクトに変換されます。 がそれぞれlines空白で区切られた に分割されるとwords、日付/時刻要素はゼロインデックスの列と にあります.[3]。これらはitute コマンドとed.[4]を使用して変換され、DateTime オブジェクトが作成されます。 次に、各行をテストして、その DateTime オブジェクトが目的の範囲内にあるかどうかを確認します。substjoinISO 8601$start .. $stop

サンプル入力:

10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 10/Aug/2020:23:45:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 11/Aug/2020:23:34:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 12/Aug/2020:23:45:43 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 13/Aug/2020:23:43:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 14/Aug/2020:23:33:45 +0800 "GET /eai/random.jsp HTTP/1.1" 200 74

サンプル出力(両方のコード例):

10.434.22.334 - unauthenticated 2020-08-11T23:34:45+08:00 "GET /eai/random.jsp HTTP/1.1" 200 74
10.434.22.334 - unauthenticated 2020-08-12T23:45:43+08:00 "GET /eai/random.jsp HTTP/1.1" 200 74

https://www.iso.org/iso-8601-日付と時刻の形式.html
https://docs.raku.org
https://raku.org

関連情報