Cloudwatch Logsの複数ロググループ参照に便利なツール「utern」

Cloudwatch Logsの複数ロググループ参照に便利なツール「utern」を紹介します。 複数のLambdaのログ確認したい時とか、ECSによるマイクロサービスで、複数のCloudwatch Logsグループのログを確認する時に、困ってましたが、解決すると思います。
2019.08.24

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、コカコーラ大好きカジです。

複数のLambdaのログ確認したい時とかECSによるマイクロサービスで、複数のCloudwatch Logsグループのログを確認する時に、aws cliでは面倒で困ってました。

同じ悩みを持った人いそうだなぁ...と思って調べたら解決していた人がいました。ありがとうございます。

uternとは

Cloudwatch Logsのログ参照で以下のことが行えます。(MITライセンスです。)

  • インストールが簡単
  • 複数のロググループを指定可能
  • ロググループやログストリームごとに異なる色で表示
  • 複数のログストリームを指定可能(省略すると全て)
  • 時刻指定が柔軟
  • フィルタリング

GitHub - knqyf263/utern: Multi group and stream log tailing for AWS CloudWatch Logs.

インストール

MacOSXの場合はbrewインストールが使えます。他のOSも対応してます。詳細は上記Github参照ください。

brew tap knqyf263/utern
brew install knqyf263/utern/utern

前提条件

AWS認証情報は ~/.aws/config や ~/.aws/credentials から取得するため、事前にawscliが使える必要があります。ただ、Assume Roleの場合は利用できませんでした。今後の機能アップデートに期待しています。

(私の環境の問題かもしれないので、情報ありましたらお願いします。)

簡単な使い方

まず最初に

Cloudwatchのロググループのリスト取得はaws cliを利用します。以下のコマンドでロググループが参照できることを確認してください。

$ aws logs describe-log-groups --query "logGroups[].[logGroupName]" --output text

参考例

2つの別のFargate(Nginxコンテナのタスク)から出力されたログのCloudwatch Logsロググループを用意して確認しています。

$ aws logs describe-log-groups --query "logGroups[].[logGroupName]" --output text
/ecs/logs/kaji-test-fargate1-ecs-group
/ecs/logs/kaji-test-fargate2-ecs-group

時間範囲指定

オプション「--since」「--end」で指定できます。 上記の1つの目のロググループの10分前から5分前のログを表示結果

$ utern --since 10m --end 5m '/ecs/logs/kaji-test-fargate1-ecs-group'

実行結果

ロググループ名、ログストリーム名の後ろにログがあり、Nginxのアクセスログが表示されてます。

$ utern --since 10m --end 5m '/ecs/logs/kaji-test-fargate1-ecs-group'
+ /ecs/logs/kaji-test-fargate1-ecs-group
+ /ecs/logs/kaji-test-fargate1-ecs-group › kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 (2019-08-24T19:01:18+09:00)
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:51:43 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.11.78 - - [24/Aug/2019:09:51:49 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:52:13 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
<省略>

ロググループの正規表現フィルタ

ロググループ名を正規表現で渡せます。命名規則が整っていれば楽に使えます。

ロググループに「/ecs/logs/」が含まれていて、10分前から5分前のログを表示

$ utern --since 10m --end 5m '/ecs/logs/\w'

実行結果

色付き表示なので、画像にしました。複数ロググループが色分けされて表示されてます。

ロググループ非表示

「--no-log-group」で非表示にできます。

$ utern --since 10m --end 5m --no-log-group '/ecs/logs/\w'

実行結果

色付き表示なので、画像にしました。ロググループが非表示されてます。

ログストリームの非表示

「--no-log-stream」で非表示にできます。

$ utern --since 10m --end 5m --no-log-group --no-log-stream '/ecs/logs/\w'

実行結果

+ /ecs/logs/kaji-test-fargate1-ecs-group
+ /ecs/logs/kaji-test-fargate1-ecs-group › kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 (2019-08-24T20:01:53+09:00)
+ /ecs/logs/kaji-test-fargate2-ecs-group
+ /ecs/logs/kaji-test-fargate2-ecs-group › kaji-test-fargate2/kaji-test-fargate2-container/ca46ffc0-cb69-4ec6-939a-f39500a074e2 (2019-08-24T20:01:45+09:00)
10.1.11.91 - - [24/Aug/2019:10:52:11 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:52:31 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.91 - - [24/Aug/2019:10:52:41 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:53:01 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.91 - - [24/Aug/2019:10:53:11 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:53:31 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.91 - - [24/Aug/2019:10:53:41 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:54:01 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.91 - - [24/Aug/2019:10:54:11 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:54:31 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.91 - - [24/Aug/2019:10:54:41 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:55:01 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.91 - - [24/Aug/2019:10:55:11 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:55:31 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.91 - - [24/Aug/2019:10:55:41 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:56:01 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.91 - - [24/Aug/2019:10:56:11 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:56:31 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.91 - - [24/Aug/2019:10:56:41 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.152 - - [24/Aug/2019:10:57:01 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:52:16 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.78 - - [24/Aug/2019:10:52:22 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:52:46 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.78 - - [24/Aug/2019:10:52:52 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:53:16 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:53:20 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36" "92.27.209.179"
10.1.11.78 - - [24/Aug/2019:10:53:22 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:53:46 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.78 - - [24/Aug/2019:10:53:52 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:54:16 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.78 - - [24/Aug/2019:10:54:22 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:54:46 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.78 - - [24/Aug/2019:10:54:52 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:55:16 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.78 - - [24/Aug/2019:10:55:22 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:55:46 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.78 - - [24/Aug/2019:10:55:52 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:56:16 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.78 - - [24/Aug/2019:10:56:22 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.12.249 - - [24/Aug/2019:10:56:46 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
10.1.11.78 - - [24/Aug/2019:10:56:52 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"

フィルター

「--filter」で抽出できます。以下のIPアドレスのみを抽出してみました。

utern --since 10m --end 5m --filter '10.1.12.249' '/ecs/logs/\w'

実行結果

$ utern --since 10m --end 5m --filter '10.1.12.249' '/ecs/logs/\w'
+ /ecs/logs/kaji-test-fargate1-ecs-group
+ /ecs/logs/kaji-test-fargate1-ecs-group › kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 (2019-08-24T18:58:23+09:00)
+ /ecs/logs/kaji-test-fargate2-ecs-group
+ /ecs/logs/kaji-test-fargate2-ecs-group › kaji-test-fargate2/kaji-test-fargate2-container/ca46ffc0-cb69-4ec6-939a-f39500a074e2 (2019-08-24T18:58:40+09:00)
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:48:43 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:49:13 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:49:43 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:50:13 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:50:43 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:51:13 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:51:43 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:52:13 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:52:43 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"
/ecs/logs/kaji-test-fargate1-ecs-group kaji-test-fargate1/kaji-test-fargate1-container/654202d8-2f6d-462b-bb39-74d54a4647d0 10.1.12.249 - - [24/Aug/2019:09:53:13 +0000] "GET / HTTP/1.1" 200 612 "-" "ELB-HealthChecker/2.0" "-"

まとめ

このツールの良さをわかっていただけたでしょうか? Assume Roleでも使えるようになったら、ほんとうに最高です。今後のアップデートに期待してます。

参考元

AWS CloudWatch Logsを見やすくするツールを作った - Qiita