IISのログをfluentdで集めてWindows上のMySQLに突っ込む

# 0. 前書き
Windowsで利用可能なWebサーバーとしてIIS(Microsoft Internet Information Services)があります。WebサーバーとしてはApacheが広く認知され広く利用されていますが、以外とIISもお目にかかるものです。

この投稿では、fluentdを使ってIISのログを収集する手順サンプルを示しています。

最近では色々な理由で、Windows(のみ)を中心としてインフラ周りを構築されているケースも多いと思いますので、以下の状況を設定してみました。

* IISは2台
* **Windows上にインストールされたMySQLにログを保存する**
* **fluentdでログを集約**
* fluentdのWindowsブランチを使用
* **収集のフローにLinuxは登場しない**
* Rubyは1.9系（32bit）を使用

fluentd Windows版で　
　"forwardできるじゃん！" 
　"MySQLに書けるじゃん！"
的なところがポイントでしょうか。
MySQLの導入も触れるので少々長めの投稿です。

めざす構成は以下の様になります。

![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/31816/b157ae00-419d-a895-3873-ec8535fbc4ed.png)


fluentdはWindowsブランチ版を使用します。Windowsへの導入について [WIndowsでfluentdを動かす](http://qiita.com/okahashi117/items/0203badd77c9df564166) を参考にしてください。文中でも同投稿を参照しています。

IISは2台という設定のもと、タグ名にホスト名をつけたいので、config expander プラグインを併用します。


IISのログのフォーマットおよびローテーションなどはデフォルト設定とします。（IIS 7.5）

* W3C形式
* %SystemDrive%\inetpub\logs\LogFiles
* 日毎にファイル名に日付





#1. IISが導入されているWindowsマシンにfluentdをインストールする
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/31816/3bab61fb-f5c0-3a62-370a-190f77d1d86b.png)

まずはIISが入っているマシン側を設定します。
以下の投稿内容と同等のところまでできるようにfluentdをセットアップします。

[WIndowsでfluentdを動かす]
(http://qiita.com/okahashi117/items/0203badd77c9df564166)

以降、fluentdの設定ファイルは以下の場所にあるものとします。

```
C:\fluent\fluent.conf
```

Server1, Server2 双方とも実施します。

　
#2. fluent-plugin-config-expanderを導入する
複数のIISのログ収集というシナリオのもと、fluentdメッセージのタグにホスト名を動的につけるため、fluentdのconfig expanderプラグインを導入します。

tagomorisさん謹製です。感謝。

コマンドプロンプトを立ち上げて、以下のようにタイプし実行します。

```
> fluent-gem install fluent-plugin-config-expander
```

特に問題なく入ると思います。
Server1, Server2 双方とも導入しましょう。

　
#3. IISのログをfluentdで読み取れるようにする
*IISログファイル→* ![キャプチャ5.PNG](https://qiita-image-store.s3.amazonaws.com/0/31816/e6f4c313-9a3d-44a3-3d16-70ceb3967b2c.png) *→標準出力（仮）*

デフォルトで、IISのログのファイルの書式とローテーション設定は

* W3C形式
* ファイル名に日付

ファイルのローテーションは
です。
具体的には、以下のようなログファイルを生成します。

```
#Software: Microsoft Internet Information Services 7.5
#Version: 1.0
#Date: 2014-06-15 00:17:32
#Fields: date time s-ip cs-method cs-uri-stem cs-uri-query s-port cs-username c-ip cs(User-Agent) sc-status sc-substatus sc-win32-status time-taken
2014-06-15 00:17:32 127.0.0.1 GET / - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+6.1;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/35.0.1916.153+Safari/537.36 304 0 0 1868
2014-06-15 00:17:32 127.0.0.1 GET /welcome.png - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+6.1;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/35.0.1916.153+Safari/537.36 304 0 0 1
2014-06-15 00:19:35 127.0.0.1 GET / - 80 - 127.0.0.1 Mozilla/5.0+(Windows+NT+6.1;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/35.0.1916.153+Safari/537.36 304 0 0 7
```

また、ログファイルは以下のようなファイル名を持ち、日付毎にファイルがきられます。
ファイル名の後ろがyymmddとなっています。
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/31816/ad463748-30f4-85be-f265-a2e3e7c14523.png)


fluentdの設定として、まずここでは、

* IISのログの読み取り
* 日付ベースでのログファイル名への対応
* ホスト名での動的なタグ付け
* 標準出力

をおこない、MySQLサーバーへの転送設定は、後ほど行います。
C:\fluent\fluent.confを以下のように設定します。

```
<source>
  type config_expander
  <config>
    type tail
    format /^(?<time>[^ ]* [^ ]*) (?<sip>[0-9.]*) (?<csmethod>[^ ]*) (?<csuristem>[^ ]*) (?<csuriquery>[^ ]*) (?<sport>[0-9]*) (?<csusername>[^ ]*) (?<cip>[0-9.]*) (?<csua>[^ ]*) (?<scstatus>[0-9]*) (?<scsubstatus>[0-9]*) (?<scwin32status>[0-9.]*) (?<timetaken>[0-9]*)$$/
    time_format %Y-%m-%d %H:%M:%S
    path C:/inetpub/logs/LogFiles/W3SVC1/*
    tag iislog.__HOSTNAME__
    pos_file C:/temp/iislog.pos
    reflesh_interval 1s
  </config>
</source>

<match iislog.*>
  type stdout
</match>
```

正規表現が気に入らない等は、適当に手直しをどうぞ:)
pos_fileをC:\tempフォルダに設定していますので、C:\tempフォルダは事前に作成しておきます。
formatで＊ワイルドカードによるフォルダ内のファイルを全て対象としています。以前はtail_exとして知られた機能ですが、本家にマージされました。Yoshihisa Tanakaさんに感謝。

