🎃

ディスク空き容量を取得するFluentdのプラグイン作った

2021/07/23に公開

プラグイン作りました

fluentdという様々なデータ収集を統一できるオープンソースのソフトウェアがありますが、プラグインを入れることによって様々で種類のデータを取得したり、加工したりすることができるようになります。

今回は、fluentdを動かしているPCのディスク容量を取得したかったのですが、よさげなプラグインがなかったので作ってみました。RubyGemにも公開済みです。OSSなのでPR, issue歓迎です🙇‍♂

https://github.com/nomunomu0504/fluent-plugin-diskfree

https://rubygems.org/gems/fluent-plugin-diskfree

使い方

プラグインをGemでインストールします。

$ gem install fluent-plugin-diskfree

これでプラグインが利用できるようになるので、fluentdの設定ファイルに追記します。

<source>
  @type diskfree
  option -k
  refresh_interval 10
  mounted_path /fluentd/etc
  replace_separator true
  trim_percent true
  tag_prefix hostpc.df
</source>

それぞれの設定値は以下の通りです。

オプション デフォルト値 説明
option string -k dfコマンドに渡すオプション。
デフォルトはblock-sizeを1Kとして
表示するオプションが設定されています。
refresh_interval integer 5 dfコマンドを実行する間隔。
デフォルトは5秒です。
mounted_path string / チェック対象のマウントパスを指定します。
デフォルトはルートディレクトリとなっています。
trim_percent bool true dfコマンド結果に現れる%を削除します。
trueの場合、返却される値の型はint
falseの場合は、返却される値の型はstringになります。
replace_separator bool true mounted_pathで指定したパスの/_に変換してから返却します。
tag_prefix string diskfree fluentdのタグに接頭語を追加します。

上記のfluent.confの状態で、fluentdを実行すると以下のようなログを取得することができます。

hostpc.df._fluentd_etc: {
  "mounted_path":"_fluentd_etc",
  "disksize":250630588,
  "used":147889068,
  "used_percent":59.0,
  "available":102741520,
  "available_percent":40.99,
  "capacity":59
}

実装解説

fluentd公式サイトに、プラグインの作成方法が掲載されています。基本的にはその方法に従って作成します。
(※ 今回のプラグインを作るときには、fluentd公式の方法を見つけていなくて普通のGemを作る方法で実装してました...🥺)

このプラグインの主要な部分だけ軽く解説しておきます。ソース全体はGithub上に公開されています。

# Get df output. splited by line.
result = `#{@execute_command}`.split(/\R/)
# Remove df output header.
result.shift

@execute_command には実行する df コマンドを指定します。@execute_command の定義はこんな感じです。

@execute_command = "df -P #{@option} #{@mounted_path} 2> /dev/null"

fluent.conf で指定した option や mounted_path を展開して実行する df コマンド作りあげます。上記のconf設定だと、このような df コマンドが実行されます。

@execute_command = "df -P -k /fluentd/etc 2> /dev/null"

このコマンドを実行すると以下のような結果が返ってきます。それを result の中に格納します。
(※ 表示内容は実行している端末によって異なります。)

Filesystem           1024-blocks    Used Available Capacity Mounted on
/dev/mapper/centos-home    250630588 149553004 101077584  60% /fluentd/etc

そして result.shift を実行することで、df コマンドのヘッダー部分を削除して、必要な情報だけが result の中に残るようにします。

# resultの中身
Filesystem           1024-blocks    Used Available Capacity Mounted on
/dev/mapper/centos-home    250630588 149553004 101077584  60% /fluentd/etc
↓
↓ result.shift を実行すると先頭(ヘッダー)が削除されます。
↓
/dev/mapper/centos-home    250630588 149553004 101077584  60% /fluentd/etc

ヘッダーを削除した状態で、データを分割して配列化します。
結果を出力するために必要なデータを取得できなかった場合には、エラーログを出力するようにしておきます。

data_list = line.split(/\s+/)
log.error("Invalid df output format. #{line}") unless data_list.length == DF_HEADER_COLMUS_LENGTH

あとは必要なデータから、出力するデータを生成して終了です。

used_percent = ((data_list[2].to_f / data_list[1].to_f) * 100).floor(2)
available_percent = ((data_list[3].to_f / data_list[1].to_f) * 100).floor(2)

disk_info = {
  'mounted_path' => replace_separator?(data_list[5]),
  'disksize' => data_list[1].to_i,
  'used' => data_list[2].to_i,
  'used_percent' => @trim_percent ? used_percent : "#{used_percent}%",
  'available' => data_list[3].to_i,
  'available_percent' => @trim_percent ? available_percent : "#{available_percent}%",
  'capacity' => data_list[4].to_i
}
disk_info
GitHubで編集を提案

Discussion