🐥

fluentdを利用してOSログをS3に転送する

2023/11/19に公開
  • 業務で EC2インスタンス内のOSログをS3に転送したい という要件があったのでfluentdで実装した
  • 当初、パースとか頑張っていたのですが、長期保管が目的であり、JSON形式にパースする必要も無いことに気づいてそのままのフォーマットで転送することにした
  • S3のパスにインスタンスIDを含めたかったため、 fluent-plugin-ec2-metadata を利用した
  • fluentdはネット上には多くの情報がありますが、古くからあるため古い記述方法が残っていたりする
  • 将来の自分用のメモですが、該当のバージョンで動作した設定例として同じようなことをやろうとしている他の方の参考になれば幸いです

実行環境

OS Versions

  • Amazon Linux 2
  • AlmaLinux 8.7

Software Versions

  • td-agent v4.5.1
  • fluentd v1.16.2
  • fluent-plugin-s3 (v1.7.2)
  • fluetnd-plugin-ec2-metadata (v0.1.3)

※ td-agentに同梱されているため、fluetnd-plugin-ec2-metadata のみ追加でインストール

事前準備

ログ転送先のS3バケットを作成する

事前にログ転送先のS3バケットを作成する。私の場合は環境毎にバケットを分ける想定だったため、 test-dev-ec2-logs で作成しました。

該当インスタンスにIAMロールをアタッチする

事前にログを転送したいインスタンスに必要なIAMポリシーを付与したIAMロールをアタッチしておく。

細かいIAMポリシーの指定が面倒な場合は、AWS管理ポリシーの「ReadOnlyAccess」「AmazonS3FullAccess」を付与する。最小限のポリシーであれば、下記のIAMポリシーを作成して下さい。S3バケット名は上記で作成したS3バケット名を指定して下さい。

最小のIAM Policy例
{
"Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ec2:Describe*",
            "Resource": "*"
        },
        {
            "Action": "s3:ListBucket",
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::test-dev-ec2-logs",
        },
        {
            "Action": [
                "s3:PutObject",
                "s3:GetObject"
            ],
            "Effect": "Allow",
            "Resource": "arn:aws:s3:::test-dev-ec2-logs/*",
        }
    ]
}

インストール

ROOTユーザに切替後、td-agentのインストールを行う

$ sudo su -

td-agent本体のインストール

業務利用のため、fluentd を直接インストールするのではなく、td-agentで安定版をインストールする。td-agentのインストール方法はOS毎に異なるため Treasure Dataのドキュメント を参照する

  • Amazon Linux 2
    # curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent4.sh | sh
    
  • AlmaLinux 8
    # curl -L https://toolbelt.treasuredata.com/sh/install-redhat-td-agent4.sh | sh
    

td-agent のバージョンを確認する。td-agent (v4.5.1) の場合、fluentd (v1.16.2) がインストールされた

# td-agent --version
td-agent 4.5.1 fluentd 1.16.2 (d5685ada81ac89a35a79965f1e94bbe5952a5d3a)

td-agentの実行ユーザ変更

  • OSログを読み込む際にデフォルトのtd-agentユーザだと権限エラーになるため、td-agentをROOTユーザで起動するように変更する
    # cp -p /usr/lib/systemd/system/td-agent.service{,.`date "+%Y%m%d"`}
    # vim /usr/lib/systemd/system/td-agent.service
    # diff -u /usr/lib/systemd/system/td-agent.service.`date "+%Y%m%d"` /usr/lib/systemd/system/td-agent.service
    --- /usr/lib/systemd/system/td-agent.service.20231029	2023-08-29 11:55:16.000000000 +0900
    +++ /usr/lib/systemd/system/td-agent.service	2023-10-29 19:05:45.973071675 +0900
    @@ -5,8 +5,8 @@
    Wants=network-online.target
    
    [Service]
    -User=td-agent
    -Group=td-agent
    +User=root
    +Group=root
    LimitNOFILE=65536
    Environment=LD_PRELOAD=/opt/td-agent/lib/libjemalloc.so
    Environment=GEM_HOME=/opt/td-agent/lib/ruby/gems/2.7.0/
    # systemctl daemon-reload
    

