CloudWatch Logsエージェント環境にCloudWatch統合エージェントへウィザードを使って設定を引き継いだ場合の挙動を確認する

2021.11.02

いわさです。

CloudWatch Logsへログを転送したい場合、エージェントを設定することで簡単にログ転送を行うことが可能です。
このエージェントには、CloudWatch Logs エージェントとCloudWatchエージェントの2種類があります。

昔はCloudWatch Logs エージェントが使われていましたが、現在はCloudWatchエージェントでログ転送もメトリクス取得も統合されています。(この記事では便宜上、前者を旧エージェント、後者を新エージェントと呼びたいと思います。)

旧エージェントが稼働している環境に新エージェントをセットアップする場合にログ転送設定を引き継ぐことが出来ます。
その際にどういう動きをするのか観察してみました。

設定はどう引き継がれるのでしょうか。
また、旧エージェントは無効化されるのでしょうか。

先にまとめ

  • 構成ウィザードを使うことでログ転送設定は引き継ぐことが出来る
  • 旧エージェントの実行は無効化されないので、停止や削除は別途行う必要がある

確認したこと

Amazon Linux2環境にApacheをセットアップしアクセスログ(/var/log/httpd/access_log)を旧エージェントで転送する環境を用意します。
その後、その環境に新エージェントを設定を引き継ぐ形で導入します。

旧エージェントセットアップ

パッケージマネージャーでawslogsをインストールします。
その後、/etc/awslogs/awslogs.confにApacheログを転送する設定を追記します。
また、東京リージョン利用のために/etc/awslogs/awscli.confのリージョンを修正します。
事前にCloudWatch Logsへの設定は不要ですが、EC2のインスタンスプロファイルには相応の権限が必要です。

sh-4.2$ sudo yum install -y awslogs
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
amzn2-core                                                                                                                                            | 3.7 kB  00:00:00
Resolving Dependencies
--> Running transaction check
---> Package awslogs.noarch 0:1.1.4-3.amzn2 will be installed
--> Processing Dependency: aws-cli-plugin-cloudwatch-logs for package: awslogs-1.1.4-3.amzn2.noarch
--> Running transaction check
---> Package aws-cli-plugin-cloudwatch-logs.noarch 0:1.4.6-1.amzn2.0.1 will be installed
--> Finished Dependency Resolution

/etc/awslogs/awslogs.conf

[/var/log/messages]
datetime_format = %b %d %H:%M:%S
file = /var/log/messages
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/messages

[/var/log/httpd/access_log]
datetime_format = [%a %b %d %H:%M:%S.%f %Y]
file = /var/log/httpd/access_log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /var/log/httpd/access_log

[/var/log/httpd/error_log]
datetime_format = [%a %b %d %H:%M:%S.%f %Y]
file = /var/log/httpd/error_log
buffer_duration = 5000
log_stream_name = {instance_id}
initial_position = start_of_file
log_group_name = /varlog/httpd/error_log

/etc/awslogs/awscli.conf

[plugins]
cwlogs = cwlogs
[default]
region = ap-northeast-1

設定完了後、awslogsdを実行し、サイトにアクセスしましょう。
少し待つとAWSマネージメントコンソール上からもCloudWatch Logsへログが転送されていることが確認出来ると思います。

sh-4.2$ sudo systemctl start awslogsd
sh-4.2$ sudo systemctl enable awslogsd.service

ログ転送されていることが確認出来ました。

新エージェントのセットアップ

次に、新エージェントをセットアップします。

今度はパッケージマネージャーでamazon-cloudwatch-agentをインストールします。
その後、amazon-cloudwatch-agent-config-wizardを実行し、対話形式でCloudWatchエージェントの設定ファイルを作成します。

その過程でCloudWatch Log Agentが使われているか問われるので、yesを選択します。(下記ハイライト部分)

sh-4.2$ sudo yum install amazon-cloudwatch-agent
Loaded plugins: extras_suggestions, langpacks, priorities, update-motd
Resolving Dependencies
--> Running transaction check
---> Package amazon-cloudwatch-agent.x86_64 0:1.247347.4-1.amzn2 will be installed
--> Finished Dependency Resolution

...省略...

sh-4.2$ sudo /opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-config-wizard

...省略...

