この記事は、Fluentd Advent Calendar 2015 - Qiita の16日目の記事です。
IISでwebサービスを運営している環境で、nxlog+fluentdを使ってログ収集の環境を構築して半年程運用したので、その話を書こうと思います。
Windows系の記事はあまり響く方がいないのであれですが誰かの参考になれば。
※この記事を書いている最中にfluentdがwindowsに正式対応した事を知ったので、あんまり今後は需要がないかもしれません。。
##全体の構成
##なぜnxlog??
- 検証・導入の時点でwindows版fluentdが開発版で導入事例もなかった。。
- Webアプリケーションサーバに負荷をかけないツールを使う必要があった
- Cで書かれた軽量ツールで、負荷試験したところCPU使用率1%以内,Memも負荷をかけても2,30MBしか使用しなかった
- Input,Processor,Outputという3段階構成で各処理コンフィグに書くので、コンフィグも見やすい
- buffering機構,cache機構(positionファイル)があるので、取りこぼしや重複が発生しないアーキテクチャ
fluentdで担保されている部分をWindowsで出来るツールはないかと探した結果がnxlogでした。
##fluentdの設定
###[工夫してる点]
-
multi_process_pluginを使いサービス種別毎にListenポートを分ける事でfluentdのタグを区別
※送信(nxlog)側で、タグをつけれない為 - 同一プロセスの中で、ログ種類を区別する時の為に、parser時にtagsというキーを追加
- プロセスのエラーは、td-agent.logには出ないので、プロセス毎にロギングを指定してwarn以上のログはslackに通知
###td-agent.confサンプル
## match tag=debug.** and dump to console
<match debug.**>
type stdout
</match>
## live debugging agent
<source>
type debug_agent
bind 127.0.0.1
port 24230
</source>
##マルチプロセス化
<source>
type multiprocess
<process>
cmdline -c /etc/td-agent/td-agent_child1.conf --log /var/log/td-agent/td-agent1_st.log
sleep_before_start 1s
sleep_before_shutdown 5s
</process>
</source>
###td-agent_child1.confサンプル
※エラー検知の為に、warn以上のログをプロセス毎のタグをつけてslackに通知
####
## タグ:
## 機能:
<source>
type syslog
protocol_type tcp
port 5100
tag xx.iislog
</source>
@include conf.d/iislog.conf
<match fluent.**>
type record_modifier
tag internal.message
include_tag_key
tag_key original_tag
</match>
<filter internal.message>
type grep
exclude1 message .+(Version: |Date: |Fields: |Software: ).+
</filter>
<filter internal.message>
type grep
regexp1 original_tag fluent.(warn|error|fatal)
</filter>
<match internal.message>
type buffered_slack
webhook_url [URL]
channel [channel名]
username fluentd
color danger
icon_emoji :rotating_light:
message "Level:%s [タグ名] Time:%s\r\nMessage:%s"
message_keys original_tag,time,message
flush_interval 5s
log_level warn
</match>
###iislog.confサンプル
#####【アウトプット】
- BigQueryにバッチインサート用の一時ファイル(1時間単位)
※BigQueryの場合は、-はフィールド名に使えないので注意 - Elasticsearchにデイリーインデックスでエクスポート
#####【IISログならでは】
- parserで、nxlogから送ったmessage部分を各キーにparseする
- record_reformerでJST時間に変換(ElasticsearchにJSTで入れたい為)
<match xx.iislog.*.*>
type parser
add_prefix parse
format /^(?<tags>.+)\s(?<time>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})\s(?<s_sitename>[^ ]*)\s(?<s_ip>[^ ]*)\s(?<cs_method>[^ ]*)\s(?<cs_uri_stem>[^ ]*)\s(?<cs_uri_query>[^ ]*)\s(?<s_port>[^ ]*)\s(?<cs_username>[^ ]*)\s(?<c_ip>[^ ]*)\s(?<User_Agent>[^ ]*)\s(?<Referer>[^ ]*)\s(?<sc_status>[^ ]*)\s(?<sc_substatus>[^ ]*)\s(?<sc_win32_status>[^ ]*)\s(?<sc_bytes>[^ ]*)\s(?<cs_bytes>[^ ]*)\s(?<time_taken>[^ ]*)\r/
key_name message
types sc_status:integer,time_taken:integer,sc_bytes:integer,cs_bytes:integer
</match>
<match parse.xx.iislog.*.*>
type copy
<store>
type file
path /var/log/td-agent/bq/bqfile_iis
time_slice_format %Y%m%d
include_time_key true
time_format %Y-%m-%d %H:%M:%S
format json
buffer_type file
buffer_path /var/log/td-agent/bq/buffer/bq_iis
buffer_chunk_limit 2g
buffer_queue_limit 10
flush_interval 1h
#flush_at_shutdown true
compress gzip
</store>
<store>
type record_reformer
tag ${tag_prefix[1]}.elastic
jst_time ${(time + (9 * 60 * 60)).strftime('%Y-%m-%dT%H:%M:%S%z')}
</store>
</match>
<match parse.xx.elastic>
type elasticsearch
host localhost
port 9200
logstash_format true
time_key jst_time
logstash_prefix iis_log
logstash_dateformat %Y.%m.%d
type_name iis_log
buffer_type file
buffer_path /var/log/td-agent/buffer/iis_es
buffer_chunk_limit 3m
buffer_queue_limit 1000
flush_interval 3s
flush_at_shutdown true
retry_wait 1s
retry_limit 17
</match>
##nxlogの設定
収集対象の、WindowsServerでの設定
インストールは、こちら からmsiパッケージをダウンロードしてインストールするだけ!
C:/Program Files (x86)/nxlog/nxlog.conf #conf.d配下をinclude
/con.d/xxx.conf
/xxx2.conf
###nxlog.confサンプル
うちだと、ログやバッファはD:¥nxlogに作成するので、その場合は、最初にディレクトリを作成しておく必要がある。
#define ROOT C:\Program Files\nxlog
define ROOT C:/Program Files (x86)/nxlog
define DATA_DIR D:/nxlog
define DST_SRV [fluentdが稼働しているサーバのIP]
#Global Directive
#バイナリ置き場
Moduledir %ROOT%/modules
#最終読込位置記憶の為のconfigcache.datの保存場所
CacheDir %DATA_DIR%/data
#ログ出力先
LogFile %DATA_DIR%/data/logs/nxlog.log
#ログレベル: CRITICAL, ERROR, WARNING, INFO, DEBUG
LogLevel ERROR
#何に使っているかは不明
SpoolDir %DATA_DIR%/data
#<Extension _syslog>
<Extension syslog>
Module xm_syslog
</Extension>
<Extension charconv>
Module xm_charconv
AutodetectCharsets utf-8, euc-jp, utf-16, utf-32, iso8859-2
</Extension>
# エスケープ注意
include %ROOT%\conf\conf.d\\*.conf
#####xxx.confサンプル(includeされるファイル)
#####サンプル内にコメントでIIS用のTIPSを。
<Input in_fgac>
Module im_file
File "D:\[IISログディレクトリ]\ex*.log"
SavePos TRUE
ReadFromLast TRUE
InputType LineBased
# shift_jisに設定しないとIISログの日本語が文字化けするので注意
Exec convert_fields("shift_jis", "utf-8");
</Input>
<Processor fg_t>
Module pm_transformer
OutputFormat syslog_bsd
# IISログの中身を全て$Message(syslogのmessageキーに詰め込む)
Exec $Message=(": "+$raw_event);
# fluentd側ではsyslogで受信するので、タグが統一されるため、予めタグをnxlogで仕込んでおく場合は下記
# Exec $Message=(": [タグ名] "+$raw_event);
</Processor>
<Processor fg_b>
Module pm_buffer
# 500MB
MaxSize 512000
Type disk
Directory %DATA_DIR%\data\buffer
WarnLimit 1024
</Processor>
<Output out_fgac>
Module om_tcp
Host %DST_SRV%
# fluentdでListenしているポート
Port 5100
</Output>
<Route fgac_r>
Path in_fgac => fg_t => fg_b => out_fgac
</Route>
この構成で、nxlog,fluentdにはこれまで障害が出たことはなく、4000万/dayくらいのログを捌いているのでIISログを扱うには中々いい組み合わせかなと。
もう少しユースケースが出てきたら、Windows版fluentdも試してみたいとは思っています!タグを収集側でつけれると格段に楽になるので!