27
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

NginxのアクセスログをJSON形式で出力する

Last updated at Posted at 2018-03-18

TL;DR

log_format ディレクティブでパラメータ escape=json を指定する。

nginx.conf
http {
  :
  log_format json escape=json '{"time": "$time_iso8601",'
    '"host": "$remote_addr",'
    '"vhost": "$host",'
    '"user": "$remote_user",'
    '"status": "$status",'
    '"protocol": "$server_protocol",'
    '"method": "$request_method",'
    '"path": "$request_uri",'
    '"req": "$request",'
    '"size": "$body_bytes_sent",'
    '"reqtime": "$request_time",'
    '"apptime": "$upstream_response_time",'
    '"ua": "$http_user_agent",'
    '"forwardedfor": "$http_x_forwarded_for",'
    '"forwardedproto": "$http_x_forwarded_proto",'
    '"referrer": "$http_referer"}';

  server {
    :
    access_log /path/to/access_log json; # 上で設定したjsonフォーマットを使う
    :
  }
  :
}

解説

この escape パラメータのデフォルト値は default である。
この場合、 " (0x22)や ' (0x27)はそれぞれ \x22, \x27 のようにエスケープされる。1

json オプションはNginx 1.11.8で導入された。

また、Nginx 1.13.10では escape=none によって、エスケープしないというオプションが追加されるようだ。2

数値を数値型で扱わないのはなぜか?

$status$request_time のような、本来JSONの数値型で扱うべき値も "$status" のように文字列型で扱っていることが気になるという人がいるかもしれない。

これらのような値をクォートしない形式で設定するとどうなるだろうか。
実は、値が取得できないときに空文字になり、invalidなJSONになってしまう。
結果として、エラーによりログ出力ができなくなってしまう。

そこで、ここでは簡単のため文字列型で扱う例を示した。

参考

脚注

  1. 0x00-0x1F, 0x7F-0xFFの範囲の文字も同様にエスケープされる。参考: http://nginx.org/en/CHANGES v0.7.0, v1.1.6の変更。

  2. https://trac.nginx.org/nginx/ticket/1450 のパッチによるようだ。

27
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
19

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?