Do you have any existing CloudWatch Log Agent (http://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/AgentReference.html) configuration file to import for migration?
1. yes
2. no
default choice: [2]:
1
What is the file path for the existing cloudwatch log agent configuration file?
default choice: [/var/awslogs/etc/awslogs.conf]
/etc/awslogs/awslogs.conf
Do you want to monitor any log files?
1. yes
2. no
default choice: [1]:
2
Saved config file to /opt/aws/amazon-cloudwatch-agent/bin/config.json successfully.

ウィザード完了後、config.jsonに選択した内容で設定がされています。

/opt/aws/amazon-cloudwatch-agent/bin/config.json

{
    "agent": {
        "metrics_collection_interval": 60,
        "run_as_user": "root"
    },
    "logs": {
        "force_flush_interval": 5,
        "logs_collected": {
            "files": {
                "collect_list": [
                    {
                        "file_path": "/var/log/httpd/access_log",
                        "log_group_name": "/var/log/httpd/access_log",
                        "log_stream_name": "{instance_id}"
                    },
                    {
                        "file_path": "",
                        "log_group_name": ""
                    },
                    {
                        "file_path": "/var/log/httpd/error_log",
                        "log_group_name": "/varlog/httpd/error_log",
                        "log_stream_name": "{instance_id}"
                    },
                    {
                        "file_path": "/var/log/messages",
                        "log_group_name": "/var/log/messages",
                        "log_stream_name": "{instance_id}",
                        "timestamp_format": "%b %d %H:%M:%S"
                    }
                ]
            }
        }
    },
    "metrics": {
        "append_dimensions": {
            "AutoScalingGroupName": "${aws:AutoScalingGroupName}",
            "ImageId": "${aws:ImageId}",
            "InstanceId": "${aws:InstanceId}",
            "InstanceType": "${aws:InstanceType}"
        },
        "metrics_collected": {
            "collectd": {
                "metrics_aggregation_interval": 60
            },
            "disk": {
                "measurement": [
                    "used_percent"
                ],
                "metrics_collection_interval": 60,
                "resources": [
                    "*"
                ]
            },
            "mem": {
                "measurement": [
                    "mem_used_percent"
                ],
                "metrics_collection_interval": 60
            },
            "statsd": {
                "metrics_aggregation_interval": 60,
                "metrics_collection_interval": 10,
                "service_address": ":8125"
            }
        }
    }
}

後述しますが、一部不正な情報とログ転送部分以外は本検証の範囲外なので一旦削除しました。
先程の構成ウィザードでSSMパラメータストアへ登録するよう最後に選択していると同じ形式でパラメータが登録されていますので不要部分を削除します。

以下のように変更しました。

SSM Parameter

{
    "agent": {
        "metrics_collection_interval": 60,
        "run_as_user": "root"
    },
    "logs": {
        "force_flush_interval": 5,
        "logs_collected": {
            "files": {
                "collect_list": [
                    {
                        "file_path": "/var/log/httpd/access_log",
                        "log_group_name": "/var/log/httpd/access_log",
                        "log_stream_name": "{instance_id}"
                    },
                    {
                        "file_path": "/var/log/httpd/error_log",
                        "log_group_name": "/varlog/httpd/error_log",
                        "log_stream_name": "{instance_id}"
                    },
                    {
                        "file_path": "/var/log/messages",
                        "log_group_name": "/var/log/messages",
                        "log_stream_name": "{instance_id}",
                        "timestamp_format": "%b %d %H:%M:%S"
                    }
                ]
            }
        }
    }
}

パッと見、旧エージェントで設定していた内容が反映されていますね。
設定後、以下を参考に、SSMからRun Commandでエージェントを起動しました。

Run Commandの実行結果が正常終了していたら、CloudWatch Logsを確認してみましょう。

同一ログが重複して出力されていますね。
予想出来ていたかもしれませんが、旧エージェントと新エージェント両方からログ転送がされている状態になっていました。
やはり構成ウィザードでは設定ファイルの生成までで、旧エージェントの停止や削除をしてくれるものではありませんでした。

旧エージェントを停止しましょう。

sudo service awslogsd stop

停止後、ログは重複出力されなくなりました。

config.jsonの調整

構成ウィザード実行後のconfig.jsonそのままだとRun Commandでのエージェント起動に失敗しました。

不要なロググループの記述がある

この部分を削除しました。

ログ転送設定以外で記述上の問題ありそう(未解決)

パース時にエラーが発生していました。
目視で確認した限りログ転送部分は問題なさそうだったので、カスタムメトリクスは今回の検証範囲には不要ということでメトリクス部分は削除しました。

さいごに

CloudWatchエージェントの導入記事はいくつかあったのですが、

Do you have any existing CloudWatch Log Agent

で、デフォルトの2.noを選択している記事が多かったので、実証は大事ということで確認してみました。
製品によっては移行ウィザードで旧製品が停止したり削除されたりするものもありますしね。
結果としては予想どおりだったかもしれません。

旧エージェントは今後廃止予定ということで賞味期限の短い記事になりそうですが、まぁ残しておくかということで記事にしておきました。