Windowsのプロセス単位のCPU使用率アラートをfluentdを使ってやってみる
fluentdにいつの間にかWindowsのユースケースが載っていました。気づくの遅すぎ。
http://docs.fluentd.org/ja/articles/windows
ということでレッツトライします。
お題はWindows側の特定プロセスのCPU使用率が●%を越えたらアラート。
ユースケースに則ってWindows側にnxlogをインストールして、fluentd側で type syslog で受けるところまでは進めます。
受け側のfluentd側はセットアップで楽するためにtd-agentを入れました。
なんとか目的のものはできましたが、なんか非効率な気がしているので何だかなぁ…という感じです。
参考
filterの書き方 http://muddydixon.hatenablog.com/entry/2012/08/31/144853
paser の正規表現チェック http://fluentular.herokuapp.com/
Windows側で使うもの(Linux側のfluentdはなくて良いよね…)
PsList http://technet.microsoft.com/en-us/sysinternals/bb896682
nxlog http://nxlog.org/download
大雑把な構造
pslist -s でファイルに pslist の結果を出力 nxlog で pslist の結果を fluentd に飛ばす fluentd の syslog で受ける filtered で必要なプロセスに絞る notifier で閾値設定とアラート出力
nxlog.conf
define ROOT C:\Program Files (x86)\nxlog Moduledir %ROOT%\modules CacheDir %ROOT%\data Pidfile %ROOT%\data\nxlog.pid SpoolDir %ROOT%\data LogFile %ROOT%\data\nxlog.log <Extension syslog> Module xm_syslog </Extension> <Extension json> Module xm_json </Extension> <Input in> Module im_file File "D:\work\winfluent\srclog\log.txt" SavePos TRUE InputType LineBased </Input> <Processor t> Module pm_transformer OutputFormat syslog_bsd Exec $Message=(": "+$raw_event); </Processor> <Output out> Module om_tcp Host xxx.xxx.xxx.xxx Port 5140 </Output> <Route r> Path in => t => out </Route>
fluentd側追加プラグイン
/usr/lib64/fluent/ruby/bin/gem install fluent-plugin-filter /usr/lib64/fluent/ruby/bin/gem install fluent-plugin-mail /usr/lib64/fluent/ruby/bin/gem install fluent-plugin-notifier /usr/lib64/fluent/ruby/bin/gem install fluent-plugin-parser /usr/lib64/fluent/ruby/bin/gem install fluent-plugin-rewrite-tag-filter
td-agent.conf(syslogで受けるところからの部分のみ。最終的にはmail通知。)
firefoxプロセスのCPU使用率5%/10%以上でのアラート
IdleのCPU使用率50%/20%以下でのアラート(マシン全体のCPU使用率の代わりです)
# サンプルそのまま <source> type syslog protocol_type tcp port 5140 tag winlog </source> # filterプラグインで以降に流す部分の量を減らすためにプロセス名でフィルタします。 # syslog で受けたものをそのまま受けてフィルタするため、正規表現パターンで行います。 <match winlog.**> type filter all deny allow message: /firefox/, message: /Idle/ </match> #<match filtered.**> # type stdout #</match> # この後 parse に入力すると syslog で受けた key=host が無くなるため、 # ここで rewrite_tag_filter を使ってホスト名をタグ部分に移動させます。 <match filtered.**> type rewrite_tag_filter rewriterule1 host ^(.+)$ filterrewrited.$1.${tag} remove_tag_prefix filtered </match> # parse で message 内容に key 付けして、notifier で使う target_keys を作ります。 <match filterrewrited.**> type parser remove_prefix filterrewrited add_prefix winproc format /^(?<Name>[^ ]* +\d+) +(?<Cpu>\d+) +(?<Thd>\d+) +(?<Hnd>\d+) +(?<Priv>\d+) +(?<CpuTime>.+) +(?<ElapsTime>.+)$/ key_name message suppress_parse_error_log true </match> #<match winproc.**> # type stdout #</match> # notifier のデフォルトアラート出力だとプロセス名などが抜けてしまうので、 # rewrite_tag_filter でタグ側に移動させます。今回はプロセス名とPID。 # ついでに、message のパースの際プロセス名を key にする方法がちょっと探しきれずにタイムオーバしたため # 暫定でプロセス名をタグの先頭に配置することで、後の notifier の match にプロセス名を使えるようにして # プロセスごとの閾値を設定できるようにします。 <match winproc.**> type rewrite_tag_filter rewriterule1 Name ^([^ ]*) +(\d+)$ $1.$2.${tag} remove_tag_prefix winproc </match> # プロセス名ごとに match ルールで notifier で閾値設定。 # 本当は <def> 内の target_keys を プロセス名_Cpu とかにして、記述できるようが綺麗だと思ってる…。 <match firefox.**> type notifier <def> pattern firefox check numeric_upward warn_threshold 5 crit_threshold 10 target_keys Cpu </def> </match> <match Idle.**> type notifier <def> pattern Idle check numeric_downward warn_threshold 50 crit_threshold 20 target_keys Cpu </def> </match> # 最終的にはメール通知とかIRCに出すとか。もうお好みで。 <match notification.**> type stdout # type mail # host localhost # port 25 # from FROM # to TO # subject fluentd notification # out_keys pattern,target_tag,target_key,level,value,message_time </match>
Windows側でのテストキック
D:\work\winfluent\PSTools pslist.exe -s 100 >> ..\srclog\log.txt
サンプル出力
2014-05-04 20:26:54 +0900 notification: {"pattern":"Idle","target_tag":"Idle.0.desktop-PC.winlog.user.notice","target_key":"Cpu","check_type":"numeric_upward","level":"crit","threshold":10.0,"value":91.0,"message_time":"2014-05-04 03:15:51 +0900"}
改善したいもの
本当は notifier の target_keys でプロセス名を指定して閾値を設定したいのだけど、その場合は送られてきた message 内のプロセス名を key に設定しないといけない。
ざっくりプラグインリストを見ていたけど、ちょっと目的に合うものが簡単には見つからなかったので rewrite_tag_filter を使ってプロセス名やホスト名をタグの方に持ってきて notification 出力を調整。
実運用時には、オリジナルログの保全のために type syslog で受けたものをファイルコピーする部分も別に必要。
win側では pslist の定期実行とログローテ用のスクリプト作成が必要。
1時間単位での min/max/avg も出したくなってくる。
メモ:fluent-plugin-forestとfluent-plugin-datacalculator