Gマイナー志向

とくに意味はありません

nginx-1.7.1でsyslogにログを飛ばせるようになったので試してみた

nginxのアクセスログやエラーログをsyslogに直接飛ばす機能は商用版のNGINX Plusでのみ提供されていたのだが、1.7.1でオープンソース版にもその機能が取り込まれた。

CHANGES

Changes with nginx 1.7.1                                         27 May 2014

    *) Feature: the "error_log" and "access_log" directives now support
       logging to syslog.

早速試してみた。

docker-nginx

syslogサーバのホスト名は仮にlogserverとする。

Dockerfile
FROM centos:latest
ADD nginx.repo /etc/yum.repos.d/
RUN yum install -y nginx
ADD access_log.conf /etc/nginx/conf.d/
EXPOSE 80
CMD ["/usr/sbin/nginx", "-g", "daemon off; error_log syslog:server=logserver,facility=local2 notice;"]
nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
access_log.conf
access_log syslog:server=logserver,facility=local1 main;

具体的な書式は公式のDocumentationを参照

docker-rsyslog

syslogを受けるサーバはこんな感じか。

Dockerfile
FROM centos:latest
RUN yum install -y rsyslog
ADD remote.conf /etc/rsyslog.d/
CMD ["/sbin/rsyslogd", "-c5", "-n"]
remote.conf
$ModLoad imudp
$UDPServerRun 514
$AllowedSender UDP, 127.0.0.0/8, 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16

local1.* /var/log/nginx_access_log
local2.* /var/log/nginx_error_log

AllowedSenderで0/0が書けなかったのでなんかダサい。もっと良い書き方ないものか。

動作確認

アクセスログ

Jun  3 10:53:33 c65d458cb3e9 nginx: 127.0.0.1 - - [03/Jun/2014:10:53:33 -0400] "GET / HTTP/1.1" 200 612 "-" "curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.13.6.0 zlib/1.2.3 libidn/1.18 libssh2/1.4.2"

エラーログ

Jun  3 10:53:23 c65d458cb3e9 nginx: 2014/06/03 10:53:23 [notice] 23#0: start worker processes
Jun  3 10:53:23 c65d458cb3e9 nginx: 2014/06/03 10:53:23 [notice] 23#0: start worker process 25

いいじゃないか、と思うでしょう。しかしsyslogには1行あたりの文字数制限があるため、長いログだとお尻が途切れて残念なことになる。

Jun  3 11:42:42 c65d458cb3e9 nginx: 127.0.0.1 - - [03/Jun/2014:11:42:42 -0400] "GET /12345678901234(中略)012345678

syslog自体は2048文字あたりが上限になるようだが、手元で試した限りは2043文字が上限になった。このあたりの詳細は調べてない。

nginxの派生で独自にsyslog対応されているTengineでも試したが、2043文字あたりが上限になるのは同じだった。syslogの制約だからそりゃそうか。

まとめ

ログをコンテナ内に蓄積しないことでよりImmutable Infrastructureっぽくなるし、1コンテナ1プロセスを実現できていいのだがsyslogには文字数制限があるので注意。

ちなみにnginxから直接fluentdに飛ばせるnginx-fluentd-moduleも試したのだが、受信側fluentdにfluent-plugin-udpが必要なのはまぁ良いとしても、記号などのエスケープ処理周りが怪しい感じで若干微妙だった。こちらもその内紹介できればと思う。

追記