sorta kinda...

主にAWS関連ですが、これに限らずいろいろ勉強したことや思ったことを書いていきます。

Apache のアクセスログでオブジェクトサイズが "-" になってた [cloudpack OSAKA blog]

ナスです。

Cloudwatch logs のログを Elasticsearch Service に転送するの、簡単でいいですね。対象のロググループのアクションで、「Stream to Amazon Elasticsearch Service」を選べばいいだけですから。
docs.aws.amazon.com

でも、それで作成される Lambda Function が完璧かというとそうでもありません。残念ながらいろいろと調整しないといけないです。というか本番環境でそのまま使えた試しがまだ一回もないです… 使い方が悪いのかな。

 

Apacheアクセスログだけたまにエラーで転送されない

という事象に出くわしました。本当にたまにです。Elasticsearch Service に転送する Lambda のログを見ると、こんなエラーでした。

2017-04-19T00:00:00.700Z   xxxxxxxxxxxxxx    Failed Items: [
{
    "index": {
        "_index": "cwl-access_log-2017.04.19",
        "_type": "/var/log/httpd/access_log",
        "_id": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
        "status": 400,
        "error": {
            "type": "mapper_parsing_exception",
            "reason": "failed to parse [bytes]",
            "caused_by": {
                "type": "number_format_exception",
                "reason": "For input string: \"-\""
            }
        }
    }
}
]

ちなみにログ転送する際に定義したフィルタは↓これです。

[host, id, user, date, request, status, bytes, other]

bytes に入れようとした値が -(ハイフン) だったので、それ数値じゃねーよ!って言われてます。

 

対処は簡単

対処法は 2 つあります。

1 つは、Lambda で bytes にあたる値が “-” だったら 0 にする。もう 1 つは、httpd 側でログフォーマットを変更する。です。

httpd のログフォーマットについては、ここをみれば ok です。
ログファイル - Apache HTTP サーバ バージョン 2.2

該当の説明を見ると、

この最後のエントリはクライアントに送信されたオブジェクトの、 応答ヘッダを除いたサイズを表します。コンテントがクライアントに送られなかった 場合は、この値は “-” になります。コンテントが無い場合に “0” をログ収集するには、%b ではなく %B を使ってください。

とありますので、ログフォーマットを %B に変更してやればいいわけです。結局、Lambda 側で調整することにしたので、httpd のログフォーマットで調整できるかどうかは試していませんが、たぶんできると思います。

 

この件で思ったのは、ログファイルごとにログフォーマットがちゃんと揃ってないと Elasticsearch Service に転送する時にエラーが出まくることになるので、注意が必要だということです。ミドルウェア等のログフォーマットはだいたい揃っていると思いますのでいいのですが、自社や他ベンダーが開発したアプリケーションのログも Elasticsearch Service に転送するなら、ログフォーマットがどうなっているかよく調べたほうがいいと思います。