CloudWatch Embedded Metric Format(EMF)でログからカスタムメトリクスを生成する
CloudWatch Embedded Metric Format(EMF)のログ連携、JSON構造、メトリクス抽出の仕組みを理解し、PutMetricDataとの違い、IAM権限、ディメンション設計、重複配信とコスト上の注意点を学びます。
EMFが解決する課題
アプリケーション固有の処理量や処理時間をCloudWatchで監視するには、カスタムメトリクスを発行します。従来の方法では、アプリケーションからCloudWatchのPutMetricData APIを呼び出して数値を送信する一方、処理の詳細は別途ログとしてCloudWatch Logsへ送る設計が一般的でした。
この分離方式には、主に二つの課題があります。第一に、メトリクス送信のためのAPI呼び出しをアプリケーション側に実装し、認証情報や送信エラー、再試行などを扱う必要があることです。同期的なAPI呼び出しを処理経路に組み込むと、ネットワーク通信や再試行が応答時間に影響する可能性もあります。第二に、メトリクスとログが別々のデータとして届くため、メトリクスの異常を見つけた後に、対応する処理やリクエストの詳細を持つログを別に検索しなければならないことです。
**CloudWatch Embedded Metric Format(EMF)**は、メトリクスの値を構造化ログに埋め込んで出力するJSON形式です。アプリケーションはEMF形式のログイベントを出力し、CloudWatch Logsがそのイベントからメトリクスを自動抽出します。メトリクス値と処理の文脈を同じログイベントに含められるため、数値の監視と原因調査に用いる詳細ログを一体として設計できます。
EMFの処理フロー
EMFを使うアプリケーションは、仕様に沿ったJSONオブジェクトを生成し、ログとして出力します。Lambdaでは関数の標準出力がLambdaのログ機構を経由してCloudWatch Logsへ送られます。EC2などではCloudWatch Agent等を使ってログを転送できます。CloudWatch LogsがEMFイベントを受け取ると、JSON内のメトリクス指示を解釈し、指定された値をカスタムメトリクスとして発行します。一方で、イベント自体もCloudWatch Logsのログとして保持され、Logs Insightsで詳細を検索できます。
この方式では、アプリケーションがメトリクス専用のPutMetricData呼び出しを直接実装する代わりに、ログ送信経路を利用します。EMFログをCloudWatch Logsへ取り込む権限は必要ですが、EMFからメトリクスを生成するためだけにcloudwatch:PutMetricDataをアプリケーションへ付与する必要はありません。Lambdaでは標準出力がCloudWatch Logsへ送信されるため、EMF出力にログエージェントを追加する必要はありません。EC2等では、ログをCloudWatch Logsへ運ぶ手段と、そのための権限を適切に構成します。
EMF JSONの制御情報とペイロード
EMFイベントは、メッセージ全体が有効なJSONオブジェクトである必要があります。トップレベルの_awsオブジェクトには、CloudWatchにメトリクスをどう解釈させるかという制御情報を置きます。メトリクスの実数値やログに残したい詳細情報は、通常そのJSONのルート階層に置くペイロードです。メトリクス値そのものを_awsの配下に入れるのではなく、Metricsで名前を指示し、その名前と一致するルート階層の数値フィールドを抽出対象にします。
たとえば、画像変換サービスが変換時間と成功した画像数を記録するとします。以下はEMFの構造を示す例です。
{
"_aws": {
"Timestamp": 1735689600000,
"CloudWatchMetrics": [
{
"Namespace": "MediaPipeline",
"Dimensions": [["Service", "Stage"]],
"Metrics": [
{ "Name": "TransformDuration", "Unit": "Milliseconds" },
{ "Name": "ImagesCompleted", "Unit": "Count" }
]
}
]
},
"Service": "ImageResizer",
"Stage": "Preview",
"TransformDuration": 184.7,
"ImagesCompleted": 6,
"jobKey": "job-7f29c",
"sourceFormat": "TIFF",
"result": "SUCCESS"
}
各要素の役割は次のとおりです。
| 要素 | 役割 | 例 |
|---|---|---|
_aws.Timestamp |
抽出するメトリクスに用いる時刻。Unixエポックからのミリ秒で指定する | 1735689600000 |
_aws.CloudWatchMetrics |
メトリクス抽出の指示を格納する配列 | 下記のディレクティブ |
Namespace |
カスタムメトリクスを分類する名前空間 | MediaPipeline |
Dimensions |
メトリクス系列を分けるルート階層のフィールド名の組 | ServiceとStage |
Metrics |
抽出するメトリクスの名前や単位を列挙する | TransformDuration、ImagesCompleted |
| ルート階層のメトリクス値 | Metricsの名前と同じキーで指定する数値 |
TransformDuration: 184.7 |
| その他のルート階層フィールド | ログに残す文脈情報。メトリクス値やディメンションとして指定しなければ、それだけでメトリクス系列の分割には使われない | jobKey、sourceFormat、result |
Namespaceは関連するカスタムメトリクスをまとめる識別子です。AWSサービスの名前空間と混同しないよう、アプリケーションやシステムの単位で独自の名前を選びます。Dimensionsには配列形式でディメンションの組を記述します。上の例では、メトリクスはService=ImageResizerとStage=Previewの組み合わせで識別されます。jobKeyのような個々の処理ごとに変わる値をディメンションへ加えると、異なる組み合わせが大量に作られ、メトリクス数や料金が急増する可能性があります。その値が高い識別力を持つ場合は、メトリクスのディメンションではなくログの文脈フィールドとして保持し、必要な処理の詳細検索に使う設計が適しています。
Metricsの各定義にはメトリクス名を指定し、必要に応じてUnitやStorageResolutionなどを指定できます。定義したメトリクス名に対応する値は、ルート階層の数値フィールドにします。Timestampはメトリクスの時刻であり、ログイベント自体のタイムスタンプと同一の役割ではありません。どの時点の測定値なのかを意図して設定します。
一つのJSONイベントには、複数のメトリクス値と文脈情報を含められます。CloudWatchMetricsに複数のディレクティブを置くこともできます。ログ本文は有効なJSON一つで構成し、JSONの前後に別のテキストを付加しないでください。また、EMFログイベントのサイズ上限はCloudWatch Logsのイベント制限に従い、最大1 MBです。
メトリクスとログを関連づけた調査
EMFで記録すると、抽出後のメトリクスはCloudWatch Metricsのグラフやアラームに利用できます。同時に、元のイベントにはメトリクスの測定値だけでなく、ジョブ識別子、入力形式、処理結果などの情報も残ります。たとえば変換時間の増加をメトリクスで検知した後、該当時間帯のログをLogs Insightsで調べ、遅延が大きかった入力形式や処理段階、失敗の有無を絞り込めます。
重要なのは、業務の集計やアラームに適した低カーディナリティの属性をディメンションに選び、個別イベントを特定する値はログの文脈情報として残すことです。ディメンションはメトリクスの系列を分割するため、値の種類が増えるほど別々のメトリクス系列が増加します。requestIdやジョブごとのIDなど、ほぼ一意な値を安易にディメンションへ含めないようにします。
ライブラリと運用上の注意
EMF JSONを手作業で組み立てると、フィールド名や型、配列の構造を誤るおそれがあります。AWSが公開するEMFクライアントライブラリを利用すれば、コードからメトリクスやディメンションを指定して、規格に合ったログを生成できます。ライブラリはCloudWatch Agentと連携でき、生成したEMFログをAgent経由でCloudWatch Logsへ送る構成にも対応します。Lambdaでは、標準出力に出したログがLambdaのログ機構によって送信されるため、Agentなしで利用できます。
設計・運用時には次の点を押さえてください。
- 送信経路とIAM権限:EMF自体はログイベントとしてCloudWatch Logsに届くことで処理されます。実行環境にはログ送信権限を与え、ログを転送するAgentやLambda実行ロールの設定も確認します。
PutMetricDataによる別送信を行わない構成では、そのAPI権限をEMFのためだけに付与する必要はありません。 - 料金:CloudWatch Logsへのログ取り込み・保存と、生成されたカスタムメトリクスの双方が課金対象です。詳細な文脈をログへ残す利点とログ量、保持期間、メトリクス系列数のバランスを取ります。
- ディメンションのカーディナリティ:一意に近いIDなどをディメンションにすると、その値の組み合わせごとにメトリクス系列が生成されます。値の種類を抑え、集計・アラームに本当に必要な属性だけを選びます。
- 配信の重複:EMFからのメトリクス抽出は少なくとも1回の配信を前提とし、同じ値が重複して届くことがあります。厳密に一度だけ記録されることを前提にした集計設計は避けてください。
- フォーマット検証:EMFのフィールド名は大文字・小文字を区別します。JSON構文、
_awsの構造、Metricsが参照する値、タイムスタンプや単位を確認します。抽出失敗の調査には、CloudWatch LogsのEMF処理に関するメトリクスも活用できます。
試験での判断ポイント
アプリケーションがカスタムメトリクスと詳細ログの両方を生成し、アプリケーション内にメトリクスAPI呼び出しを組み込まずにメトリクスを利用したい場合、EMFは有力な選択肢です。数値の発行に加えて、同じイベントの処理内容をLogs Insightsで追える点も判断材料になります。
一方、EMFを利用してもログ送信の構成、IAM権限、メトリクスの名前空間・ディメンション設計は不要になりません。また、個別の値までディメンション化するのではなく、集約に必要な属性と調査に使うログ属性を分けます。EMFはログを入口にメトリクスを抽出する仕組みであり、ログとメトリクスの双方がCloudWatch上で利用できるという関係を押さえましょう。
公式ドキュメント
重要ポイント
- ▸EMFはメトリクスの値と構造化ログを1つのJSONログイベントに含め、CloudWatch Logsへの取り込み時にカスタムメトリクスを抽出する方式である
- ▸アプリケーションはEMF形式のJSONを標準出力などへ出力し、Lambdaのログ機構やCloudWatch AgentなどがCloudWatch Logsへ運ぶ
- ▸JSONの`_aws`はNamespace、Dimensions、Metrics、タイムスタンプなど抽出方法を指示し、メトリクス値と任意の文脈情報はルート階層に置く
- ▸EMFはアプリケーションから`PutMetricData`を直接呼ばずに済み、メトリクスと原因調査用ログを関連づけて扱える
- ▸EMFにはログ取り込みと生成されたカスタムメトリクス双方の料金が発生し、高カーディナリティディメンションや重複メトリクスに注意する
このトピックの学習を完了しますか?
完了状態はいつでも切り替えられます