Windowsオンリーの環境でサーバーステータスをfluentd + Elasticsearch + Kibana で収集・可視化する

## 0. 前書き

Windows **サーバーのステータス情報を収集し**、ある意味鉄板となっている**fluentd + Elasticsearch + Kibanaによる可視化をWindows オンリーで**実現します。



目指す構成はこんな感じです。

![fluentd-elastic-kibana.png](https://qiita-image-store.s3.amazonaws.com/0/31816/1956d7af-0749-7b86-81e8-cbfabe346474.png)


下記投稿をElasticsearch + Kibanaで実現するイメージに近いですね。

["WindowsのCPU使用率/空きメモリ量ログを fluentd で転送して、GrowthForecastでグラフ化"](http://qiita.com/okahashi117/items/f5dcebaaadcbd3aa98b7)


ただし、集めるカウンターをちょっと変更し、もう少し現実的なサーバーのパフォーマンスチェックをおこないましょう。Microsoft Technetの記事 ["サーバーのパフォーマンスを測定する"]( https://technet.microsoft.com/ja-jp/magazine/2008.08.pulse.aspx )から以下のカウンタをピックアップします。

CPU関連
![core-i7-88355_640.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/a9a04310-14d9-9dad-39de-9e41f823b5bc.jpeg)

```
Processor\% Processor Time 
プロセッサがアイドル状態でないスレッドを実行した時間の割合を測定します。この割合が 85% を超える場合は、プロセッサに負荷がかかっており、より処理速度の速いプロセッサをサーバーで使用することが必要になる場合があります。
```
```
Processor\% User Time プロセッサがユーザー モードのプログラムを実行した時間の割合を測定します。この値が大きい場合、サーバーのリソースはアプリケーションに占有されています。この場合に考えられる解決策の 1 つは、プロセッサ リソースを占有しているアプリケーションを最適化することです。
```
```
Processor\% Interrupt Time 
特定のサンプリング間隔中にプロセッサがハードウェア割り込みを受け取って処理した時間の割合を測定します。このカウンタの値が 15% を超える場合、ハードウェアに関する問題が発生している可能性があります。
```
```
System\Processor Queue Length 
プロセッサ キューに格納されているスレッドの数を示します。この値が長時間にわたって CPU 数の 2 倍を超える場合は、サーバーで使用されているプロセッサの処理能力が十分ではありません。
```

メモリ関連
![ram-424813_640.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/28b2f3b7-443f-7ae3-080b-14a321155f27.jpeg)

```
Memory\% Committed Bytes in Use 
Commit Limit に対する Committed Bytes の割合 (つまり、使用されている仮想メモリの量) を測定します。この値が 80% を超える場合は、メモリが不足しています。この場合の解決策は、当然メモリを追加することです。
```
```
Memory\Available Mbytes
実行中のプロセスに使用できる物理メモリのサイズ (MB 単位) を測定します。この値が物理 RAM 全体の 5% を下回る場合は、メモリが不足しているため、ページング操作の回数が増加する可能性があります。この問題を解決するには、単純にメモリを追加します。
```

ハードディスク関連
![hard-drive-463922_1280.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/bc787cd8-8572-e640-39e8-5b2145407f8a.jpeg)

```
LogicalDisk\% Free Space 
選択した論理ディスク ドライブ上の空き領域の割合を測定します。この値が 15% を下回る場合は、OS が重要なファイルを格納するための空き領域が不足している可能性があります。当然この場合の解決策は、ディスク領域を追加することです。
```
```
PhysicalDisk\% Idle Time 
サンプリング間隔中にディスクがアイドル状態であった時間の割合を測定します。このカウンタの値が 20% を下回る場合、ディスク システムの使用率は非常に高いと言えます。現在のディスク システムを処理速度の速いディスク システムに交換することを検討してください。
```

プロセス関連
![3127032191_fe29ef809d.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/fd9e8e17-3093-476f-8463-c4eaed8cb3a7.jpeg)

```
Process\Handle Count 
プロセスによって現在開かれているハンドルの合計数を測定します。このカウンタの値が 10,000 を超える場合、ハンドル リークが発生している可能性があります。
```
```
Process\Thread Count 
プロセス内で現在アクティブなスレッドの数を測定します。この値がスレッドの最小数と最大数の間で 500 を超える場合、スレッド リークが発生している可能性があります。
```
```
Process\Private Bytes 
このプロセスに割り当てられており、他のプロセスと共有できないメモリの量を示します。この値がスレッドの最小数と最大数の間で 250 を超える場合、メモリ リークが発生している可能性があります。
```

最終的にはこんな風に見えるようになります。

![winsvrstatus_kibana2.JPG](https://qiita-image-store.s3.amazonaws.com/0/31816/8e290b48-7222-1f04-f719-4df55025d01f.jpeg)


本投稿で利用する環境は以下のとおりです。

**監視するWindowsサーバー**
![win-fluent.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/4e5e39b7-712c-a33e-bbf5-2061548c2b9f.jpeg)

* Windows Server 2012 日本語版
* Ruby 2.1 x64（RubyInstaller 2.1.5）
* fluentd Windowsブランチのバージョン 0.10.46.win150316001

あまりこだわる必要もないですが、それっぽくfluentdはWindowsサービス動作させることにしましょう。


**Elasticsearch + KibanaのWindowsサーバー**
![win-fluent-es-kibana.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/eb45e430-734b-fe5b-88cb-722e7a9c50c8.jpeg)

* Windows Server 2008R2 日本語版
* Ruby 2.1 x64（RubyInstaller 2.1.5）
* fluentd Windowsブランチのバージョン 0.10.46.win150316001

こちらはWindowsサービス動作させようとすると、Kibana4で一手間でるのでWindowsサービス動作させません。それほどハードル高くない（らしい）のでお好みでググりましょう。
また2008R2であることに深い意味はありません。なんとなく手元にあったからです=)

## 1. 監視するWindowsサーバーにfluentdをWindowsサービスとしてインストール
![win_s-fluent.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/792910c6-3072-2e97-860d-37949d6f3224.jpeg)

以下の記事を参考にしてfluentdを導入＆Windowsサービスとして登録します。
["fluentd Windows版をWindowsサービスとして動かす"](http://qiita.com/okahashi117/items/9b55418e770f1f5ce4b7)

記事内のステップ「3. fluentdのオプションを指定する」まで完了しているものとします。
すなわち

* fluentdがWindowsサービスとして動作可能
* C:/fluent/fluent.confを設定ファイルとして指定

の状況となっています。

## 2. 監視するWindowsサーバーに fluent-plugin-parserを導入
![win_s-fluent.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/792910c6-3072-2e97-860d-37949d6f3224.jpeg)

in_execで得られた値をパースするために導入します。
なぜかv0.4だとうまく動かないで、v0.3.4指定で導入します。

```
> gem install fluent-plugin-parser -v 0.3.4 --no-ri --no-rdoc
```


## 3. 監視するWindowsサーバーのfluent.confを設定
![win_s-fluent.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/792910c6-3072-2e97-860d-37949d6f3224.jpeg)

以下のようにfluent.confを記述します。
「0.前書き」で記述のカウンタを読み取って、後ほど設定するElasticsearch+Kibanaのサーバーへフォワードする設定です。

```fluent.conf
<source>
  type exec
  command typeperf -sc 1 "\Processor(_Total)\% Processor Time" "\Processor(_Total)\% User Time"  "\Processor(_Total)\% Interrupt Time" "\System\Processor Queue Length" "\Memory\% Committed Bytes in Use"  "\Memory\Available MBytes" "\LogicalDisk(C:)\% Free Space" "\PhysicalDisk(_Total)\% Idle Time" "\Process(_Total)\Handle Count" "\Process(_Total)\Thread Count" "\Process(_Total)\Private Bytes"
  keys msg
  run_interval 60s
  tag raw.winsvr.status
</source>

<match raw.winsvr.status>
 type parser
 remove_prefix raw
 key_name msg
 format /\"(?<time>[\d:./ ]*)\",\"(?<processor__per_processor_time>[\d.]*)\",\"(?<processor__per_user_time>[\d.]*)\",\"(?<processor__per_interrupt_time>[\d.]*)\",\"(?<system__processor_queue_length>[\d.]*)\",\"(?<memory__per_commited_bytes_in_use>[\d.]*)\",\"(?<memory__available_mybtes>[\d.]*)\",\"(?<logicaldisk_c__per_free_disk>[\d.]*)\",\"(?<physicaldisk__per_idle_time>[\d.]*)\",\"(?<process__handle_count>[\d.]*)\",\"(?<process__thread_count>[\d.]*)\",\"(?<process__private_bytes>[\d.]*)\"/
 time_format %m/%d/%Y %H:%M:%S.%L
 log_level error
</match>

<match winsvr.status>
  type copy
  <store>
    type forward
    <server>
      host xxx.xxx.xxx.xxx #your elasticserver IP here  
    </server>
    flush_interval 60s
  </store>
  #if you want to test, try stdout.
  #<store>
  #  type stdout
  #</store>
</match>
```

flushu_interval等を含むデータの転送タイミングは環境にあわせて適切に調整しましょう。本例ではとりあえず60sとしています。

まだ動かしませんよー。転送先となるサーバーを設定してからです。
forwardのhostのIPは転送先となるElasticserver + KibanaのWindowsサーバーのIPを指定します。

心配な方は上記設定のコメント部分のstdoutを有効化して（forwardを無効化して）、Windowsサービスでなく単純にfluentdコマンドを叩いて確認しておくとよいでしょう。

```
上記プラグインの導入により、Windowsブランチとは別にfluentdのマスターが導入されてしまう場合があります。
> gem list
で確認して、もしマスターが導入されていたら
> gem uninstall fluent
しておきます。
```

## 3. Elasticsearch + KibanaをWindowsサーバーにセットアップ
![win_fluent_s-es_s-kibana.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/500d15a6-5438-04b8-f3cc-a2ce7ee5a7b9.jpeg)

Windowsサーバーのステータス情報を蓄積/分析するためのElasticserverとKibanaをセットアップします。**こちらもWindowsマシンです**。
これは以下の@Aco-gtさんの投稿が簡潔でナイスです。すばらしい。バージョンのみ最新のものを使います。

["Windowsローカル環境で使う、elasticsearch-1.4.1 + kibana-4.0.0-BETA2.0 導入編"](http://qiita.com/Aco-gt/items/ad351387c1ab3ad2561f)

上記手順通り、ElasticsearchとKibanaはこのタイミングですでに起動しておいて問題ありません。

## 4. Elasitsearch + Kibana マシンにfluentd Windows版を導入
![win_s-fluent_es_kibana.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/6d010b94-069a-df73-d6bc-ab4422978ac9.jpeg)

以下の記事を参考にして導入します。
[”fluentd WindowsブランチをRuby 2.1上で動かす”]
(http://qiita.com/![tasksch.JPG](https://qiita-image-store.s3.amazonaws.com/0/31816/9c753897-65d8-f081-de6e-97d9cc9c7d68.jpeg)
okahashi117/items/a0b55ea24a6ef7b6582b)

ただし、上記手順のステップ2で利用するfluentdのgemパッケージは以下のものを使いましょう。まぁ最新版を使おうということです。この記事の投稿時だとこんな感じ。

```
> gem install pkg\fluentd-0.10.46.win20150316001.gem
```



##5. Elasticsearch + Kibana マシンに必要なgem と fluentd pluginを導入
![win_s-fluent_es_kibana.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/6d010b94-069a-df73-d6bc-ab4422978ac9.jpeg)

### patron
これはfluent-pluguin-elasticsearchと依存関係を持つRubyのHTTPクライントなのですが、**単純に gem install fluent-plugin-elasticsearch すると、patronの導入時にlibcurlに関わるnative extentionのビルド部分でこけてしまいインストールできません**。なので個別に、以下の手順を踏んでインストールします。

**libcurlを導入**
**1.** libcurlをダウンロードします
ここではWindows Server 2008R2 (64bit)と仮定していますので、64ビット版をダウンロードします。
http://curl.haxx.se/download.html
のページの、かなり下のほうにある
Win64 - MinGW64のdevel
をダウンロードします。執筆当時でバージョンは7.40.0です。

**2.** 解凍して以下の場所に配置します
7z形式というWindowsではあまりお目にかからないタイプですが、フリーツールを駆使して解凍し、得られたフォルダ curl-7.40.0-devel-mingw64を

```
C:\curl-7.40.0-devel-mingw64
```

として配置します。

**3.** PATHを通します
以下のフォルダにパスを通します。

```
C:\curl-7.40.0-devel-mingw64\bin
```

**4.** libcurl.dllをコピーして必要な場所に配置します
以下の場所にあるlibcurl.dll

```
C:\curl-7.40.0-devel-mingw64\bin\libcurl.dll
```

をRubyインストールディレクトリのbinフォルダにコピーします。
既定のままであれば以下のディレクトリです。

```
C:\Ruby21-x64\bin
```

以上でlibcurlの導入は完了です。

**patronを導入**
libcurlが導入されていれば、以下のコマンドで問題なく入ると思います。

```
> gem install patron -- --with-curl-lib=C:\curl-7.40.0-devel-mingw64\bin --with-curl-include=C:\curl-7.40.0-devel-mingw64\include
```

### fluent-plugin-elasticsearch
patronが導入されていれば、以下のコマンドで問題なく導入されるでしょう。

```
> gem install fluent-plugin-elasticsearch --no-ri --no-rdoc 
```
### fluent-plugin-typecast
fluent-plugin-elasticsearchで放り込むデータの型定義のために必要です。

```
> gem install fluent-plugin-typecast --no-ri --no-rdoc 
```



```
上記プラグインの導入により、Windowsブランチとは別にfluentdのマスターが導入されてしまう場合があります。
> gem list
で確認して、もしマスターが導入されていたら
> gem uninstall fluentd
しておきます。
```

## 6. Elasticsearch + Kibana のWindowsサーバーのfluent.confを設定
![win_s-fluent_es_kibana.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/6d010b94-069a-df73-d6bc-ab4422978ac9.jpeg)

in_forwardで受けて、Elasticsearchに吐き出す設定を記述します。
fluent.confは C:\fluent\fluent.conf にあるものとします。

```fluent.conf
<source winsvr.status>
  type forward
</source>

<match winsvr.status>
  type typecast
  item_types processor__per_processor_time:integer,processor__per_user_time:integer,processor__per_interrupt_time:integer,system__processor_queue_length:integer,memory__per_commited_bytes_in_use:integer,memory__available_mybtes:integer,logicaldisk_c__per_free_disk:integer,physicaldisk__per_idle_time:integer,process__handle_count:integer,process__thread_count:integer,process__private_bytes:integer
  prefix typed
</match>

<match typed.winsvr.status>
  type elasticsearch
  type_name winsvr_status
  buffer_type memory
  logstash_format true
  include_tag_key true
  tag_key @log_name
  flush_interval 60s
</match>
```

先にも書きましたが、flushu_interval等を含むデータの転送タイミングは環境にあわせて適切に調整しましょう。本例ではとりあえず60sとしています。

## 7. いざ！
![ful2.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/8b8656c9-9da9-a443-b62a-4934ef913317.jpeg)

まずElasticsearch + Kibana 側のfluentdを起動します。

```
> fluentd -c C:/fluent/fluent.conf
```

これでカウンター値を受ける側はオッケー。

次は監視される側、カウンター値を送る側のfluentdを起動します。
今回はWindowsサービスとして登録、動作させますので、

```
コントロールパネル > システムとセキュリティ > 管理ツール > サービス > Fluentd Windows Service
```

を選択してダブルクリックでプロパティ画面を開きます。

![fluentdwinsvc3.JPG](https://qiita-image-store.s3.amazonaws.com/0/31816/8ad3f5e7-d080-b35e-e2d0-2384ee6eda76.jpeg)

から開始ボタンをクリックして、Fluend Windows Serviceを開始させます。ポチッとな。

で、ちゃんと転送されているかどうか確認しましょう。
まずインデックス名を確認します。
手元のマシン（Windows！）からブラウザを立ち上げて、ElasticsearchのURLにアクセスしてインデックスを確認しましょう。アドレスバーに以下のURLを入力します。

```
http://<your_elasticserver_ip>:9200/_aliases
```
インデックスの一覧が表示されているはずです。
そのうち"logstash-<今日の日付>"となるインデックスができていると思います。
![es_indexes.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/3ade60ac-8ac5-9516-4a33-d040ea9291ae.jpeg)

この例だと logstash-2015.03.22 ですね。
タイプ名は fluent.confでwinsvr_statusとしていますので、再度以下のURLを入力し、データ転送が正しく行われているか確認します。

```
http://<your_elasticserver_ip>:9200/logstash-2015.03.22/_search&pretty
```
![es_documents2.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/9b86ccf5-acc2-d18e-4466-7fdaf3e9dae4.jpeg)

いいですね！
あとは可視化です！

## 8. Kibanaのダッシュボード作成
![win_fluent_es-kibana.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/dca43fcf-5146-ca11-67f1-ab3e19a8c923.jpeg)

では仕上げ。
手元のマシンからKibanaのURL（ポート）にアクセスして、ポチポチポチとダッシュボードを作りましょう。

```
http://<your_elastic(kibana)server_ip>:5201/
```

![kibana4-2.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/0cbe9978-376d-9503-ac24-a711a2e2cad2.jpeg)

表示されるインデックスパターンの作成画面で、index nameはそのまま、Time-Field nameを@timestampとして、作成ボタンを押します。
どーん。
![kibana4-3.jpg](https://qiita-image-store.s3.amazonaws.com/0/31816/6c02f47d-f463-f311-ca6f-c21a21904f6e.jpeg)


これ以降の手順はQiitaを含めいろいろな方が記事を公開していますので、そちらを参照にしてください。必要に応じてググりましょう。秀逸な記事がゴマンとあります。感謝感謝。


データ範囲とクエリを決めて、
グラフの形をきめて、
ダッシュボード化して
はい、完成！

![winsvrstatus_kibana2.JPG](https://qiita-image-store.s3.amazonaws.com/0/31816/8e290b48-7222-1f04-f719-4df55025d01f.jpeg)

見ると、やや定常的にCPUが一定負荷を占めている&若干のスパイクがありますが、これは予測の範囲なので問題無いです。リーク等もなく、まぁ妥当に稼働しているみたいですね。よかったよかった。

## 9. その他
fluentd Windows版はv10系しか今のところありませんが、今のところはそんなに困ることもないでしょう、たぶん。

おしまい。