CloudWatch Logs でサポートされたログ取り込み時の変換機能を紐解く

CloudWatch Logs でサポートされたログ取り込み時の変換機能を紐解く

Clock Icon2025.02.20

こんにちは!クラウド事業本部コンサルティング部のたかくに(@takakuni_)です。

一昔前、 CloudWatch Logs では、ログの取り込み時にログの内容を変換(トランスフォーム)する機能がリリースされました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/11/amazon-cloudwatch-logs-transform-enrich/

この機能を利用することで、ログに含まれる特定のキー/文字列を変換し、 CloudWatch Logs Insights での検索性の向上が見込めます。

機能

取り込み変換機能には、トランスフォーマー、プロセッサ、パーサーが登場します。

トランスフォーマー

トランスフォーマーは変換機能をまとめる仕組みです。1 つのロググループに対して 1 つトランスフォーマーを設定できます。

プロセッサ

プロセッサは具体的に、どのような変換処理を行うかを設定する部分です。

次のようなプロセッサが用意されています。

  • 文字列ミューテーションプロセッサ
    • 大文字/小文字変換など
  • JSON ミューテーションプロセッサ
    • キーの追加/削除/移動/名前変更など
  • データ型コンバータプロセッサ
    • 型の変換

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation-Processors.html

パーサー

パーサーの役割はプロセッサと同じです。しかし、必要なプロセッサタイプ最初のプロセッサとも呼ばれます。文字通り、変換処理を行う順序が一番最初のプロセッサです。

パーサーの中には、プロセッサ(順序が2番目以降に)として利用可能なパーサー(Configurable Parser)も存在します。以下、AWS vended log 用にビルトインされたパーサーも用意されています。

  • parseWAF
  • parsePostgres
  • parseCloudfront
  • parseRoute53
  • parseVPC

(重要) ログの表示について

少し癖があるのですが、ログは変換前と変換後のログが保管されます。

GetLogEvents, FilterLogEvents API を実行した場合は、変換前のログが表示され、 CloudWatch Logs Insights で検索した場合は変換後のログが表示されます。

ログイベントが変換されたら、CloudWatch Logs Insights クエリを使用して、変換されたバージョンのログを表示する必要があります。 GetLogEvents アクションと FilterLogEvents アクションは、変換される前のログイベントの元のバージョンのみを返します。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation.html

コスト

CloudWatch Logs の変換機能は、ログ取り込み時の料金に含まれています。

ログの変換および拡張機能は、AWS のすべての商用リージョンでご利用いただけます。この機能は、既存の標準ログクラス取り込みの料金に含まれています。

https://aws.amazon.com/jp/about-aws/whats-new/2024/11/amazon-cloudwatch-logs-transform-enrich/

ただし、機能を利用するためには、標準ログクラスのロググループの利用が必須です。

ログ変換とエンリッチメントは、標準ログクラスのロググループでのみサポートされます。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation.html

取り込みと保管別の料金について

さらに深掘りしてみます。

CloudWatch Logs には、取り込み時の料金と保管時の料金の2パターンが発生します。

image-8.png
CloudWatch Logs と S3 にかかる料金比較 | DevelopersIOより画像引用

今回の機能は、先ほどの通り取り込み時の料金は変わらないものの、保管時の料金は増加する可能性があります。

変換はログの取り込み中にのみ行われます。既に取り込まれたログイベントを変換することはできません。変換は元に戻せません。元のログと変換されたログの両方が、同じ保持ポリシーで CloudWatch Logs に保存されます。ログ変換とエンリッチメント機能は、既存の標準ログクラスの取り込み料金に含まれています。ログストレージのコストは、変換後のログサイズに基づいており、元のログボリュームを超える可能性があります。

https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/CloudWatch-Logs-Transformation.html

たとえば変換前後のログが、以下のバイト数と仮定します。(圧縮は無視します)

  • 変換前のログ 4GB
  • 変換後のログ 2GB

収集(データインジェスト)

収集(データインジェスト)は変換前の 4GB に対して課金が発生します。

4 GB * 0.5 = 2 USD

保存 (アーカイブ)

保存は変換前、変換後、両方のログに対して課金が発生します。

(4 GB + 2 GB) * 0.03 = 0.18 USD

クエリ

すべてのログを読み込み検索したと仮定した場合、変換前、変換後、両方のログに対して課金が発生します。

(4 GB + 2 GB) * 0.005 = 0.03 USD

https://aws.amazon.com/cloudwatch/pricing/?nc1=h_ls

