fluentdでS3にJSONLでアップロード

fluentdでログをS3にJSONL(JSON Lines)でアップロードするところまでを試しました。

前提

  • fluentdはインストール済み
  • credentialsファイルなどでfluentd動作環境からS3アクセスする権限がある

プラグインインストール

fluentdのS3プラグインを別途インストールする必要があります。gemであれば以下のコマンドです。

$ gem install -N fluent-plugin-s3

fluentd設定ファイル

sample.conf という名前で以下のような設定ファイルを作成しました。

<source>
  # ファイルからログを入力
  @type tail
  path input.txt # 入力のファイル名
  pos_file input.pos
  tag test
  <parse>
    @type none
  </parse>
</source>

# fluentdが処理した日時をtimestampという項目名で保存
<filter test.**>
  @type record_transformer
  enable_ruby
  <record>
    timestamp ${Time.now.iso8601}
  </record>
</filter>

<match test.**>
  # 検証しやすいようにログをS3だけでなく標準出力にも出力
  @type copy
  <store>
    @type stdout
  </store>

  <store>
    @type s3

    # 設定詳細はプラグインのREADMEに書いてある
    # https://github.com/fluent/fluent-plugin-s3

    # S3バケット名
    s3_bucket xxxx

    # S3バケットのリージョン
    s3_region ap-northeast-1

    # S3バケット内のパスプレフィックス
    # ディレクトリのつもりならスラッシュを付ける
    path fluentd-sample-log/

    # S3のファイル存在有無をチェックするかどうか
    # デフォルトはtrue
    # falseにすれば余計なS3 APIコールを節約できる
    # そのかわりS3のキーが常にユニークになるように秒をキーに含めるなどの対応が必要
    check_object false

    # S3のキーのルール
    # デフォルトは %{path}%{time_slice}_%{index}.%{file_extension}
    # fluendの動作環境のタイムゾーン設定によらずUTCになる
    # ↓この設定でこういうキーになる: fluentd-sample-log/2020-09-25-084337.gz
    s3_object_key_format %{path}%Y-%m-%d-%{hms_slice}.%{file_extension}

    # AWS credentialsファイルの特定のprofileで実行したいならば
    <shared_credentials>
      profile_name xxxx
    </shared_credentials>

    # 検証しやすいようにログ3件ごとにS3出力
    # ログ3件ごとにファイルが分割される
    <buffer>
      chunk_limit_records 3
    </buffer>

    # JSONLにするための設定
    # これがないと、日時、タグ、JSONのタブ区切りファイルになる
    <format>
      @type json
    </format>
  </store>
</match>

check_objects3_object_key_format については以下の記事が参考になります。

S3のキーの生成ロジックはソースコードでいうと以下のあたりが参考になります。

https://github.com/fluent/fluent-plugin-s3/blob/v1.4.0/lib/fluent/plugin/out_s3.rb#L276

動かしてみる

入力ファイルを作成し、fluentdを起動します。

$ touch input.txt
$ fluentd -c sample.conf

別のコンソールからテストログを送ります。

$ (echo hello1; echo hello2; echo hello3) >> input.txt

S3には以下のようなファイルができました。

$ aws s3 cp s3://xxxx/fluentd-sample-log/2020-09-25-091258.gz - | gunzip
{"message":"hello1","timestamp":"2020-09-25T18:12:58+09:00"}
{"message":"hello2","timestamp":"2020-09-25T18:12:58+09:00"}
{"message":"hello3","timestamp":"2020-09-25T18:12:58+09:00"}

なお、formatをJSONLにする設定を書かないと、次のような日時、タグ、JSONの順のタブ区切りファイルになりました。(↓testの前後はタブです)

2020-09-25T22:12:52+09:00 test {"message":"hello1","timestamp":"2020-09-25T22:12:52+09:00"}
2020-09-25T22:12:52+09:00 test {"message":"hello2","timestamp":"2020-09-25T22:12:52+09:00"}
2020-09-25T22:12:52+09:00 test {"message":"hello3","timestamp":"2020-09-25T22:12:52+09:00"}

バージョン情報

fluent-plugin-s3 (1.4.0)
fluentd (1.11.1)

リンク

fluentdに関する私の記事