カメニッキ

カメとインコと釣りの人です

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>

補足

  • /var/log/nginx/%Y%m%d/blocked.log_%Y%m%d_%H を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

でログ形式・Time形式を指定しており、該当したものに nginx-blocked.log tagを付与しています。

  • ここで行数のカウントをおこなっています。 内容としては 600sec 単位に BLOCKED キーワードを抜き出しています。 threshold 1 と本来の使い方では回数がしきい値超えた時にmailする、などとなるようですが、今回は全て記録したいため 1 としました。

  • filterを使用して以降の処理 tdlog で {"time": 1234567, "count": 123 }のようなjson形式でTreasure Dataへなげれるように整形しています。 record内でrubyを使いたいのでenable_ruby grepcounterから使わないキーも渡ってきているのでremove_keys message,input_tag,input_tag_lastで削除します。 recordディレクティブ内でtime` というキーでunixtimestampを列追加しています

  • Treasure Dataにデータインポートしています。 使い方は標準の内容なので割愛


  • Apacheのログを全部TDに突っ込む
  • 条件に一致したnginxログをTDに突っ込む

のような方法はすぐ見つかったのですが、集計した個数を一行TDに突っ込む方法が見つからず苦戦しました。(そもそもTDの使い方にあっているか謎) 参考までに