追加プラグインのインストール

  • fluent-plugin-s3 などのプラグインは td-agentに同梱されている

    # td-agent-gem list | grep fluent-plugin
    fluent-plugin-calyptia-monitoring (0.1.3)
    fluent-plugin-elasticsearch (5.3.0)
    fluent-plugin-flowcounter-simple (0.1.0)
    fluent-plugin-kafka (0.19.0)
    fluent-plugin-metrics-cmetrics (0.1.2)
    fluent-plugin-opensearch (1.1.3)
    fluent-plugin-prometheus (2.1.0)
    fluent-plugin-prometheus_pushgateway (0.1.1)
    fluent-plugin-record-modifier (2.1.1)
    fluent-plugin-rewrite-tag-filter (2.4.0)
    fluent-plugin-s3 (1.7.2)
    fluent-plugin-sd-dns (0.1.0)
    fluent-plugin-systemd (1.0.5)
    fluent-plugin-td (1.2.0)
    fluent-plugin-utmpx (0.5.0)
    fluent-plugin-webhdfs (1.5.0)
    
  • fluetnd-plugin-ec2-metadata は同梱されていないため、追加でインストールを行う

    td-agent-gem install fluent-plugin-ec2-metadata
    

td-agentの設定ファイルを追記

td-agentの設定ファイルを追記する。すべて td-agent.conf に記載しても良かったのですが、アプリログなど色々と記載して複雑になるのも嫌だったので、 インプットに関しては @include で読むこむようにしました。アウトプットは共通のため td-agent.conf に記載しています。

  • 最終的なディレクトリ構成は下記になります。
    # tree /etc/td-agent
    /etc/td-agent/
    ├── conf.d
    │   ├── apache.conf
    │   └── os.conf
    ├── plugin
    ├── td-agent.conf
    └── td-agent.conf.20231029
    

オリジナルの設定ファイルをバックアップ

  • オリジナルの設定ファイルのバックアップ取得し、 conf.d を作成する

    # mv /etc/td-agent/td-agent.conf{,.`date "+%Y%m%d"`}
    # mkdir /etc/td-agent/conf.d
    
  • 設定ファイル (/etc/td-agent/td-agent.conf) を記述する

    # vim /etc/td-agent/td-agent.conf
    

設定ファイル(td-agent.conf)を追記する

  • 設定ファイル (/etc/td-agent/td-agent.conf) を記述する

    # vim /etc/td-agent/td-agent.conf
    
  • 記述内容は下記の通りです

    /etc/td-agent/td-agent.conf
    #######################
    # Input Plugin
    #######################
    ## OS logs (messages, secure, cron)
    @include /etc/td-agent/conf.d/os.conf
    
    #######################
    # EC2 metadata
    #######################
    <match log.**>
        @type ec2_metadata
        @label @S3
        output_tag ${tagset_name}.${instance_id}.${tag}
    </match>
    
    #######################
    # Output Plugin
    #######################
    <label @S3>
        <match **>
            @type s3
            s3_bucket test-dev-ec2-logs # Fix me
            s3_region ap-northeast-1
            # ${tag[0]} = test-dev-bastion01
            # ${tag[1]} = i-xxxxxxxxxxxxxxx
            # ${tag[2]} = log
            # ${tag[3]} = os
            # ${tag[4]} = messages
            path ${tag[1]}/%Y/%m/%d
            time_slice_format %Y%m%d_%H%M%S
            s3_object_key_format %{path}/${tag[3]}-${tag[4]}-%{time_slice}-%{index}.%{file_extension}
            <format>
                @type single_value
            </format>
            <buffer tag,time>
                @type file
                path /var/log/td-agent/buffer/s3
                timekey 1d # 1時間に1回の場合は60mに変更
                timekey_wait 1m
                timekey_use_utc false
                timekey_zone Asia/Tokyo
                chunk_limit_size 1g
                flush_at_shutdown true
            </buffer>
        </match>
    </label>
    

設定ファイル(os.conf)を追記する

  • 設定ファイル (/etc/td-agent/conf.d/os.conf) を記述する

    # vim /etc/td-agent/conf.d/os.conf
    
  • 記述内容は下記の通りです

    /etc/td-agent/conf.d/os.conf
    <source>
        @type tail
        path /var/log/messages
        pos_file /var/log/td-agent/pos/messages.pos
        tag log.os.messages
        <parse>
            @type none
        </parse>
    </source>
    
    <source>
        @type tail
        path /var/log/secure
        pos_file /var/log/td-agent/pos/secure.pos
        tag log.os.secure
        <parse>
            @type none
        </parse>
    </source>
    
    <source>
        @type tail
        path /var/log/cron
        pos_file /var/log/td-agent/pos/cron.pos
        tag log.os.cron
        <parse>
            @type none
        </parse>
    </source>
    

