EC2上のエラーログをS3に移してAthenaで分析する


エラーログをAthenaでお手軽に見やすくしたい

ALBのアクセスログをAthenaで可視化してみたら非常に便利だったので、エラーログでもやってみました。
エラーログ、見るの手間だけどほっとくと増えてるんだよな…。

参考 AWS公式 ALBログのクエリ

環境と要件

Apache/2.4.46 ()
PHP 7.0.33

そこまでリアルタイム性は求めてないですが、毎日更新はさせたいです。
さすがにFatalが出ていたら気づきたいですし、Warningも無理のない範囲でつぶしていきたいです。
ログファイルはLogrotateで日付ごとのファイル分割と.gzファイルへの圧縮は対応済みです。
良い感じの記事が見つからなかったのでテーブルは自作します。

エラーログをS3におく

必ずしも漏らさず拾う必要もないので、ログファイルは適当に定時でS3に移動するようにします。

S3上のエラーログからAthenaでテーブルを作成する

エラーログは以下のような形式です。

[Fri Feb 26 06:50:56.127563 2021] [:error] [pid 26587] [client 127.0.0.1:21111] PHP Warning:  strlen() expects parameter 1 to be string, array given in /home/example.jp/test.php on line 20, referer: https://example.jp/

そしてテーブルの作成クエリがこちら。テーブル名とS3バケット名は任意のものに変更してください。

CREATE EXTERNAL TABLE IF NOT EXISTS in_error_logs (
    time string,
    theme string,
    pid string,
    user_name string,
    ip string,
    type string,
    detail string
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
    'input.regex' = 
    '([^ ]* [^ ]* [^ ]* [^ ]* [^ ]*) ([^ ]*) [^ ]* ([^ ]*) ([^ ]*) ([^ ]*) (.+?): ((.+ on line [0-9]+)(.+))'
)
LOCATION 's3://in-log/error-log/';

以下、考慮した部分です。
同じ内容をGROUP BYでまとめるために、発生個所にreferer情報が出る場合を考慮してカラムを作成しています。
エラーのレベルと内容が分かれば十分なので、ほかの情報はあまり細かく分割していません。
例えば今回ログファイルを日付ごとに分割しているので、記録日時は重要ではないと判断しました。
参考 php エラーログの読み方

必要な情報だけを取り出す

Queryは例えばこんな感じです。

SELECT
    COUNT(TIME) AS COUNT,
    error_level,
    detail
FROM
    elblogdb.media_in_error_logs
GROUP BY
    error_level,
    detail
ORDER BY
    error_level DESC,
    COUNT DESC;

するとこうなります。めでたしめでたし👏
エラー解消していきましょう。

BIツールで可視化

共有したかったのでBIツールで可視化しました。
AWSアカウントのないメンバーでも、ログの確認と対応ができます。
個人的にはRedash気に入ってまして、実際はここまでのクエリ操作もすべてRedash上で行っています。
Fatalないよね?とか、急に件数増えてる!とかわかりやすいです。

やってみて

アクセスログの分析をやっていれば問題なくできると思います。
エラーログを見るハードルがぐんと下がりました。やったね👍