top of page
検索
  • 執筆者の写真make

ログ検索を使い倒そう

始めに

 

みなさん、CloudWatchLogsInsight使っていますか?私は正直、ほとんど使いこなせていません。

やっていることといえば、

  1. filterでエラー文言を引っ掛ける。

  2. 期間をカスタムで見たい範囲より少し広めに取る。(ピンポイントすぎると見つからないことあるので)

  3. ヒットしたログのログストリーム名、リクエストID(Lambdaが多いので)などをメモって、改めて該当ログを通しで確認する。

のみです。

つまりはこの程度。

fields @timestamp, @message, @logStream, @log
| filter @messeage like /ERROR/
| sort @timestamp desc
| limit 20

特にこれで困ってはいないのですが、とある案件で、

  • ログをダッシュボードに出したい。

  • エラーの数を見える化したい。

といった調査・検証をすることになり、未知の領域へ一歩踏み出すことになりました。


メッセージをparseする

 

CloudWatchLogsはサービス毎に出力フォーマットの大枠が決まっています。内容は公式の以下の通り。https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData-discoverable-fields.html

決まっているものは、クエリ構文の「field」で@messageなど「@XXX」の形で指定することで取得できます。

しかし、この@messageには実際のアプリケーションで出力した内容がそのまままるごと入ることになるため、エラーの件数を集計したいみたいな場面ではちょっとそのままでは扱えません。

しかしさすがAWSさん、そこはちゃんと考えてあります。こういうときに使うのがクエリ構文の「parse」です。

parseは以下の2通りの書き方ができます。

  • glob形式

  • 正規表現形式

それぞれ説明します。


glob形式

 

ファイル検索などでよくあるやつです。

例えば、こんなメッセージがあったとします。(var/log/messagesの内容)


メッセージを見ると、一定の書式で成り立っていることがわかります。

Sep 14 09:41:23 ip-10-0-0-84 systemd[1]: Finished refresh-policy-routes@ens5.service - Refresh policy routes for ens5.

フィールド

意味

値の例

1

ログ出力した月

Sep

2

ログ出力した日

14

3

ログ出力した時刻

09:41:23

4

ログ出力したホスト

ip-10-0-0-84

5

ログ出力したプロセス名

systemd

6

ログ出力したプロセスID

1

7

出力メッセージ

Finished refresh-policy-routes@ens5.service - Refresh policy routes for ens5.

これをparseするには、

fields @timestamp, @message, @logStream, @log
| parse @message "* * * * *[*]: *" as @logmon,@logday,@logtime,@host,@process,@pid,@logmsg
| display @logmon,@logday,@logtime,@host,@process,@pid,@logmsg

でできます。アスタリスクで指定したところが順次、as以降の変数にセットされるイメージです。

みなれない「display」について、これはなくてもfieldsで選んだものとパースした結果がでてきますが、最終出力の項目をこの例のように最後に選択することができます。


正規表現形式

 

比較的単純なケースはglobで事足りますが、もっと込み入った解析が必要となる場合、正規表現にも対応しています。名前付きキャプチャグループという書き方で指定することになります。

名前付きキャプチャグループとは、以下のような形で()で括った中の正規表現にヒットするものを<>内の変数名として抜き出すものになります。

(?<変数名>正規表現)

先程のglobと同じことを正規表現で行うには、

fields @timestamp, @message |
 parse @message /(?<logmon>[^\s]+) (?<logday>[^\s]+) (?<logtime>[^\s]+) (?<host>[^\s]+) (?<process>[^\s\[\]]+)\[(?<pid>[^\s\[\]]+)\]: (?<logmsg>.+)/ |
 display logmon,logday,logtime,host,process,pid,logmsg

といった具合になります。


正規表現のところはちょっと込み入った感じで書きましたが、globでできるくらいなので、実際はもっとシンプルでも抜き出せるかもしれません。

また、glob形式と違って変数名に@がつかないです。


ログを集計する

 

ここまでで、メッセージを解析して要素ごとに分解できました。次にホスト名毎、プロセス毎の件数を取得してみたいと思います。

集計は「stats」でできます。

fields @timestamp, @message |
 parse @message /(?<logmon>[^\s]+) (?<logday>[^\s]+) (?<logtime>[^\s]+) (?<host>[^\s]+) (?<process>[^\s\[\]]+)\[(?<pid>[^\s\[\]]+)\]: (?<logmsg>.+)/ |
 stats count(*) by host,process

まとめ

 

使い倒そうと言いつつ、初歩やんけ、というツッコミがありそうですが、千里の道も一歩からということでご容赦ください。

調べてみるといろんなことができそうです。https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html

ログはトラブルシューティングで避けては通れないもの。誰かのお役に立てれば幸いです。

閲覧数:18回0件のコメント

最新記事

すべて表示

データ状態により異なるSQLを実行させたい

はじめに 近頃担当する業務は夜間バッチでのデータ更新処理が多く、特にDWH的にテーブル再構築(TRUNCATE/INSERT)のパターンを多く使用しています。 その中でSQLで処理を組み上げる時、エラー処理などで条件分岐で異なるSQLを実行したくなる事は珍しくありません。 多くのシステムでは呼び出し側でSQLの実行結果を参照し、次に実行するSQLを選択/実行していると思います。 また、SQLだけで

Quick Sightの分析のクロスアカウントコピー

はじめに 今回のブログではQuick Sightで作成した分析をクロスアカウントコピーするための方法を紹介します。 開発環境で作成した分析を本番環境にコピーしたい時などにこの方法が使えるのではないかと思います。 前提 コピー先アカウントとコピー元アカウントで同じ形のデータセットが存在する。 コピー元ではそのデータセットから作られた分析が存在する。 実施環境 今回のブログで紹介する手順はcloud9

コメント


bottom of page