OTel Vended Metric Enrichment を有効化して既存AWSメトリクスをPromQLで参照してみた
はじめに
前編では、カスタムメトリクスをOTLPでCloudWatchに送信し、PromQLで参照する方法を紹介しました。対象は自分で送ったメトリクスに限られていました。
本記事ではOTel Vended Metric Enrichmentを使い、既存のAWSサービスメトリクスをPromQLで参照する方法を試します。
| Classic | Enrichment(本記事) | |
|---|---|---|
| 絞り込み軸 | Dimension(InstanceId, LoadBalancer等) | Dimension + リソースタグ |
| クエリ言語 | Metric Math / GetMetricData | PromQL |
| パーセンタイル | 取得時に指定(対応メトリクスのみ、p99等) | クエリ時に任意指定(histogram_quantile) |
| 追加コード | 不要 | 不要 |
OTel Vended Metric Enrichment とは
OTel Vended Metric Enrichmentを有効化すると、対応AWSサービスのClassicメトリクスについてOTel形式のメトリクスが並行して自動生成されます。EC2のCPUUtilizationやALBのTargetResponseTimeなどが対象です。Classicメトリクスはそのまま残ります。アプリケーションコードやエージェントの追加・変更は不要です。
生成されるOTelメトリクスには、リソースARN、リソースタグ、Instrumentation scopeなどのラベルが付与されます。これにより、DimensionベースのClassicメトリクスでは難しかったタグベースの絞り込みや集計がPromQLで可能になります。
コスト
EnrichmentにはClassicメトリクスの課金に加えて、追加コストが発生します。
| 項目 | 料金 |
|---|---|
| Enrichment 取り込み | $0.50/GB(非圧縮 OTLP ペイロードサイズ) |
| コンソール PromQL クエリ | 無料 |
| API PromQL クエリ | $0.01/100万サンプル |
課金対象のペイロードには、メトリクス値・名前・タイムスタンプだけでなく、全属性(タグ、ARN、Instrumentation scope等)のメタデータが含まれます。
公式の試算例(Pricing Example 25)では、EC2 500台 + RDS 50台 + ELB 100台の環境で約 $77.50/月と見積もられています。
コンソール上のPromQLクエリは無料のため、GetMetricDataで多数のメトリクスを定期ポーリングしている環境では、PromQLへの置き換えで参照コストを削減できる場合があります。ただしEnrichment取り込みコストは常に発生するため、単純に安くなるとは限りません。
事前確認: metric identity数とコスト概算
有効化はアカウント × リージョン単位で全対応リソースタイプに一括適用されます。サービス単位での選択はできません。有効化前に、自アカウントのmetric identity数を確認してコスト感を把握しておくことを推奨します。
以下のスクリプトで主要namespaceのlist-metrics件数(メトリクス名×Dimensionの組み合わせ数)を数え、公式Example 25ベースのラフ換算でコスト目安を出せます。この件数はEnrichmentの課金単位と厳密には一致しません。
#!/bin/bash
REGION="${1:-ap-northeast-1}"
ROUGH_COST_PER_METRIC=0.0097 # Pricing Example 25の月額から便宜的に逆算したラフ係数
NAMESPACES=(
AWS/EC2 AWS/ApplicationELB AWS/NetworkELB AWS/Lambda
AWS/DynamoDB AWS/SQS AWS/RDS AWS/S3 AWS/NATGateway
AWS/Firehose AWS/ECS AWS/ElastiCache AWS/Kinesis
AWS/SNS AWS/ApiGateway
)
total=0
printf "%-28s %s\n" "Namespace" "Metrics"
printf "%-28s %s\n" "----------------------------" "-------"
for ns in "${NAMESPACES[@]}"; do
# 認証エラー等は stderr に出力されるが、ここでは無視して件数 0 として扱う
count=$(aws cloudwatch list-metrics --namespace "$ns" --region "$REGION" \
--output text 2>/dev/null | grep -c '^METRICS')
if [ "$count" -gt 0 ]; then
printf "%-28s %d\n" "$ns" "$count"
fi
total=$((total + count))
done
printf "%-28s %s\n" "----------------------------" "-------"
printf "%-28s %d\n" "Total" "$total"
echo ""
echo "Enrichment cost estimate: \
$(echo "$total $ROUGH_COST_PER_METRIC" | awk '{printf "$%.2f/month", $1 * $2}')"
検証アカウント(ap-northeast-1)での実行結果です。
Namespace Metrics
---------------------------- -------
AWS/EC2 820
AWS/ApplicationELB 591
AWS/RDS 138
AWS/NATGateway 16
AWS/S3 6
AWS/Firehose 2
---------------------------- -------
Total 1573
Enrichment cost estimate: $15.26/month
有効化手順
前提条件は以下のとおりです。
- AWS CLI v2.35.6以降(
observabilityadminとcloudwatch start-otel-enrichmentに対応したバージョン。最新版推奨) - IAM権限:
observabilityadmin:StartTelemetryEnrichment、cloudwatch:StartOtelEnrichment
CLI 2コマンドで有効化します。start-telemetry-enrichmentはリソースタグをテレメトリに付与する基盤機能、start-otel-enrichmentがOTelメトリクス生成の本体です。リージョン単位の設定のため、明示的に--regionを指定しています。
REGION=ap-northeast-1
# 1. Resource tags on telemetry を有効化(タグ付与の基盤)
aws observabilityadmin start-telemetry-enrichment --region "$REGION"
# 2. OTel Enrichment を有効化(メトリクス生成の本体)
aws cloudwatch start-otel-enrichment --region "$REGION"
1つ目のコマンドの実行結果です。
{
"Status": "Running",
"AwsResourceExplorerManagedViewArn": "arn:aws:resource-explorer-2:ap-northeast-1:XXXXXXXXXXXX:managed-view/AWSManagedViewForCloudWatchTelemetryEnrichment/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
}
2つ目のコマンドは空レスポンス(正常)でした。
有効化してから約4分後にPromQLでクエリが可能になりました。タグの反映には最大3時間かかる場合があります(公式ドキュメント記載)。
PromQL でサービスメトリクスをクエリ
EC2 CPUUtilization
EC2のCPU使用率を取得します。{"メトリクス名", ラベル=...}の記法はCloudWatchのPromQL実装固有の構文です。
histogram_avg({"CPUUtilization", "@instrumentation.@name"="cloudwatch.aws/ec2"})
4台のインスタンスが返りました。
| インスタンス | CPUUtilization |
|---|---|
| i-XXXXXXXXX(otel-switch-test) | 1.27% |
| i-YYYYYYYYY | 3.20% |
| i-ZZZZZZZZZ | 6.40% |
| i-WWWWWWWWW | 7.20% |
vended metricsは ExponentialHistogram 型(delta temporality)として格納されます。CPUUtilizationのような平均値・瞬時値として扱われがちなメトリクスであっても、vended metricsではExponentialHistogram型として返るため、平均値を表示するには histogram_avg() を使います。
レスポンスに含まれる主なラベルは以下のとおりです。
| カテゴリ | ラベル例 |
|---|---|
| リソース識別 | @resource.cloud.resource_id(ARN)、InstanceId |
| アカウント/リージョン | @aws.account、@aws.region |
| タグ | @aws.tag.Name、@aws.tag.Environment、@aws.tag.Project |
| Instrumentation | @instrumentation.@name、@instrumentation.cloudwatch.source |
| メタデータ | __temporality__(delta)、__type__(ExponentialHistogram) |
ALB TargetResponseTime
同様に histogram_avg() でALBのレスポンスタイムを取得します。
histogram_avg({"TargetResponseTime", "@instrumentation.cloudwatch.source"="aws.elasticloadbalancing"})
2つのALB × AZ × TargetGroupの組み合わせで6 seriesが返りました。
| ALB | AZ | TargetGroup | 平均レスポンスタイム |
|---|---|---|---|
| ALB-A | ap-northeast-1d | TG-1 | 0.084s |
| ALB-A | ap-northeast-1a | TG-1 | 0.121s |
| ALB-A | ap-northeast-1c | TG-1 | 0.214s |
| ALB-B | ap-northeast-1c | TG-1 | 0.200s |
| ALB-B | ap-northeast-1c | TG-2 | 1.601s |
| ALB-B | ap-northeast-1d | TG-1 | 0.199s |
実測結果にはLoadBalancer、TargetGroup、AvailabilityZoneに相当するラベルが含まれ、加えて@aws.tag.*のタグラベルも付与されていました。
タグベースの絞り込み・集計
ClassicのGetMetricDataでは、LoadBalancer IDやInstanceIdなどのDimensionを指定して絞り込む必要がありました。Enrichmentでは、リソースに付けたタグで意味ベースの絞り込みが可能です。
タグで絞り込む
Project タグが ecs-express-initial のALBに絞ってTargetResponseTimeを取得します。
histogram_avg({
"TargetResponseTime",
"@instrumentation.cloudwatch.source"="aws.elasticloadbalancing",
"@aws.tag.Project"="ecs-express-initial"
})
6 seriesあった結果が、該当プロジェクトの3 seriesに絞り込まれました。
| AZ | TargetGroup | 平均レスポンスタイム |
|---|---|---|
| ap-northeast-1c | TG-1 | 0.200s |
| ap-northeast-1c | TG-2 | 1.601s |
| ap-northeast-1d | TG-1 | 0.199s |
LoadBalancerのIDを知らなくても、プロジェクトタグで意図したリソースだけを取得できます。
タグで集計する
プロジェクトごとの平均CPU使用率を集計します。
avg by ("@aws.tag.Project") (
histogram_avg({"CPUUtilization", "@instrumentation.@name"="cloudwatch.aws/ec2"})
)
検証環境ではProjectタグ未設定のインスタンス群で平均5.60% でした。
オートスケール環境での自動追従
タグベースのクエリは、オートスケールでEC2が入れ替わっても追従します。新しいインスタンスに同じタグが付与されていれば、既存のクエリがそのまま新インスタンスを拾います。ASGのタグ伝播設定(PropagateAtLaunch)やLaunch Templateでのタグ指定が前提です。
histogram_quantile — 任意パーセンタイルを後から計算
vended metricsはExponentialHistogram型で分布を保持しているため、PromQLのhistogram_quantile()でクエリ時に任意のパーセンタイルを算出できます。
histogram_quantile(0.99, {
"TargetResponseTime",
"@instrumentation.cloudwatch.source"="aws.elasticloadbalancing"
})
同じデータに対してp99を算出しました。
| ALB | AZ | TargetGroup | p99 |
|---|---|---|---|
| ALB-A | ap-northeast-1d | TG-1 | 1.211s |
| ALB-A | ap-northeast-1a | TG-1 | 0.786s |
| ALB-A | ap-northeast-1c | TG-1 | 1.019s |
| ALB-B | ap-northeast-1c | TG-1 | 0.442s |
| ALB-B | ap-northeast-1c | TG-2 | 1.541s |
| ALB-B | ap-northeast-1d | TG-1 | 0.666s |
Classicでは取得時にExtendedStatisticsでp99等を指定する必要がありますが、Enrichmentではクエリのパラメータを変えるだけでp50、p95、p99を切り替えて確認できます。
対応リソース
OTel Vended Metric Enrichmentは90以上のAWSリソースタイプ(CloudFormationリソースタイプ基準)に対応しています。本記事で実測確認したのはEC2とALBですが、検証アカウントでは以下のサービスがPromQLに出現しました。
| source ラベル | サービス | メトリクス例 |
|---|---|---|
aws.ec2 |
EC2 | CPUUtilization, NetworkIn, StatusCheckFailed |
aws.elasticloadbalancing |
ALB | TargetResponseTime, RequestCount, HealthyHostCount |
aws.dynamodb |
DynamoDB | ConsumedReadCapacityUnits, ConsumedWriteCapacityUnits |
aws.sqs |
SQS | ApproximateAgeOfOldestMessage, NumberOfMessagesSent |
aws.lambda |
Lambda | Invocations, Duration, Errors, Throttles |
aws.firehose |
Kinesis Data Firehose | DeliveryToS3.Records, IncomingBytes |
対応リソースの全リストは公式ドキュメントを参照してください。主要カテゴリの抜粋です。
- Compute: EC2, Lambda, ECS, EKS, App Runner
- Networking: ALB/NLB, NATGateway, CloudFront, Transit Gateway
- Database: RDS, DynamoDB, ElastiCache, Neptune, OpenSearch
- Storage: S3, EBS, EFS
- Messaging: SQS, SNS, Kinesis
まとめ
前編ではカスタムメトリクスの送信が前提でしたが、OTel Vended Metric Enrichmentを使えば既存のAWSサービスメトリクスもPromQLの世界に入ってきます。CLI 2コマンドで有効化するだけで、EC2やALBのメトリクスをPromQLから参照できるようになりました。
実際に触って感じたのは、タグベースの絞り込みの手軽さです。@aws.tag.Project="my-app"のようにプロジェクトタグで絞るだけで目的のリソースにたどり着け、インスタンスが入れ替わってもタグを引き継いでいれば意識する必要がありません(タグ伝播の設定が前提)。
Dimension固定のダッシュボードを多数管理している環境や、タグ単位での集計・絞り込みを多用する環境ほど恩恵が大きいと感じました。一方でEnrichment取り込みコストは規模に応じて発生するため、事前にmetric identity数でコスト感を把握したうえで、自環境で見合う効果が得られるか評価してみてください。
参考リンク