やってみる

それでは今回、ビルトインで用意されている AWS WAF 用のパーサーを利用して、変換機能を試してみます。

httpRequestheaders の Key, Value を検索しやすく変換します。

変換前

{
  "timestamp": 1576280412771,
  "formatVersion": 1,
  "webaclId": "arn:aws:wafv2:ap-southeast-2:111122223333:regional/webacl/STMTest/1EXAMPLE-2ARN-3ARN-4ARN-123456EXAMPLE",
  "terminatingRuleId": "STMTest_SQLi_XSS",
  "terminatingRuleType": "REGULAR",
  "action": "BLOCK",
  "terminatingRuleMatchDetails": [
    {
      "conditionType": "SQL_INJECTION",
      "sensitivityLevel": "HIGH",
      "location": "HEADER",
      "matchedData": ["10", "AND", "1"]
    }
  ],
  "httpSourceName": "-",
  "httpSourceId": "-",
  "ruleGroupList": [],
  "rateBasedRuleList": [],
  "nonTerminatingMatchingRules": [],
  "httpRequest": {
    "clientIp": "1.1.1.1",
    "country": "AU",
    "headers": [
      { "name": "Host", "value": "localhost:1989" },
      { "name": "User-Agent", "value": "curl/7.61.1" },
      { "name": "Accept", "value": "*/*" },
      { "name": "x-stm-test", "value": "10 AND 1=1" }
    ],
    "uri": "/myUri",
    "args": "",
    "httpVersion": "HTTP/1.1",
    "httpMethod": "GET",
    "requestId": "rid"
  },
  "labels": [{ "name": "value" }]
}

変換後

{
  "httpRequest": {
    "headers": {
      "Host": "localhost:1989",
      "User-Agent": "curl/7.61.1",
      "Accept": "*/*",
      "x-stm-test": "10 AND 1=1"
    },
    "clientIp": "1.1.1.1",
    "country": "AU",
    "uri": "/myUri",
    "args": "",
    "httpVersion": "HTTP/1.1",
    "httpMethod": "GET",
    "requestId": "rid"
  },
  "labels": { "name": "value" },
  "timestamp": 1576280412771,
  "formatVersion": 1,
  "webaclId": "arn:aws:wafv2:ap-southeast-2:111122223333:regional/webacl/STMTest/1EXAMPLE-2ARN-3ARN-4ARN-123456EXAMPLE",
  "terminatingRuleId": "STMTest_SQLi_XSS",
  "terminatingRuleType": "REGULAR",
  "action": "BLOCK",
  "terminatingRuleMatchDetails": [
    {
      "conditionType": "SQL_INJECTION",
      "sensitivityLevel": "HIGH",
      "location": "HEADER",
      "matchedData": ["10", "AND", "1"]
    }
  ],
  "httpSourceName": "-",
  "httpSourceId": "-",
  "ruleGroupList": [],
  "rateBasedRuleList": [],
  "nonTerminatingMatchingRules": []
}

CloudWatch Logs の設定

CloudWatch Logs 側を設定します。トランスフォーマーがありましたね。

2025-02-20 at 16.43.28-CloudWatch  ap-northeast-1.png

パーサーに WAF を選びます。

2025-02-20 at 17.04.29-CloudWatch  ap-northeast-1.png

トランスフォーマーには、最大 5 つのパーサーと、20つのプロセッサを指定できます。文字列ミューテーションプロセッサのため、大文字変換などが用意されてます。

2025-02-20 at 17.14.55-CloudWatch  ap-northeast-1 2.png

今回は純粋な WAF Parser のみ利用します。保存を押すと、トランスフォーマーが有効になっています。

2025-02-20 at 17.23.20-CloudWatch  ap-northeast-1.png

ログの確認

ログを確認しています。コンソール(GetLogEvents)で確認すると、変換前のログが表示されています。

2025-02-20 at 17.28.15-CloudWatch  ap-northeast-1.png

一方、CloudWatch Logs Insights で確認すると、変換後のロググループが表示されていますね。@message は変換前のログの内容が表示されているようでした。

2025-02-20 at 17.32.15-CloudWatch  ap-northeast-1.png

まとめ

以上、「CloudWatch Logs でサポートされたログ取り込み時の変換機能を紐解く」でした。

Lambda などで、ログ変換を頑張っていた方にとっては、嬉しかったりするのではないでしょうか。

このブログがどなたかの参考になれば幸いです。クラウド事業本部コンサルティング部のたかくに(@takakuni_)でした!

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.