Un nouveau monde parfumé

香り立つ備忘録

HAProxy のログを journald のみで保存する

どうも。systemd シンパです。

で、rsyslogd がいない Ubuntu でデフォルト設定よろしく /var/lib/haproxy に chroot などしていると、/var/log/haproxy.log が出ません。

 # cat /etc/haproxy/haproxy.cfg 
global
        log /dev/log    local0
        log /dev/log    local1 notice
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
...

 # cat /var/log/haproxy.log
cat: /var/log/haproxy.log: No such file or directory

これは、ログをファイルに書き出すのが実際には RSyslog の役目*1で、その設定の中で chroot 先に rsyslogd のソケットを作っているためです。

 # cat /etc/rsyslog.d/49-haproxy.conf 
# Create an additional socket in haproxy's chroot in order to allow logging via
# /dev/log to chroot'ed HAProxy processes
$AddUnixListenSocket /var/lib/haproxy/dev/log

# Send HAProxy messages to a dedicated logfile
if $programname startswith 'haproxy' then /var/log/haproxy.log
&~

当然 rsyslogd が動作していない環境では /dev/log への送信ができなくなります。

 # ls -l /var/lib/haproxy/dev
total 0

ではどうするか。当然一番簡単なのは RSyslog をインストールして起動することですが、そうしたくない人はせっかく動いてる systemd-journald に送りつけましょう。

そんなわけでこんな感じの .mount ユニットを書く:

 # cat > /etc/systemd/system/var-lib-haproxy-dev-log.mount
[Unit]
Description=Mount /run/systemd/journal/dev-log to haproxy chroot
ConditionPathExists=/var/lib/haproxy/dev/log
PartOf=haproxy.service
Before=haproxy.service

[Mount]
What=/run/systemd/journal/dev-log
Where=/var/lib/haproxy/dev/log
Type=none
Options=bind

[Install]
WantedBy=haproxy.service

.mount は Where ダイレクティブに書いた内容が存在しないとディレクトリを新たに切っちゃうので、空のファイルを置いておきます。 *2

 # touch /var/lib/haproxy/dev/log

後はイネェーブルしておけば PartOf の効果で haproxy の起動時にこいつも起動される:

 # systemctl daemon-reload
 # systemctl enable var-lib-haproxy-dev-log.mount
 # systemctl restart haproxy

後は haproxy.cfg 側の log 設定を好きにしてください。 local1 つけて送ってる設定はもう要らないと思います。

アクセスログ(info/option httplog)だけ見たいときはこうじゃ:

 # journalctl SYSLOG_FACILITY=16 -u -p info..info
-- Logs begin at Fri 2020-04-04 01:47:14 JST, end at Sun 2020-04-12 10:05:01 JST. --
Apr 12 09:10:44 Mars1B haproxy[11947]: 192.168.21.50:56676 [12/Apr/2020:09:10:44.043] http_in~ darkhttpd_local/main 0/0/7/1/8 304 136 - - ---- 1/1/0/1/0 0/0 "GET "
Apr 12 09:24:07 Mars1B haproxy[25282]: 192.168.21.50:57080 [12/Apr/2020:09:24:07.289] http_in~ darkhttpd_local/main 0/0/6/1/7 304 136 - - ---- 1/1/0/1/0 0/0 "GET "
Apr 12 09:24:09 Mars1B haproxy[25282]: 192.168.21.50:57080 [12/Apr/2020:09:24:09.708] http_in~ darkhttpd_local/main 0/0/0/2/2 404 390 - - ---- 1/1/0/1/0 0/0 "GET "

めんどくせえやっぱファイルでくれやって人は素直に RSyslog 入れてください。現場からは以上です。

*1:HAProxy はログを syslog デーモンに送る機能しか持っておらず、ファイルに書き出す機構を持ちません

*2:例では ConditionPathExists も付けてる ちゃんとしたい人(?)は systemd-tmp-files を使ってください