AWS CloudTrailのログをGrafana Lokiに取り込んで可視化してみた

AWS CloudTrailのログをGrafana Lokiに取り込んで可視化してみた

2025.12.29
## はじめに

AWS CloudTrailのログをGrafanaで見たいな〜ってことありますよね?
一番簡単な方法としてはAthenaデータソースを利用する方法です。
これであればCloudTrailの証跡がS3に保存されているため、簡単にAmazon Athenaを使ってクエリすることができます。

しかし、毎度クエリ書くのが面倒だな〜とか、Athenaの料金が心配だな〜とか思うことがあったりなかったり。
そこで、偶然手元にGrafana Cloudの環境があったのでLokiに取り込めないかな?と思い、やってみました。

構成図

最終的な全体像はこんな感じになります。
Pasted image 20251229145720

今回はCloudTrailの証跡はS3に保存している前提で話を進めます。
S3にイベントが保存されると、それをトリガーにSQSにデータが送信されます。
CloudTrailのログにリアルタイム性は求めていないので、ある程度ログが溜まってからLambdaで処理するようにしています。
最後は、Lokiに保存されたデータをいい感じにフィルタリングしてGrafanaで見やすくします。

最終的なダッシュボード

最終的には次のようなシンプルなダッシュボードを作成します。
シンプルに表形式にしているだけですが、カラムごとにフィルタができたり、日本時間で時間軸を調整できるなど、クエリを書かなくても調査できる汎用性の高い必要十分なダッシュボードにしています。
CleanShot 2025-12-29 at 16.40.19@2x

lambda-promtail

最も重要なのはS3のデータをLokiに登録する方法です。
何かいい方法ないかな〜と探していたらGrafana Labsの公式ドキュメントにログエージェント (lambda-promtailというLambda関数)を作ってLokiに送信する仕組みが紹介されていました。
https://grafana.com/docs/grafana-cloud/monitor-infrastructure/monitor-cloud-provider/aws/logs/cloudwatch-logs/

早速リポジトリを覗いて使い方を見てみます。
https://github.com/grafana/lambda-promtail
Terraformでデプロイできるようなので今回はTerraformでデプロイします。

Terraform

汎用性の高い構成となっているので、CloudTrail用に編集しています。
サンプルコードは以下に配置しています。
ラベルはいくつかLmabda側で作成してくれるようなので、追加のラベルは作成していません。
https://github.com/yonamine-sou/terraform-cloudtrail-to-loki

作成されるリソース

Terraformで以下のリソースが作成されます。

リソース 説明
S3バケット Lambda zipを格納
IAM Role Lambda実行用(S3読み取り、SQS操作、CloudWatch Logs書き込み権限)
Lambda関数 lambda-promtail(Lokiにデータを転送するための関数)
SQS Queue S3イベントのバッファ用
SQS DLQ 失敗時のリカバリ用(14日間保持)
CloudWatch Logs Lambda用ロググループ(14日間保持)
S3 Bucket Notification CloudTrailバケットへのイベント通知設定
Lambda Event Source Mapping SQS → Lambda のトリガー設定

デプロイ手順

terraform.tfvarsを作成

まずはterraform.tfvarsを作成します。

cp terraform.tfvars.example terraform.tfvars

自身の環境に合わせて証跡が保存されているS3バケット名、Grafana LokiのURL、ユーザー名、パスワードを設定してください。

# ------------------------------------------------------------------------------
# 基本設定
# ------------------------------------------------------------------------------
aws_region = "ap-northeast-1"
prefix     = "lambda-promtail"

# ------------------------------------------------------------------------------
# Loki設定
# ------------------------------------------------------------------------------
# Grafana Cloudでurl, username, APIトークンを確認
write_address = "https://your-loki-url/loki/api/v1/push"
username      = "your-username"
password      = "your-password"

# ------------------------------------------------------------------------------
# CloudTrail S3バケット設定
# ------------------------------------------------------------------------------
cloudtrail_bucket_name = "your-cloudtrail-bucket-name"

lambda-promtail.zipのダウンロード

プリビルドのzipファイルをローカルにダウンロードします。
Terraformのデプロイ時にこのzipファイルを使ってLambda関数を作成します。

curl -L -o lambda-promtail.zip "https://grafanalabs-cf-templates.s3.amazonaws.com/lambda-promtail/lambda-promtail.zip"

デプロイ

準備が整ったらデプロイします。

terraform init
terraform plan
terraform apply

デプロイが完了すると、CloudTrailログがLokiに転送され始めます。
GrafanaのExplorerを使ってログが正しく転送されているか確認しましょう。
Grafana ExplorerでLokiのデータソースを選択して、次のクエリを実行します。

{__aws_log_type="s3_cloudtrail"}

クエリを実行すると次のようなデータが表示されるはずです。
CleanShot 2025-12-29 at 17.25.31@2x

データが表示されれば、lambda-promtailによるログ転送は正常に動作しています。
ただし、この時点では1つのカラムにCloudTrailのログ情報が詰め込まれています。
人間が読みやすい形ではないので整形する必要がありますね。

ダッシュボード作成

ダッシュボードを作成して、人間が読みやすい形に整形していきます。
Lambdaでデータを挿入する際にJSONをパースしてラベル付けしても良さそうですが、それだとコードを修正する必要があるので、他の方法でやってみます。

