【小ネタ】CloudWatchAgent timestamp_formatは設定するべき

2020.09.24

はじめに

AWSはもちろんのこと、オンプレミスでも利用できるCloudWatchAgentは、メトリクスとログを収集できます。CloudWatchAgentで収集されるログは、CloudWatchのlogsの指定されたロググループに出力されます。出力の設定は、CloudWatchAgentの設定ファイル(amazon-cloudwatch-agent.json)のlogsセクションに記述しますが、timestamp_formatを設定することでログの参照や管理がしやすくなるのでご紹介します。

ログ出力の構成

今回の構成は、EC2インスタンスからCloudwatch logsにログを収集後、S3バケットに格納します。cloudwatchlogsは、一時的に保存して参照する、長期保存はS3とするイメージです。

timestamp_format設定なしの場合

timestamp_formatは、オプションの設定なので必須のフィールドではありません。logsセクションの設定は


{
    "agent": {
        "metrics_collection_interval": 60,
        "region": "ap-northeast-1",
        "logfile": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log",
        "debug": false,
        "run_as_user": "root"
       },
       "logs": {
        "logs_collected": {
            "files": {
                "collect_list": [
                    {
                        "file_path": "/var/log/messages"
                    }
                ]
            }
        }
    }
}

これだけの設定でログを収集できます。 この設定でCloudWatchAgentサービスを再起動するとログストリームに以下のように出力されます。

CloudWatch logsのタイムスタンプは、ログストリームに書き込まれた時間、メッセージのタイムスタンプは、実際のログに書き込まれた時間です。logsセクションにtimestamp_formatフィールドがない場合、両方の値は必ずしも一致しません。数秒〜1分ほどのズレが誤差の範囲内という場合もあるかと思いますが、厄介なのがOSの定期的な再起動、予期せぬサービス停止が発生し、蓄積されたログが取り込まれるときです。CloudWatchAgentサービスが起動すると取り込まれていないログは再度取り込まれますが、CloudWatch logsのタイムスタンプが大きくズレてしまいます。 以下の図は、9/23に停止したCloudWatchAgentを9/24に起動した時のログストリームです。CloudWatch logsのタイムスタンプは9/24、メッセージのタイムスタンプは9/23とズレています。

タイムスタンプのズレで困るのが、CloudWatch logsコンソールで期間の検索とAmazon S3のエクスポートです。CloudWatch logsのタイムスタンプが抽出条件となる為、上記のようにズレた状態だと正しく抽出されません。

timestamp_format設定ありの場合

timestamp_formatを設定することでメッセージのタイムスタンプとCloudWatch logsのタイムスタンプが同じになります。先程の設定ファイルにtimestamp_formatを追記します。併せて、log_group_nameとlog_stream_nameを追記してロググループとログストリームを指定します。


{
    "agent": {
        "metrics_collection_interval": 60,
        "region": "ap-northeast-1",
        "logfile": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log",
        "debug": false,
    "run_as_user": "root"
       },
       "logs": {
        "logs_collected": {
            "files": {
                "collect_list": [
                    {
                        "file_path": "/var/log/messages",
                        "log_group_name": "/var/log/messages",
                        "log_stream_name": "{instance_id}",
                        "timestamp_format": "%b %-d %-I:%-M:%-S"
                    }
                ]
            }
        }
    }
}

timestamp_formatの形式は、ログファイル毎に異なるのでユーザーガイドを参考にしてください。 CloudWatch エージェント設定ファイル: logs セクション Amazon Linux2(x86)の/var/log/messagesの形式は、以下の通りです。

  • %b:ロケールの省略名称での月
  • %-d:10 進数での日 (ゼロ詰めなし)
  • %-I:10 進数での時間 (12 時間制) (ゼロ詰めなし)
  • %-M:10 進数での分 (ゼロ詰めなし)
  • %-S:10 進数での秒 (ゼロ詰めなし)

形式に併せてスペースやコロンで設定します。

CloudWatchサービスを再起動するとログストリームに書き込まれたログメッセージのタイムスタンプとCloudWatch logsのタイムスタンプが同じであることが確認できます。蓄積されたログが取り込まれる場合でも同様です。

CloudWatch logsコンソールで期間の検索とAmazon S3のエクスポートも正しく抽出することができます。

まとめ

timestamp_formatを設定していない場合、個人的にはデメリットが無いので設定するべきと考えます。