fluentdでログ中の特定キーワード出現回数を集計しTreasure Dataへインポートする
やりたいこと
外部からのアクセスを、ある条件をもとにブロックした時、/var/log/nginx/blocked.log
というファイルにログ記録しています。
集計単位(10分毎とか)ごとに、その件数をカウントし、Treasure Dataへインポートするためにやったことのメモです。
前提
- 全部ログ突っ込んで抜き出したら? > ログ量が膨大なので...
必要なtd-agent-gem
キーワードをもとにログ行数をカウントするのに使います github.com
Treasure Dataへインポートするために使います* github.com
conf
<source> @type tail format /^.+nginx: (?<time>\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}) \[(?<log_level>\w+)\] (?<pid>\d+).(?<tid>\d+): (?<message>.*)$/ time_format %Y/%m/%d %H:%M:%S path /var/log/nginx/%Y%m%d/blocked.log_%Y%m%d_%H pos_file /var/log/nginx/blocked.log.pos tag nginx-blocked.log </source> <match nginx-blocked.log> type grepcounter count_interval 600 input_key message regexp BLOCKED threshold 1 add_tag_prefix blocked.count </match> <filter blocked.count.nginx-blocked.log> @type record_transformer enable_ruby remove_keys message,input_tag,input_tag_last <record> time ${Time.now.to_i} </record> </filter> <match blocked.count.nginx-blocked.log> @type tdlog apikey xxxxxxxxxxxxxxxxxxxxxxxxxxxxx auto_create_table database test table blocked_count buffer_type file buffer_path /var/log/td-agent/buffer/td flush_interval 600s </match>
補足
format /^.+nginx: (?<time>\d{4}/\d{2}/\d{2} \d{2}:\d{2}:\d{2}) \[(?<log_level>\w+)\] (?<pid>\d+).(?<tid>\d+): (?<message>.*)$/ time_format %Y/%m/%d %H:%M:%S
でログ形式・Time形式を指定しており、該当したものに nginx-blocked.log
tagを付与しています。
ここで行数のカウントをおこなっています。 内容としては 600sec
単位にBLOCKED
キーワードを抜き出しています。threshold 1
と本来の使い方では回数がしきい値超えた時にmailする、などとなるようですが、今回は全て記録したいため1
としました。filterを使用して以降の処理 tdlog
で {"time": 1234567, "count": 123 }のようなjson形式でTreasure Dataへなげれるように整形しています。 record内でrubyを使いたいので
enable_rubygrepcounterから使わないキーも渡ってきているので
remove_keys message,input_tag,input_tag_lastで削除します。
recordディレクティブ内で
time` というキーでunixtimestampを列追加していますTreasure Dataにデータインポートしています。 使い方は標準の内容なので割愛
- Apacheのログを全部TDに突っ込む
- 条件に一致したnginxログをTDに突っ込む
のような方法はすぐ見つかったのですが、集計した個数を一行TDに突っ込む方法が見つからず苦戦しました。(そもそもTDの使い方にあっているか謎) 参考までに