fluentdでALBのアクセスログを取得(fluent-plugin-elb-log)

fluent-plugin-elb-logでS3からALBのアクセスログを収集してみたので手順をまとめます。

github.com

環境

$ lsb_release -d
Description:    Ubuntu 22.04 LTS
$ td-agent --version
td-agent 4.4.1 fluentd 1.15.2 (c32842297ed2c306f1b841a8f6e55bdd0f1cb27f)
$ td-agent-gem list fluent-plugin-elb-log
fluent-plugin-elb-log (1.3.2)

fluent-plugin-elb-logのインストール

fluent-plugin-elb-logをインストールします。

$ sudo td-agent-gem install fluent-plugin-elb-log
Fetching aws-sdk-ec2-1.329.0.gem
Fetching fluent-plugin-elb-log-1.3.2.gem
Successfully installed aws-sdk-ec2-1.329.0
Successfully installed fluent-plugin-elb-log-1.3.2
Parsing documentation for aws-sdk-ec2-1.329.0
Installing ri documentation for aws-sdk-ec2-1.329.0
Parsing documentation for fluent-plugin-elb-log-1.3.2
Installing ri documentation for fluent-plugin-elb-log-1.3.2
Done installing documentation for aws-sdk-ec2, fluent-plugin-elb-log after 13 seconds
2 gems installed

IAMロールの割り当て

EC2インスタンスにポリシー AmazonS3ReadOnlyAccess をIAMロールで割り当てます。

fluentdの設定

プレフィックスなしでバケット my-bucket に保存したアクセスログmy-bucket/AWSLogs/... )を対象とします。

<source>
  @type               elb_log
  tag                 elb.access
  region              ap-northeast-1  # 東京リージョンの場合
  s3_bucketname       my-bucket  # バケット名
  #s3_prefix          # プレフィックスを指定した場合のみ
  timestamp_file      /var/lib/td-agent/elb/elb_last_at.dat  # ログのタイムスタンプを記録
  buf_file            /var/lib/td-agent/elb/fluentd-elblog.tmpfile  # バッファファイル
  start_time          2022-09-01 00:00:00Z  # 開始時刻(後述)
  refresh_interval    300  # リフレッシュ間隔
  delete              false  # 処理したログファイルをS3から削除
  include_all_message false  # 生のログをall_messageフィールドに出力(後述)
</source>
<match elb.access>
  @type stdout
</match>

start_time

ドキュメント化されていませんが、開始時刻はstart_timeで指定できました。
timestamp_filestart_time のうち、より大きいタイムスタンプを使用するようです。

include_all_message

同様に説明がないですが、以下のIssueで追加されたオプションです。
true を設定すると、生のログを all_message に出力します。
省略されたフィールドにアクセスしたい場合に使用します。

github.com

{
    ...
    "all_message": "h2 2022-09-01T00:00:40.188594Z ... ... 192.168.xxx.xxx:80 0.002 0.003 0.000 200 200 245 641 \"GET https://... HTTP/2.0\" \"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0\" ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 arn:aws:elasticloadbalancing:ap-northeast-1:...:targetgroup/... ... ... ... 1 2022-09-01T00:00:40.183000Z \"forward\" \"-\" \"-\" \"192.168.xxx.xxx:80\" \"200\" \"-\" \"-\"\n"
}

動作確認

以下の通りにアクセスログが取得できることを確認できました。
オブジェクトの件数が多いと時間がかかるので気長に待ちましょう。

...
2022-09-06 14:37:52 +0900 [info]: #0 processing 6212 object(s).
2022-09-06 14:37:52.803265383 +0900 fluent.info: {"message":"processing 6212 object(s)."}

2022-09-01 09:00:40.000000000 +0900 elb.access:
{
  "account_id":"...",
  "region":"ap-northeast-1",
  "logfile_date":"2022/09/01",
  "logfile_elb_name":"...",
  "elb_ip_address":"...",
  "logfile_hash":"...",
  "elb_timestamp":"20220901T0005Z",
  "key":"AWSLogs/.../elasticloadbalancing/ap-northeast-1/2022/09/01/....log.gz",
  "prefix":null,
  "elb_timestamp_unixtime":1661990700,
  "s3_last_modified_unixtime":1661990709,
  "time":"2022-09-01T00:00:40.188594+0000",
  "elb":"...",
  "client":"...",
  "client_port":"...",
  "backend":"...",
  "backend_port":"...",
  "request_processing_time":0.002,
  "backend_processing_time":0.003,
  "response_processing_time":0.0,
  "elb_status_code":"200",
  "backend_status_code":"200",
  "received_bytes":245,
  "sent_bytes":641,
  "request_method":"GET",
  "request_uri":"https://...",
  "request_protocol":"HTTP/2.0",
  "user_agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:104.0) Gecko/20100101 Firefox/104.0",
  "ssl_cipher":"ECDHE-RSA-AES128-GCM-SHA256",
  "ssl_protocol":"TLSv1.2",
  "type":"h2",
  "target_group_arn":"arn:aws:elasticloadbalancing:ap-northeast-1:...:targetgroup/...",
  "trace_id":"...",
  "domain_name":"...",
  "chosen_cert_arn":"...",
  "matched_rule_priority":"1",
  "request_creation_time":"2022-09-01T00:00:40.183000Z",
  "actions_executed":"forward",
  "redirect_url":"-",
  "error_reason":"-",
  "option1":"...",
  "option2":"\"200\"",
  "option3":null
}
...