はじめに
HA Proxy のログは syslog を経由して下記のように一つの haproxy.log ファイルに出力していますが…
frontend セクションを複数設定している場合には frontend 毎にログを異なるファイルに分けれれば色々と嬉しいような気がしたので試してみました。
悩む
ググったところ rsyslog で頑張れや…的な情報しか見つからず、諦めようとしていた矢先にログを何とかしたいなら泣く子も黙る fluentd を使うことを思い付きました。処理の流れとしては以下のような流れにすることを目論んでいます。
やってみた
結果
- 条件付きで出来ました
やり方
haproxy のログフォーマット
以下のような感じで Custom log format を使いました。
log-format %{+Q}o %{-Q}ci - - [%T] %r %ST %B "" "" %cp %ms %ft %b %s
ポイントは frontend の名前を意味する %ft を設定して frontend_name_transport をログに記録します。上記のフォーマットで以下のようなログが出力されます。フォーマットの詳しい解説はこちら。
xxx.xxx.xxx.xxx - - [27/Jul/2014:15:20:58 +0000] "GET /check HTTP/1.1" 200 293 "" "" 61819 734 "cluster1" "backend1" "web1"
in_tail プラグインの format
以下のような format を書きました。
format /^ +(?[^ ]*) [^ ]* (?[^ ]*) [(?[^]]*)] "(?S+)(?: +(?[^ ]*) +S*)?" (?[^ ]*) (?[^ ]*) [^ ]* [^ ]* (?[^ ]*) (?[^ ]*) "(?[^ ]*)" "(?[^ ]*)" "(?[^ ]*)"$/
ポイントは
^ +(?[^ ]*)
なぜか haproxy のログは行頭に半角スペースが入るようなので上記のように半角スペースを入れてあげます。後はシンプルにパターンマッチを重ねていくだけです。尚、format を書くにあたっては以下のサイトがとても役に立ちました。
有難うございます!
fluent-plugin-rewrite
今回は frontend 毎(frontend_name_transport 毎)にログ出力を分けるにあたっては以下のプラグインを利用させて頂きました。
fluent-plugin-rewrite を以下のように設定しました。
type copy
type file
path /tmp/haproxy.log
type rewrite
key frontend_name_transport
pattern ^(cluster1)
append_to_tag true
fallback others
type file
path /tmp/cluster1.log
type file
path /tmp/haproxy-other.log
挙動としては以下の通りです。
- in_tail プラグインでパースされたログには haproxy というタグが付く
- haproxy タグの付いたログは copy プラグインでファイル出力と rewrite フィルターによって処理される
- rewrite フィルターで key が frontend_name_transport で値に cluster1 が含まれるログを抽出
- 抽出したログに haproxy.cluster1 というタグを付けて emit する
- cluster1 にマッチしないログは haproxy.other というタグをつけて emit する
振り分けられたログ…
見てもどうこうってことはありませんが…
2014-07-27T15:20:58Z haproxy.cluster1 {"host":"xxx.xxx.xxx.xxx","user":"-","timestamp":"27/Jul/2014:15:20:58 +0000","method":"GET","path":"/check","code":"200","size":"293","client_port":"61819","accept_date_milliseconds":"734","frontend_name_transport":"cluster1","backend_name":"backend","server_name":"web1"}
ちゃんと frontend_name_transport が cluster1 となっているログのみがログに記録されています。
という感じで
fluent-plugin-rewrite の rule で指定している frontend_name_transport のパターンを以下のような感じで追加していけば良さそうです。
pattern ^(cluster1|cluster2|cluster3)
マジ、有難うございます…fluentd 様、様。
元記事は、こちら