nginx-1.7.1でsyslogにログを飛ばせるようになったので試してみた
nginxのアクセスログやエラーログをsyslogに直接飛ばす機能は商用版のNGINX Plusでのみ提供されていたのだが、1.7.1でオープンソース版にもその機能が取り込まれた。
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
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が必要なのはまぁ良いとしても、記号などのエスケープ処理周りが怪しい感じで若干微妙だった。こちらもその内紹介できればと思う。
追記
@matsuu nginxのsyslog出力はNGX_MAX_ERROR_STR(2048で定義)にsyslogのヘッダを加えた文字数のバッファを持っていて、色々プラマイして実質2000文字前後ですね。
— Takashi Takizawa (@ttkzw) 2014, 6月 3