Server1, Server2 双方とも同様に実施ましょう。
同じ設定ファイルでいけるはずです。


　
#4. ログを収集する側のWindowsにMySQLを導入しRubyから接続できるようにする



## 4.1 MySQLをインストールする

![Mysql-256.png](https://qiita-image-store.s3.amazonaws.com/0/31816/28fee207-d1a8-f503-6479-e88b91f4da8f.png)


以下のサイトよりMySQLをダウンロードし、導入します。

[Download MySQL Community Server]
(http://dev.mysql.com/downloads/mysql/5.5.html#downloads)

**5.5系の"Windows (x86, 32-bit), MSI Installer"をダウンロードします。
今回はRuby 1.9系の32bitを前提としていますので、32bit版を利用します。
これをミスると以降の環境づくりで失敗しますのでご注意ください**



ダウンロードが完了したら画面の指示に従ってインストールします。

**コマンドプロンプトからSQLコマンドを実行できるように構成するのを忘れないでください。**


.　
## 4.2 Rubyから接続できるようにする 

![ruby_to_mysql.png](https://qiita-image-store.s3.amazonaws.com/0/31816/4868986f-8157-4cbb-5573-8542bf334776.png)

fluentdプラグイン云々以前にRubyからMySQLの接続できないと困ります。つまりはRubyからコネクタを叩けるようにします。

インストール済みのMySQLのフォルダから、以下のファイルをコピーして

> "C:\Program Files (x86)\MySQL\MySQL Server 5.5\lib\libmysql.dll"

Rubyのインストールディレクトリのbinフォルダにコピーしてください。

> "C:\Ruby193\bin"

これをやっておかないと、次のmysql2の導入時にファンクションエントリが見つからず、エラーが発生します。

コピーが完了したら、コマンドプロンプトを立ち上げ、以下のコマンドを実行します。
特にエラーなく導入が終了します（するはず）。

```
> gem install mysql2 -- '--with-mysql-lib="C:\Program Files (x86)\MySQL\MySQL Server 5.5\lib" --with-mysql-include="C:\Program Files (x86)\MySQL\MySQL Server 5.5\include"'

Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
Successfully installed mysql2-0.3.16
1 gem installed
Installing ri documentation for mysql2-0.3.16...
Installing RDoc documentation for mysql2-0.3.16...
```


.　
## 4.3 IISログ保存のためのデータベースおよびテーブルを作成する

![db-table.png](https://qiita-image-store.s3.amazonaws.com/0/31816/00fbea5e-250d-f8be-b14b-a17b4e2c2fc7.png)

まあ本題ではないので適当に。
「3. IISのログをfluentdで読み取れるようにする」の fluent.confでformatで定義したエントリ全て＋時間とタグ を格納できるようにテーブルを切ります。

* データベース名はiislog
* テーブル名はaccesslog

としておきます。
テーブル定義はこんな感じで。恐怖のvarcharアタック。

```
mysql> create table accesslog(time varchar(255),tag varchar(255),sip varchar(255),csmethod varchar(255),csuristem varchar(255),csuriquery varchar(255),sport varchar(255),csusername varchar(255),cip　varchar(255),csua varchar(255),scstatus varchar(255),scsubstatus varchar(255),scwin32status varchar(255),timetaken varchar(255));
Query OK, 0 rows affected (0.38 sec)

mysql> describe accesslog;
+---------------+--------------+------+-----+---------+-------+
| Field         | Type         | Null | Key | Default | Extra |
+---------------+--------------+------+-----+---------+-------+
| time          | varchar(255) | YES  |     | NULL    |       |
| tag           | varchar(255) | YES  |     | NULL    |       |
| sip           | varchar(255) | YES  |     | NULL    |       |
| csmethod      | varchar(255) | YES  |     | NULL    |       |
| csuristem     | varchar(255) | YES  |     | NULL    |       |
| csuriquery    | varchar(255) | YES  |     | NULL    |       |
| sport         | varchar(255) | YES  |     | NULL    |       |
| csusername    | varchar(255) | YES  |     | NULL    |       |
| cip           | varchar(255) | YES  |     | NULL    |       |
| csua          | varchar(255) | YES  |     | NULL    |       |
| scstatus      | varchar(255) | YES  |     | NULL    |       |
| scsubstatus   | varchar(255) | YES  |     | NULL    |       |
| scwin32status | varchar(255) | YES  |     | NULL    |       |
| timetaken     | varchar(255) | YES  |     | NULL    |       |
+---------------+--------------+------+-----+---------+-------+
14 rows in set (0.02 sec)
```




　
# 5. MySQLを導入したWindowsマシンにfluentdを導入する
![キャプチャ.PNG](https://qiita-image-store.s3.amazonaws.com/0/31816/e83ae37c-c8a2-787e-2e4f-62f891937a3b.png)

以下の投稿内容と同等のところまでできるようにfluentdをセットアップします。

[Windowsでfluentdを動かす]
(http://qiita.com/okahashi117/items/0203badd77c9df564166)

以降、fluentdの設定ファイルは以下の場所にあるものとします。

```
C:\fluent\fluent.conf
```

　
#6. fluent-plugin-mysqlを導入する
fluent-plungin-mysqlはfluentdからmysqlに書き込むためのプラグインです。
再びtagomorisさん謹製。感謝。
 
以下のコマンドを実行して導入します。

```
> fluent-gem install fluent-plugin-mysql

Successfully installed mysql2-cs-bind-0.0.6
Successfully installed multi_json-1.10.1
Successfully installed jsonpath-0.5.6
Successfully installed fluent-plugin-mysql-0.0.7
4 gems installed
Installing ri documentation for mysql2-cs-bind-0.0.6...
Installing ri documentation for multi_json-1.10.1...
Installing ri documentation for jsonpath-0.5.6...
Installing ri documentation for fluent-plugin-mysql-0.0.7...
Installing RDoc documentation for mysql2-cs-bind-0.0.6...
Installing RDoc documentation for multi_json-1.10.1...
Installing RDoc documentation for jsonpath-0.5.6...
Installing RDoc documentation for fluent-plugin-mysql-0.0.7...
```

もしエラーがでた場合、表示されるメッセージにあわせて対処します。mysql2の導入に失敗しているケースがよくあるようです。

　
#7. fluentdからMySQLへの書き込み設定をおこなって起動する
*forwardされたIISログ→* ![キャプチャ5.PNG](https://qiita-image-store.s3.amazonaws.com/0/31816/e6f4c313-9a3d-44a3-3d16-70ceb3967b2c.png)  *→MySQL*

C:\fluent\fluent.confを設定しましょう。

* In_forwardでイベントを受け取り
* Out_MySQLでの書き込み
* 時間とタグ（config_expanderにより動的にホスト名を含められたタグ）も記録

具体的には以下のようになります。

```
<source>
  type forward
</source>

<match iislog.*>
  type mysql
  host 127.0.0.1
  database iislog
  username #your mysql user account#
  password #your mysql user password#
  flush_interval 1s

  include_time_key yes
  include_tag_key yes

  table accesslog
  key_names time,tag,sip,csmethod,csuristem,csuriquery,sport,csusername,cip,csua,scstatus,scsubstatus,scwin32status,timetaken
  sql INSERT INTO accesslog (time,tag,sip,csmethod,csuristem,csuriquery,sport,csusername,cip,csua,scstatus,scsubstatus,scwin32status,timetaken) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
</match>
```

**そしてこれ重要。fluentdのフォワードをうけるため、Windowsファイアウォールのポート番号24224をあけてください。** TCP,UDP 双方について開ける必要がありますのでご注意を。

当たり前と思うでしょ？意外と忘れちゃうんですって。とりあえずお試しであればファイアウォール自体をオフってしまうと楽です。

ここまで完了したらMySQLマシン側のfluentdは準備完了です。動かしましょう。

```
> fluentd -c C:/fluent/fluent.conf
2014-06-26 21:50:57 +0900 [info]: starting fluentd-0.10.46
2014-06-26 21:50:58 +0900 [info]: is windows platform : true
2014-06-26 21:50:58 +0900 [info]: spawn command to main (windows) : C:/Ruby193/bin/ruby.exe 'C:/Ruby193/bin/fluentd' -c C:/fluent/fluent.conf -u
2014-06-26 21:50:58 +0900 [info]: starting fluentd-0.10.46
2014-06-26 21:50:58 +0900 [info]: is windows platform : true
2014-06-26 21:50:58 +0900 [info]: reading config file path="C:/fluent/fluent.conf"
2014-06-26 21:50:58 +0900 [info]: gem 'fluent-plugin-config-expander' version '0.1.5'
2014-06-26 21:50:58 +0900 [info]: gem 'fluent-plugin-mysql' version '0.0.7'
2014-06-26 21:50:58 +0900 [info]: gem 'fluentd' version '0.10.46'
2014-06-26 21:50:58 +0900 [info]: using configuration file: <ROOT>
  <source>
    type forward
  </source>
  <match iislog.*>
    type mysql
    host 127.0.0.1
    database iislog
    username #your mysql user accout#
    password #your mysql user password#
    flush_interval 1s
    include_time_key yes
    include_tag_key yes
    table accesslog
    key_names time,tag,sip,csmethod,csuristem,csuriquery,sport,csusername,cip,csua,scstatus,scsubstatus,scwin32status,timetaken
    sql INSERT INTO accesslog (time,tag,sip,csmethod,csuristem,csuriquery,sport,csusername,cip,csua,scstatus,scsubstatus,scwin32status,timetaken) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)
  </match>
</ROOT>
2014-06-26 21:50:58 +0900 [info]: adding source type="forward"
2014-06-26 21:50:58 +0900 [info]: adding match pattern="iislog.*" type="mysql"
2014-06-26 21:50:58 +0900 [info]: listening fluent socket on 0.0.0.0:24224
```

大丈夫ですね。

　
#8. IISマシン上のfluentdに、MySQLマシンへのフォワード設定をおこなって起動する

*IISのログファイル→* ![キャプチャ5.PNG](https://qiita-image-store.s3.amazonaws.com/0/31816/e6f4c313-9a3d-44a3-3d16-70ceb3967b2c.png) ~~→標準出力（仮）~~ *→フォワード*

「3. IISのログをfluentdで読み取れるようにする」で記述ししたfluent.confのmatch設定を変更します。
以下の内容を

```lang:前
...
<match **>
  type stdout
</match>
...
```

を

```lang:後
...
<match iislog.*>
  type forward
  send_timeout 60s
  recover_wait 10s
  heartbeat_interval 1s
  phi_threshold 16
  hard_timeout 60s
  flush_interval 1s

  <server>
    host #your mysql serverip# 
    port 24224
    weight 60
  </server>
</match>
...
```

に変更します。
Server1, Server2 双方とも実施します。

これでIISマシン側のfluentd設定も完了です。動かしましょう。
Server1, Server2とも動かします。

```
> fluentd -c C:/fluent/fluent.conf
2014-06-26 21:56:35 +0900 [info]: starting fluentd-0.10.46
2014-06-26 21:56:35 +0900 [info]: is windows platform : true
2014-06-26 21:56:35 +0900 [info]: spawn command to main (windows) : C:/Ruby193/bin/ruby.exe 'C:/Ruby193/bin/fluentd' -c C:/fluent/fluent.conf -u
2014-06-26 21:56:35 +0900 [info]: starting fluentd-0.10.46
2014-06-26 21:56:35 +0900 [info]: is windows platform : true
2014-06-26 21:56:35 +0900 [info]: reading config file path="C:/fluent/fluent.conf"
2014-06-26 21:56:35 +0900 [info]: gem 'fluent-mixin-config-placeholders' version '0.2.4'
2014-06-26 21:56:35 +0900 [info]: gem 'fluent-plugin-config-expander' version '0.1.5'
2014-06-26 21:56:35 +0900 [info]: gem 'fluent-plugin-growthforecast' version '0.2.7'
2014-06-26 21:56:35 +0900 [info]: gem 'fluentd' version '0.10.46'
2014-06-26 21:56:35 +0900 [info]: using configuration file: <ROOT>
  <source>
    type config_expander
    <config>
      type tail
      format /^(?<time>[^ ]* [^ ]*) (?<sip>[0-9.]*) (?<csmethod>[^ ]*) (?<csuristem>[^ ]*) (?<csuriquery>[^ ]*) (?<sport>[0-9]*) (?<csusername>[^ ]*) (?<cip>[0-9.]*) (?<csua>[^ ]*) (?<scstatus>[0-9]*) (?<scsubstatus>[0-9]*) (?<scwin32status>[0-9.]*) (?<timetaken>[0-9]*)$$/
      time_format %Y-%m-%d %H:%M:%S
      path C:/inetpub/logs/LogFiles/W3SVC1/*
      tag iislog.__HOSTNAME__
      pos_file C:/temp/iislog.pos
      reflesh_interval 1s
    </config>
  </source>
  <match iislog.*>
    type forward
    send_timeout 60s
    recover_wait 10s
    heartbeat_interval 1s
    phi_threshold 16
    hard_timeout 60s
    flush_interval 1s
    <server>
      host #your mysql serverip#
      port 24224
      weight 60
    </server>
  </match>
</ROOT>
2014-06-26 21:56:35 +0900 [info]: adding source type="config_expander"
2014-06-26 21:56:35 +0900 [info]: adding match pattern="iislog.*" type="forward"
2014-06-26 21:56:35 +0900 [info]: adding forwarding server '#your mysql serverip#:24224' host="#your mysql serverip#" port=24224 weight=60
2014-06-26 21:56:35 +0900 [info]: following tail of C:/inetpub/logs/LogFiles/W3SVC1/u_ex140626.log
```



　
#9. いざ!

![iis7top.png](https://qiita-image-store.s3.amazonaws.com/0/31816/cd958d35-b933-3ba9-7294-1fc59cab2a58.png)

適当なクライアントマシンからServer1, Server2のルート（http://serverip）にアクセスしましょう。IISの ~~微妙な~~ 初期スクリーンがでますね（上記画像）。

では、MySQLのテーブルを覗いてみましょう。
バーン！

```
mysql> select * from accesslog;
+----------------------+------------------------+--------------+----------+--------------+------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+----------+-------------+---------------+-----------+
| time                 | tag                    | sip          | csmethod | csuristem    | csuriquery | sport | csusername | cip         | csua                                                                                                          | scstatus | scsubstatus | scwin32status | timetaken |
+----------------------+------------------------+--------------+----------+--------------+------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+----------+-------------+---------------+-----------+
| 2014-06-26T04:15:22Z | iislog.WIN-SQB8A3LI55M | xxx.xx.x.x   | GET      | /            | -          | 80    | -          | ccc.c.ccc.c | Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/35.0.1916.153+Safari/537.36 | 200      | 0           | 0             | 10        |
| 2014-06-26T04:15:22Z | iislog.WIN-SQB8A3LI55M | xxx.xx.x.x   | GET      | /welcome.png | -          | 80    | -          | ccc.c.ccc.c | Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/35.0.1916.153+Safari/537.36 | 200      | 0           | 0             | 134       |
| 2014-06-26T04:15:22Z | iislog.WIN-SQB8A3LI55M | xxx.xx.x.x   | GET      | /favicon.ico | -          | 80    | -          | ccc.c.ccc.c | Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/35.0.1916.153+Safari/537.36 | 404      | 0           | 2             | 56        |
| 2014-06-26T04:15:43Z | iislog.WIN-JNJ9JSKTQUU | yyy.yy.y.yyy | GET      | /            | -          | 80    | -          | ccc.c.ccc.c | Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/35.0.1916.153+Safari/537.36 | 200      | 0           | 0             | 29        |
| 2014-06-26T04:15:43Z | iislog.WIN-JNJ9JSKTQUU | yyy.yy.y.yyy | GET      | /welcome.png | -          | 80    | -          | ccc.c.ccc.c | Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/35.0.1916.153+Safari/537.36 | 200      | 0           | 0             | 137       |
| 2014-06-26T04:15:43Z | iislog.WIN-JNJ9JSKTQUU | yyy.yy.y.yyy | GET      | /favicon.ico | -          | 80    | -          | ccc.c.ccc.c | Mozilla/5.0+(Windows+NT+6.3;+WOW64)+AppleWebKit/537.36+(KHTML,+like+Gecko)+Chrome/35.0.1916.153+Safari/537.36 | 404      | 0           | 2             | 61        |
+----------------------+------------------------+--------------+----------+--------------+------------+-------+------------+-------------+---------------------------------------------------------------------------------------------------------------+----------+-------------+---------------+-----------+
6 rows in set (0.00 sec)
```

それっぽいですね！
tag部分にもちゃんとホスト名が入っています。わーい。

データの取り出しや可視化やら分析やらはお好みで。

　
#10. 注意事項およびその他
設定のパラメータなどは環境や負荷にあわせて設定しましょう。

おわり