ディスク空き容量を取得するFluentdのプラグイン作った
プラグイン作りました
fluentdという様々なデータ収集を統一できるオープンソースのソフトウェアがありますが、プラグインを入れることによって様々で種類のデータを取得したり、加工したりすることができるようになります。
今回は、fluentdを動かしているPCのディスク容量を取得したかったのですが、よさげなプラグインがなかったので作ってみました。RubyGemにも公開済みです。OSSなのでPR, issue歓迎です🙇♂
使い方
プラグインを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
Discussion