ヒトリ歩き

愚痴とかいろいろ書きます

Fluentdをちょっと使ってみた

前回、KibanaとElasticsearchをインストールしてみました。
kotapontan.hatenablog.com

今回は、ログ収集管理ツールのFluentdをインストールして、さわってみました。

動作環境

Fluentdをインストールする環境は、次の通りです。

OS Version
CentOS 7.5.1804 (Core)

インストール媒体

rpmでインストールするため、Fluentdのサイトからrpmをダウンロードする必要があります。

td-agent-package-browser.herokuapp.com

2020/3/7時点の最新版であるtd-agent-3.6.0-0.el7.x86_64.rpmを使用します。

インストールしてみる

ファイルディスクリプタの最大値を変更します。

ulimit -n 65535

ファイルディスクリプタの最大値の設定を永続化するために、 /etc/security/limits.confに次の設定をします。

root soft nofile 65536
root hard nofile 65536
* soft nofile 65536
* hard nofile 65536

/etc/sysctl.confに次の設定を記入し、sysctl -p を実行し、設定を反映します。

net.core.somaxconn = 1024
net.core.netdev_max_backlog = 5000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_wmem = 4096 12582912 16777216
net.ipv4.tcp_rmem = 4096 12582912 16777216
net.ipv4.tcp_max_syn_backlog = 8096
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_local_port_range = 10240 65535

td-agentが依存するパッケージをインストールします。
依存するパッケージは、yumでインストールします。

yum install -y redhat-lsb-core

rpmをダウンロードし、インストールします。

wget http://packages.treasuredata.com.s3.amazonaws.com/3/redhat/7/x86_64/td-agent-3.6.0-0.el7.x86_64.rpm
rpm -ivh td-agent-3.6.0-0.el7.x86_64.rpm

サービスを登録し、起動します。
サービスの状態が、active(running)となっていれば、インストールは完了です。

systemctl enable td-agent.service
systemctl start td-agent.service
systemctl status td-agent.service

vmstatのログをjson形式に変換する

vmstatコマンドの標準出力の結果をファイルに出力し、出力したファイルをFluentdで解析し、ファイルにjson形式で出力させてみます。
vmstatは、次のようにバックグラウンド実行し、ログに出力します。

vmstat 1 > /tmp/vmstat.log &

/etc/td-agent/td-agent.conf に定義を記載します。

<source>
  @type tail
  path /tmp/vmstat.log
  pos_file /tmp/vmstatlog.pos
  <parse>
    @type regexp
    expression /^([ ]*)(?<r>[^ ]+)([ ]*)(?<b>[^ ]+)([ ]*)(?<swpd>[^ ]+)([ ]*)(?<free>[^ ]+)([ ]*)(?<buff>[^ ]+)([ ]*)(?<cache>[^ ]+)([ ]*)(?<si>[^ ]+)([ ]*)(?<so>[^ ]+)([ ]*)(?<bi>[^ ]+)([ ]*)(?<bo>[^ ]+)([ ]*)(?<in>[^ ]+)([ ]*)(?<cs>[^ ]+)([ ]*)(?<us>[^ ]+)([ ]*)(?<sy>[^ ]+)([ ]*)(?<id>[^ ]+)([ ]*)(?<wa>[^ ]+)([ ]*)(?<st>[^ ]+)/m
  </parse>
  tag vmstat
</source>

<filter vmstat>
  @type grep
  <exclude>
    key r
    pattern /[^0-9]+/
  </exclude>
</filter>

<filter vmstat>
  @type record_transformer
  enable_ruby true
  <record>
    timestamp ${time.strftime('%Y-%m-%d %H:%M:%S')}
  </record>
</filter>

<match vmstat>
  @type file
  path /tmp/vmstat.${tag}.%Y-%m-%d.%H%M.log
  <buffer tag,time>
    timekey 1m
    timekey_wait 2m
  </buffer>
</match>

ログ収集を設定する

sourceディレクティブに、解析する対象を設定します。
pathパラメータに指定したファイルをtailして解析します。

parseディレクティブに、解析用の定義を記述します。
今回は、vmstatのログを解析するため、typeパラメータにregexpを指定し、独自に正規表現を記述しています。

<source>
  @type tail
  path /tmp/vmstat.log
  pos_file /tmp/vmstatlog.pos
  <parse>
    @type regexp
    expression /^([ ]*)(?<r>[^ ]+)([ ]*)(?<b>[^ ]+)([ ]*)(?<swpd>[^ ]+)([ ]*)(?<free>[^ ]+)([ ]*)(?<buff>[^ ]+)([ ]*)(?<cache>[^ ]+)([ ]*)(?<si>[^ ]+)([ ]*)(?<so>[^ ]+)([ ]*)(?<bi>[^ ]+)([ ]*)(?<bo>[^ ]+)([ ]*)(?<in>[^ ]+)([ ]*)(?<cs>[^ ]+)([ ]*)(?<us>[^ ]+)([ ]*)(?<sy>[^ ]+)([ ]*)(?<id>[^ ]+)([ ]*)(?<wa>[^ ]+)([ ]*)(?<st>[^ ]+)/m
  </parse>
  tag vmstat
</source>

apacheやsyslog は、すでに定義が用意されているので、解析対象の組み込みがあるかドキュメントを見て確認しましょう。
docs.fluentd.org

正規表現を作成する場合は、Fluentd向けのエディターで、Fluentularがあります。
fluentular.herokuapp.com

個人的には、Fluentularを使うよりもRublarを使った方が、正規表現の結果が即時反映されるので、分かりやすかったです。
rubular.com

フィルターを設定します

正規表現を使って解析したデータをフィルタリングをします。
rキーの文字が数値以外は収集対象外の設定とtimestampキーに処理する際の日時を設定する処理を追加してみました。

<filter vmstat>
  @type grep
  <exclude>
    key r
    pattern /[^0-9]+/
  </exclude>
</filter>

<filter vmstat>
  @type record_transformer
  enable_ruby true
  <record>
    timestamp ${time.strftime('%Y-%m-%d %H:%M:%S')}
  </record>
</filter>

解析結果をファイルに出力

pathパラメータに解析結果をjson形式で出力します。

<match vmstat>
  @type file
  path /tmp/vmstat.${tag}.%Y-%m-%d.%H%M.log
  <buffer tag,time>
    timekey 1m
    timekey_wait 2m
  </buffer>
</match>

まとめ

parseディレクティブで、正規表現を使ってvmstatのログを抽出してみましたが、正規表現がうまく一致せず、
正規表現の設定で1日使ってしましました。
正規表現を使う場合は、Rubylarのような正規表現デバッグツールを早期に活用した方が効率がいいです。
自力で正規表現を作成してましたが、Rubylarを使ったら30分もかからず、正規表現が出来上がりました。
Rubylarのようなツールがあることも知識として引き出しに入れておかないとダメだなと実感しました。
また、自分自身が正規表現の知識が少なかったので、今後、正規表現について勉強しようと思います。
(grep正規表現を全然使ってないので。)