設定ファイル(apache.conf)を追記する

  • 設定ファイル (/etc/td-agent/conf.d/apache.conf) を記述する

    # vim /etc/td-agent/conf.d/apache.conf
    
  • 記述内容は下記の通りです

    /etc/td-agent/conf.d/apache.conf
    <source>
        @type tail
        path /var/log/httpd/access_log
        pos_file /var/log/td-agent/pos/access_log.pos
        tag log.httpd.access_log
        <parse>
            @type none
        </parse>
    </source>
    
    <source>
        @type tail
        path /var/log/httpd/error_log
        pos_file /var/log/td-agent/pos/error_log.pos
        tag log.httpd.error_log
        <parse>
            @type none
        </parse>
    </source>
    

td-agentを起動する

  • td-agentを起動する (既に起動している場合は再起動する)

    systemctl status td-agent.service
    systemctl start td-agent.service
    systemctl status td-agent.service
    
  • td-agentのログを確認し、エラーが出ていないかを確認する

    less /var/log/td-agent.log
    

補足

今回はログ保管が目的だったのでパースは行わず、ログ転送を行っている。パースしてJSON形式で保管したい場合は、下記の設定ファイルを記載する。

設定ファイル(td-agent.conf)を追記する

  • 設定ファイル (/etc/td-agent/td-agent.conf) を記述する

    # vim /etc/td-agent/td-agent.conf
    
  • 記述内容は下記の通りです

    /etc/td-agent/td-agent.conf
    #######################
    # Input Plugin
    #######################
    ## OS logs (messages, secure, cron)
    @include /etc/td-agent/conf.d/os.conf
    
    #######################
    # EC2 metadata
    #######################
    <match log.**>
        @type ec2_metadata
        @label @S3
        output_tag ${tagset_name}.${instance_id}.${tag}
    </match>
    
    #######################
    # Output Plugin
    #######################
    <label @S3>
        <match **>
            @type s3
            s3_bucket test-dev-ec2-logs # Fix me
            s3_region ap-northeast-1
            path ${tag[1]}/%Y/%m/%d
            time_slice_format %Y%m%d_%H%M%S
            s3_object_key_format %{path}/${tag[3]}-${tag[4]}-%{time_slice}-%{index}.%{file_extension}
            <buffer tag,time>
                @type file
                path /var/log/td-agent/buffer/s3
                timekey 1d # 1時間に1回の場合は60mに変更
                timekey_wait 1m
                timekey_use_utc false
                timekey_zone Asia/Tokyo
                chunk_limit_size 1g
                flush_at_shutdown true
            </buffer>
        </match>
    </label>
    

設定ファイル(os.conf)を追記する

  • 設定ファイル (/etc/td-agent/conf.d/os.conf) を記述する

    # vim /etc/td-agent/conf.d/os.conf
    
  • 記述内容は下記の通りです

    /etc/td-agent/conf.d/os.conf
    <source>
        @type tail
        path /var/log/messages
        pos_file /var/log/td-agent/pos/messages.pos
        tag log.os.messages
        <parse>
            @type syslog
        </parse>
    </source>
    
    <source>
        @type tail
        path /var/log/secure
        pos_file /var/log/td-agent/pos/secure.pos
        tag log.os.secure
        <parse>
            @type syslog
        </parse>
    </source>
    
    <source>
        @type tail
        path /var/log/cron
        pos_file /var/log/td-agent/pos/cron.pos
        tag log.os.cron
        <parse>
            @type syslog
        </parse>
    </source>
    

設定ファイル(apache.conf)を追記する

  • 設定ファイル (/etc/td-agent/conf.d/apache.conf) を記述する

    # vim /etc/td-agent/conf.d/apache.conf
    
  • 記述内容は下記の通りです

    /etc/td-agent/conf.d/apache.conf
    <source>
        @type tail
        path /var/log/httpd/access_log
        pos_file /var/log/td-agent/pos/access_log.pos
        tag log.httpd.access_log
        <parse>
            @type apache
        </parse>
    </source>
    
    <source>
        @type tail
        path /var/log/httpd/error_log
        pos_file /var/log/td-agent/pos/error_log.pos
        tag log.httpd.error_log
        <parse>
            @type apache_error
        </parse>
    </source>
    

参考記事

Discussion