ApacheのログをCloudWatch Logsに保存する


概要

Apacheのエラーログを「CloudWatch Logs エージェント」を使用してCloudWatch Logsに保存します。
/var/log などに吐き出されるログをCloudWatchで管理できます。
オートスケールを使っていていると、EC2のtarminateによりログが失われる可能性があります。
そのため別の場所に保存しておく必要があります。

注意

現在「CloudWatch Logs エージェント」ではなく、「CloudWatch 統合エージェント」を使用することが推奨されています。
設定方法が違うのでご注意ください。

CloudWatch Logs エージェントを使用して、Linux または Windows Server を実行する Amazon EC2 インスタンスのログデータおよび AWS CloudTrail から記録されたイベントを発行できます。代わりに CloudWatch 統合エージェントを使用してログデータを発行することをお勧めします。
https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/logs/UsePreviousCloudWatchLogsAgent.html

環境

  • すべてAWSを使用
  • OSはAmazon Linux 2
  • Apacheのインストールはyumで行う
# cat /etc/system-release
Amazon Linux release 2 (Karoo)

エージェントのインストール

エージェントがログをCloudWatch Logsに保存してくれますのでエージェントのインストールを行います。
インストールはyumで行い、導入されたコンフィグの初期値を表示させています。

# yum install awslogs
# cd /etc/awslogs/
# ls
awscli.conf  awslogs.conf  config  proxy.conf

# grep -v ^# awslogs.conf

[general]
state_file = /var/lib/awslogs/agent-state

[/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

設定方法

EC2に権限を付与する

IAMロールを作成します

EC2で使用するのでEC2を選びます

ロールの作成でCloudWatchLogsFullAccessの権限を付与します

適当な名前をつけます

EC2の画面に戻って先ほど作成したロールの割当を行います

CloudWatch Logsの設定

リージョンの指定

東京リージョンを使用しているのでap-northeast-1を指定します。

vi /etc/awslogs/awscli.conf
region = ap-northeast-1

awslogs.conf の設定

まずは取り込みたいログのフォーマットを確認します
Apacheのエラーログです

[Sat Aug 10 16:54:37.292742 2019] [mpm_prefork:notice] [pid 3690] AH00163: Apache/2.4.39 () configured -- resuming normal operations

形式にあった設定を行います

[/var/log/httpd/error_log]
file = /var/log/httpd/error_log*
datetime_format = [%a %b %d %H:%M:%S.%f %Y]
buffer_duration = 5000
log_stream_name = {instance_id}_{ip_address}_Error
initial_position = start_of_file
log_group_name = Apache_log
#time_zone = LOCAL
  • datetime_format
    • ログでどのような時間指定がされているかを指定します
    • [Sat Aug 10 16:54:37.292742 2019] の部分と一致するようにしていします
    • フォーマットの指定は以下を参考にします
  • log_stream_name
    • CloudWatchで見たときのフォルダ分けの設定です
    • 今回はインスタンスIDとIPアドレスを表示させるようにしました
  • initial_position
    • ログデータの読み出し位置の指定
  • log_group_name
    • 送信先ロググループの指定
    • ロググループの下にログストリームが作成されます
  • time_zone
    • EC2のタイムゾーンはJSTです。指定しなくても問題なさそうです

今回できなかったこと

accessログの時間が読み取れませんでした。
上記でエラーログのみを扱っているのはaccessログの設定がうまくできなかったからです。

アクセスログのフォーマット

127.0.0.1 - - [10/Aug/2019:16:39:30 +0900] "GET / HTTP/1.1" 403 3630 "-" "curl/7.61.1"

ログの取得自体はできますが、CloudWatchで認識した時間と実際のログの時間が一致しませんでした。
ログの読み込みに関する設定 multi_line_start_pattern をうまく指定すれば解決できるかもしれません。
もしくはJSTを諦め、全てUTCで管理するというのも手かもしれません。

更新履歴

2020/03/26 統合 CloudWatch エージェントについて追記しました