GrafanaにはTransformationsという機能があり、Grafana側でSQLを叩くような感じでデータを加工することができます。
この機能を使って、JSONのログをテーブル形式にしていきます。
https://grafana.com/docs/grafana/latest/visualizations/panels-visualizations/query-transform-data/transform-data/

Transformations

パネルを作成して先ほどのLokiデータソースを選択します。
次のクエリを実行して、先ほどと同じようにデータを表示します。

{__aws_log_type="s3_cloudtrail"}
| json

次にクエリの右にある「Transformations」タブを選択します。
Add another transformationをクリックして、Extract fieldsを選択します。
CleanShot 2025-12-29 at 17.37.39@2x
Extract fieldsはデータソースを選択し、そこから様々な形式でコンテンツを抽出します。
今回の場合だとlabelsフィールドをパースしたいので次のように設定します。

設定項目
Source labels
Format JSON
Replace all fields ON
Keep time OFF

Sourceはlabelsに設定します。
labelsフィールドにはCloudTrailのログがJSON形式で格納されているため、このフィールドを抽出対象として指定します。
CleanShot 2025-12-29 at 17.39.03@2x

Organize fields by name

Extract fieldsでJSONを表形式に変換できたので、さらにTransformationを追加してフィールドを整理します。
先ほどと同じようにAdd another transformationからOrganize fields by nameを追加します。
Organize fields by nameはパネル内の単一のクエリによって返されるフィールドの名前変更、並べ替え、非表示を行うことができます。

今回はCloudTrailログの中から必要なフィールドを選択して日本語で分かりやすく表示します。
以下、CloudTrailのコンソールを参考に最低限必要な情報を抽出しました。

元のフィールド名 リネーム後
eventTime イベント時間
eventName イベント名
eventID イベントID
eventSource イベントソース
eventType イベントタイプ
awsRegion リージョン
sourceIPAddress ソースIP
errorCode エラーコード
errorMessage エラーメッセージ
readOnly 読み取り専用
userIdentity_sessionContext_sessionIssuer_userName ユーザー名
userIdentity_accessKeyId アクセスキー

実際の画面だとこんな感じです。
フィールド名の左にある目のマークを押すと表示/非表示を切り替えられます。
また、右側の入力欄で表示名を変更できます。
CleanShot 2025-12-29 at 18.08.42@2x

フィルター

これでかなりいい感じになりましたが、実際CloudTrailのログを調査するとなるともうひと工夫欲しいところです。
CleanShot 2025-12-29 at 18.11.36@2x
ということで、カラムごとにフィルタリングできるようにしましょう。
パネルの編集から Table > Column filter を有効にします。
有効にするとカラム名の右にフィルタリングマークが表示されます。
CleanShot 2025-12-29 at 18.12.20@2x
これでカラムごとにフィルタリンできるようになりました。
CleanShot 2025-12-29 at 13.58.07@2x
これで調査の捗るダッシュボードの完成です。
特定のイベントの監視やトレンドを調査したい場合は別途パネルを作成してみてください。

Drilldownでもっと簡単にログの可視化をしてみる

Grafana Drilldownを使うと先ほどまでやっていたことがもっと簡単に実現できます。
Drilldownはクエリ不要で直感的にデータを探索できる機能です。
ダッシュボードの作り込みは不要だよ、サクッと可視化したいよ!という方にはこちらがおすすめです。

左のメニュー一覧から Drilldown > Logs を選択してデータソースにCloudTrailのログを取り込んだLokiを選択します。
表示される show logsをクリックします。
CleanShot 2025-12-29 at 18.20.31@2x 1
Exploreの時と同じようにログが表示されます。
画面左下を見ると、何やらフィールドを選択できるようになっています。
CleanShot 2025-12-29 at 18.23.07@2x
フィールドが一覧で表示されているので、必要なフィールドにチェックを入れるだけで右側のテーブルに追加されていきます。
順番もフィールドをドラッグ&ドロップで好きに入れ替えられます。
また標準でフィルター機能もあります。
CleanShot 2025-12-29 at 18.35.02@2x
ここに辿り着くまで1分ほど...
一切クエリを書くことなくここまで可視化できました。
もはやこれでよくないか?と思ってしまいますね

Drilldownは他のテレメトリデータと連携した調査に向いている機能だと思っていましたが、ログ単体でもこれだけ機能が揃っているので、ダッシュボードの作り込みをする必要がないならこれで十分な気がします。
ただし、データソースとして選択できるのはLoki, Tempo, MimirなどGrafana Stackに限られます。

おわりに

今回はlambda-promtailを使ってCloudTrailログをLokiに転送し、GrafanaのTransformationsで見やすく表示する方法を試してみました。
GrafanaにはAthenaのデータソースがあるし、わざわざLokiにする必要なんてあるかな?と思っていましたが、Grafanaのリッチなダッシュボードにより検索性が向上したように思います。
また、当然ですがLokiはDrilldownやAssistantなどGrafanaの機能と親和性が高いです。これらの機能を有効活用することでよりログの調査が捗ることは間違いありません。

Grafana Cloudであれば無料枠で50GBまでログを保管できるので、面白そうだなと思った方はぜひ試してみてください!

この記事をシェアする

FacebookHatena blogX

関連記事