はじめに
新しく立てたlinux2
のインスタンスにansible
でtd-agent
の最新版を入れたのでその手順を記します。
目次
1. 対応バージョンの確認
まず古いlinuxAMI
のEC2で使っていた既存のtd-agent
のバージョンを確認しました。
td-agent v2
でした。中身はfluentd v0.12
です。
$ td-agent --version
td-agent 0.12.40 # ここで表示されるのはtd-agent内部で使用されてるfluentdのバージョン
td-agent
はfluend
と呼ばれるクロスプラットフォームのオープンソースデータ収集ソフトを簡易に利用できるようにした安定版パッケージなので、中身はfluentd
みたいです。
td-agent と fluentd の違い
tg-agentの公式サイトで現在の推奨バージョンを確認します。
td-agent v2 vs v3 vs v4
v2はとても古いためAmazonLinux2
は未対応。
td-agent v2
This is for v0.12 and old distribution users. We don't recommend this version for new deployments.
v3は古い安定版で、内部でRuby2.4
が使用。
td-agent v3
Old stable.
Ruby 2.4
Fluentd v1
Windows Support
Remove fluentd-ui from the package
v4は最新の安定版で、内部でRuby2.7
が使用。
td-agent v4
New stable. Major feature updates to td-agent v4 are as follows:
Ruby 2.7
Fluentd v1
Arm64 Support
See also Changes from Treasure Agent 3.
ログ収集はユーザーの行動分析やサイトのモニタリングなどに使う非常に重要な処理なので、とりあえず最新の安定版を入れておこうとtd-agent v4
を使うことに決めました。
2. 使用してるプラグインの確認
td-agent
は、ログのフィルタリングができたり、ログのインプット、アウトプット先などを連携するプラグインに応じて変更するなど、柔軟にカスタマイズができるみたいです。
既存のtd-agent.conf
を読んで、fluent-plugin-forestとfluent-plugin-bigqueryのプラグインが使われていることを確認しました。
これらも一旦今回のインスコ対象に含めることにしました。
3. playbookの作成
今回は5台のサーバに入れる必要があったので、ansbile
のplaybook
を作成しました。
手順書って理解するのに時間かかったり抜け漏れが怖かったりするし、再現性も担保されないから、こういう時にplaybook
がすぐ作れると便利だなと思いました。
ただ、ansible
の書き方ってweb上にある記事を色々見た印象だと人によってもかなり違うし、version
の違いで記法も変わるし、環境ごとに独自のやり方を取ってたりするので、他人のplaybook
をそのまま流用するのはほぼ不可能で、部分的に拝借してくっつけて利用するのが良いなという印象です。
(AnsibleRole
化されてる場合は環境ごとの再現性も担保されてるはずなので使用しても問題ないはず)
参考までに自分が書いたplaybook
を掲載
- hosts: all
vars_files:
- vars/{{ inventory_hostname }}.yml
any_errors_fatal: true
gather_facts: no
user: my_user
become: true
tasks:
- name: test
debug:
msg: "接続先ホスト名: {{ inventory_hostname }}"
- name: Create my_user_keys directory for td-agent
file: path="/home/my_user/my_user_keys" state=directory owner=my_user group=my_user mode=0775
- name: Put my_user_key.json
template: src=my_user_key.j2 dest=/home/my_user/my_user_keys/my_user_key.json backup=true owner=my_user group=my_user mode=0644
- name: Install td-agent v4
shell:
cmd: /bin/bash -lc "curl -L https://toolbelt.treasuredata.com/sh/install-amazon2-td-agent4.sh | sh"
become: yes
- name: Put action_schema.json
template: src=td-agent/action_schema.json.j2 dest=/etc/td-agent/action_schema.json backup=true owner=my_user group=my_user mode=0644
- name: Put td-agent.conf
template: src=td-agent/td-agent.conf.j2 dest=/etc/td-agent/td-agent.conf backup=true owner=my_user group=my_user mode=0644
- name: Install td-agent-gem plugin fluent-plugin-bigquery
shell:
cmd: /bin/bash -lc "td-agent-gem install fluent-plugin-bigquery"
become: yes
- name: Install td-agent-gem plugin fluent-plugin-forest
shell:
cmd: /bin/bash -lc "td-agent-gem install fluent-plugin-forest"
become: yes
- name: Setting root user
lineinfile:
dest: /usr/lib/systemd/system/td-agent.service
backrefs: yes
regexp: ^User=
line: User=root
state: present
- name: Setting root group
lineinfile:
dest: /usr/lib/systemd/system/td-agent.service
backrefs: yes
regexp: ^Group=
line: Group=root
state: present
- name: Enabled and Running td-agent
systemd:
name: td-agent
daemon_reload: yes
state: restarted
enabled: yes
playbook
の解説
-
td-agent
のインスコ前に、Bigquery
との接続のために使うApiKey
を配置してます。 -
AmazonLinux2
用のtd-agent v4
インストールコマンドは公式にあります。 -
td-agent
のインスコ後は、ログのスキーマ定義用のjsonファイルと設定ファイルを配置してます。 - その後、
td-agent-gem
コマンドを使ってプラグインをインスコしてます。 -
td-agent
の実行ユーザーをtd-agent
でなくroot
に変更したくて、起動時に読み込んでるsystemd
のファイルをlineinfile
モジュールを使って書き換えてます。 - 書き換え処理が終わったら
daemon_reload
で設定を読み込んだあと、リスタートさせてます。
ハマりポイント
- conf内で使ってるプラグイン(
td-agent-gem
)が入っていないと、こういうエラーがでます。プラグイン依存をやめてconfを書き換えれる場合はそのほうがいいですが、ダメならプラグインを入れましょう。
fluent/log.rb:369:error: config error file="/etc/td-agent/td-agent.conf" error_class=Fluent::ConfigError error="Unknown output plugin 'forest'. Run 'gem search -rd fluent-plugin' to find plugins"
今回入れたプラグイン
$ td-agent-gem list
fluent-plugin-bigquery (2.2.0)
fluent-plugin-forest (0.3.3)
- バージョン確認の省略コマンドはない
$ td-agent -v
でバージョン確認しようとするとなぜかバージョンが表示されずstdout
にログが垂れ流されてきて謎だったんですが、単にコマンドが--version
しかないだけでした。
この時、fluent/log.rb:369:error: unexpected error error_class=Errno::EADDRINUSE error="Address already in use - bind(2) for 0.0.0.0:24224"
というエラーが出て24224ポートが既に使用中なのだと勘違いし、よくあるエラーか?とこの記事を見ながらプロセスを消して立ち上げ直したりなどしてましたが徒労でした。
- 実行ユーザーを
root
に変更
最初にお試し導入したときに実行ログを眺めてると、このようなエラーに出会いました。
fluent/log.rb:369:error: unexpected error on reading data host="127.0.0.1" port=54444 error_class=Fluent::Plugin::Buffer::BufferOverflowError error="can't create buffer file for /var/log/td-agent/buffer/action_rack/buffer.*.log. Stop creating buffer files: error = Permission denied @ rb_sysopen - /var/log/td-agent/buffer/action_rack/buffer.b5b62c41c60856775a9a0b08a26f55fac.log"
/var/log
の所有者はroot
ユーザーなので、Permission denied
でBuffer
ファイルの生成に失敗してるようです。
td-agent で /var/log/messages の情報を読み込めないの記事を参考にしつつ、td-agent
の実行ユーザーがデフォルトだとtd-agent
になっているのをroot
に修正することにしました。
# 起動時に読み込んでるファイルを確認するためにstatusを開く
$ sudo systemctl status td-agent.service
● td-agent.service - td-agent: Fluentd based data collector for Treasure Data
Loaded: loaded (/usr/lib/systemd/system/td-agent.service; enabled; vendor preset: disabled) # ここが起動時設定ファイル
Active: active (running) since 金 2020-12-11 19:19:55 JST; 11h ago
Docs: https://docs.treasuredata.com/articles/td-agent
Process: 5133 ExecStop=/bin/kill -TERM ${MAINPID} (code=exited, status=0/SUCCESS)
Process: 5142 ExecStart=/opt/td-agent/bin/fluentd --log $TD_AGENT_LOG_FILE --daemon /var/run/td-agent/td-agent.pid $TD_AGENT_OPTIONS (code=exited, status=0/SUCCESS)
Main PID: 5151 (fluentd)
CGroup: /system.slice/td-agent.service
├─5151 /opt/td-agent/bin/ruby /opt/td-agent/bin/fluentd --log /var/log/td-agent/td-agent....
└─5154 /opt/td-agent/bin/ruby -Eascii-8bit:ascii-8bit /opt/td-agent/bin/fluentd --log /va...
上記のsystemd
の設定ファイル内にUser=td-agent
、Group=td-agent
と記載されてるので、そこをansible
のlineinfile
を使って正規表現検索をかけて、root
に書き換えます。
そして、設定ファイルを再度読み込ませるためにdeamon_reload
してrestart
すればroot
で実行されるので解決です。
(ちなみにansible
のservice
モジュールではdeamon_reload
はできず、systemd
モジュールが完全に上位互換に見えたので、サービスの自動起動設定などの際はsystemd
モジュールを使うのがオススメです。)
4. playbookの実行
td-agent v4
(fluentd v1.11.2
)が無事インストールされました。
$ td-agent --version
td-agent 1.11.2
5. 動作確認
ログの確認
$ tail -f /var/log/td-agent/td-agent.log
Bigqueryでの計測データ確認
SELECT FORMAT_TIMESTAMP('%Y-%m-%d %H:%M:%S', TIMESTAMP_SECONDS(time), 'Asia/Tokyo') AS date, message FROM `my_project.my_dataset.action_rack_20201211` ORDER By date DESC limit 100
両方に問題なければおkです。
おしまい
(余談:td-agentがエラーを吐いたときにアラートを出す仕組みがあるとよさそうです。ログ欠損怖い。)