はじめに
fluentd(td-agent)を使ってin_tailでapacheのaccessログformat正規表現を作ってみるメモです。
おおよそ先人の方々がいろいろ残してくださった情報のまんまではありますが。。
formatに指定する正規表現がすんなりうまくいかなくて
こちらを参考にほぼ同じような感じで試してみました。
ながれ
1.tailしたいaccessログ
2.format正規表現をスクリプト
3.スクリプトでやってみた完成系とちょこっとメモ
4.tail(とかtail_ex)プラグインに指定する
って感じでメモ
1.tailしたいaccessログ
試したい環境についてはこんな感じです
諸情報
# cat /etc/redhat-release CentOS release 6.4 (Final) # /usr/local/apache2.4/bin/apachectl -v Server version: Apache/2.4.4 (Unix) Server built: Apr 24 2013 16:50:43
httpd.confのfromat指定
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %D" combined
accessログ
実際に出力されるログはこんな感じ
172.21.65.11 - - [07/Jan/2014:16:09:26 +0900] "GET /mypage HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.33 Safari/535.11" 8832
172.21.65.11 - - [07/Jan/2014:16:09:26 +0900] "GET / HTTP/1.1" 200 22660 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.33 Safari/535.11" 150183
172.21.65.11 - - [07/Jan/2014:16:09:30 +0900] "GET /js/libs/jquery.enqt.js HTTP/1.1" 200 4135 "http://hoge.piyo.jp/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.33 Safari/535.11" 282
172.21.65.11 - - [07/Jan/2014:16:09:30 +0900] "GET /css/main.css HTTP/1.1" 200 3098 "http://hoge.piyo.jp/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.33 Safari/535.11" 17479
172.21.65.11 - - [07/Jan/2014:16:09:30 +0900] "GET /img/top/logo.png HTTP/1.1" 200 50999 "http://hoge.piyo.jp/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.33 Safari/535.11" 242440
2.format正規表現をスクリプト
参考にさせて頂いたサイトまんまですがこんな感じでスクリプトを作りました
- vi /etc/td-agent/script/log_format_test.rb
#!/usr/bin/env ruby # -*- coding: utf-8 -*- require 'time' require 'fluent/log' require 'fluent/config' require 'fluent/engine' require 'fluent/parser' $log ||= Fluent::Log.new # debug log = '172.21.65.11' format = /^(?<host>[^ ]+)$/ #time_format = '%d/%b/%Y:%T %z' time_format = '' parser = Fluent::TextParser::RegexpParser.new(format, 'time_format' => time_format) result = parser.call(log) puts result[0] puts result[1] puts Time.at(result[0])
log = '172.21.65.11'
format = /^(?
の部分を最終的なログフォーマットに合わせて
少しずつ文字列を増やしながらテスト実行って感じです。
- 実行結果
# /usr/lib64/fluent/ruby/bin/ruby /etc/td-agent/script/log_format_test.rb 1389087711 {"host"=>"172.21.65.11"} 2014-01-07 18:41:51 +0900
3.スクリプトでやってみた完成系とちょこっとメモ
- 完成系のスクリプト
#!/usr/bin/env ruby # -*- coding: utf-8 -*- require 'time' require 'fluent/log' require 'fluent/config' require 'fluent/engine' require 'fluent/parser' $log ||= Fluent::Log.new # debug log = '172.21.65.11 - - [07/Jan/2014:16:09:26 +0900] "GET /mypage HTTP/1.1" 302 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.33 Safari/535.11" 8832' format = /^(?<host>[^ ]+) [^ ]+ [^ ]+ \[(?<time>[^\]]+)\] "(?<request>[^ ]+ [^ ]+ [^ ]+)" (?<code>[^ ]+) .+ ".+" "(?<ua>.+)" (?<latency>[^ ]+)$/ time_format = '%d/%b/%Y:%T %z' parser = Fluent::TextParser::RegexpParser.new(format, 'time_format' => time_format) result = parser.call(log) puts result[0] puts result[1] puts Time.at(result[0])
- 結果
# /usr/lib64/fluent/ruby/bin/ruby /etc/td-agent/script/log_format_test.rb 1389078566 {"host"=>"172.21.65.11", "request"=>"GET /mypage HTTP/1.1", "code"=>"302", "ua"=>"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.33 Safari/535.11", "latency"=>"8832"} 2014-01-07 16:09:26 +0900
ちょこっとメモ
- hostのとこ
(?
[^ ]+)
rubyの正規表現なんかを見てもらうとより詳しくのってたりしますが「名前付きキャプチャ」を使ってます
この例でいうと、hostという名前尽きキャプチャでパースされたものがjsonになった際に
{host:xxx.xxx.xxx.xxx}
となります。
- timeのとこ
\[(?
正規表現的にはhostのとこと同じで名前付きキャプチャを使ってます。
日時をかこってる[]ははぶいた状態で日時文字列をパースしたいので
\[と\]で囲った中身に名前付きキャプチャになってます。
また完成系のスクリプトの結果を見てもらうとわかるとおり、timeというjsonキー名は出力されません。
\[(?
補足
\[(?
format を自ら設定した場合には、必ず time_format ディレクティブが必要です。普段 format の指定に apache を指定している場合には、fluentd が気を利かせて time_format を暗黙的に設定してくれるので、注意が必要です。
参照:Apache ログを転送するための fluentd 初期設定
とのことなので今回のスクリプトで日付文字列もちゃんとパースしておいて
後でtime_formatに指定する感じになります。
4.tail(とかtail_ex)プラグインに指定する
td-agent.confはこんな感じ
<source> type tail_ex format /^(?<host>[^ ]+) [^ ]+ [^ ]+ \[(?<time>[^\]]+)\] "(?<request>[^ ]+ [^ ]+ [^ ]+)" (?<code>[^ ]+) .+ ".+" "(?<ua>.+)" (?<latency>[^ ]+)$/ time_format %d/%b/%Y:%T %z read_all true path /apache/logs/access_log.%Y-%m-%d pos_file /var/log/td-agent/pos/access_log.pos tag apache.access </source>