CloudWatch エージェントをインストールしてEC2から自動ログ吐き出し

はじめに

Cloudformation から EC2 インスタンスを立てる作業をしていたのですが、自動でログを吐き出して欲しいと言われて実装したときのメモです。
今回吐き出したいログは以下。

  • /var/log/messages
  • /var/log/secure
  • scriptコマンドで吐き出されるログ

ssm はよく分かっていないので今回は使っていません。
使えるとssm経由でCloudWatch エージェントを管理できるので、もうちょっと楽にできるかもです。

必要な素材を用意

CloudWatch エージェント

公式ドキュメントからサーバのプラットフォームに応じて最新版をダウンロード。
Amazon Linux2 だと以下です。

https://s3.amazonaws.com/amazoncloudwatch-agent/amazon_linux/amd64/latest/amazon-cloudwatch-agent.rpm

今回は自アカウントのS3バケットに事前に置いておきました。

CloudWatch 用設定ファイル作成

公式ドキュメントを参考に作成。
今回はカスタムメトリクスを吐き出しとかはないので metrics セクションは不要です。
サーバ内でログが置いてある場所とCloudwatch ロググループでの吐き出し先を設定するだけです。
タイムスタンプも出してくれるのでscript側で気にすることはありません。

以下、具体例です。
ファイル名:awslogs.json

{
      "agent": {
        "run_as_user": "root",
        "region": "ap-northeast-1",
        # Cloudwatch エージェント自体のログ吐き出し場所。ログ吐き出しがうまくいかないときに確認します。
        "logfile": "/opt/aws/amazon-cloudwatch-agent/logs/amazon-cloudwatch-agent.log"
      },
      "logs": {
        "logs_collected": {
          "files": {
            "collect_list": [
              {
                # サーバ内ログ配置場所
                "file_path": "/var/log/messages",
                # ログ吐き出し先 Cloudwatch ロググループ名設定
                "log_group_name": "ec2-messages.log",
                # ログ吐き出し先 Cloudwatch ログストリーム名設定
                "log_stream_name": "ec2-messages.log",
                # タイムスタンプ形式設定
                "timestamp_format": "%b %d %H:%M:%S"
              },
              ...吐き出したいログの分をそれぞれ記載
            ]
          }
        },
        # ログ吐き出し先のデフォルトになる Cloudwatch ログストリーム名設定
        "log_stream_name": "ec2"
      }
}

EC2起動時にユーザデータで自動設定するため、作成したawslogs.jsonファイルを自アカウントのS3バケットに事前に置いておきます。

ユーザデータ設定

messages、secureログは自動で出るのでscriptコマンドをユーザデータで仕込みます。
また、ユーザデータでコマンドを打ち込むときはエスケープが必要なこともあるので考慮しましょう。

以下、具体例です。

#!/bin/bash
# scriptコマンドを仕込む。
cat <<EOL >> /etc/profile
P_PROC=\`ps aux | grep \$PPID | grep sshd | awk '{ print \$11 }'\`
if [ "\$P_PROC" = sshd: ]; then
  sudo script -faq /var/log/script
  exit
fi
EOL
# 用意した CloudWatch エージェントをダウンロードしてインストール
aws s3 cp s3://バケット名/amazon-cloudwatch-agent.rpm /tmp/
rpm -U /tmp/amazon-cloudwatch-agent.rpm
# 用意した CloudWatch 用設定ファイルをダウンロード
aws s3 cp s3://バケット名/awslogs.json /tmp/
# 設定ファイルを指定して CloudWatch エージェント起動。
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl -a fetch-config -m ec2 -c file:/tmp/awslogs.json -s

ログ確認

うまくいくと CloudWatch ロググループからログを確認することができます。

f:id:rioner2525:20200703200738j:plain
設定ファイルで指定したロググループができた

f:id:rioner2525:20200703201034j:plain
scriptコマンドで操作ログも取れた

scriptコマンドの操作ログについてはエスケープシーケンスも記録されてしまうため、精査するときは整形する必要があります。

おわりに

サーバに入らなくてもログを確認できるので楽できていいなぁと思いました。
特に後でどんなコマンド打ったっけーというのがマネジメントコンソールで確認できるのが助かります。
CloudWatch エージェントは監視でよく使われますが監査用(調査用)対策としても優秀ですね。
以上です。