jahed.dev

Formatting Nginx Access Logs as JSON

While Nginx and Apache's log format has become pretty standard in the industry, it'd be nice if I could use the same tools for processing them as all my other logs, which are in JSON.

Luckily, Nginx has support for it using the escape=json parameter.

log_format  main  escape=json
  '{'
    '"time_iso8601":"$time_iso8601",'
    '"remote_addr":"$remote_addr",'
    '"server_protocol":"$server_protocol",'
    '"status": "$status",'
    '"body_bytes_sent":"$body_bytes_sent",'
    '"request_time":"$request_time",'
    '"request_method":"$request_method",'
    '"request_uri":"$request_uri",'
    '"request_filename":"$request_filename",'
    '"http_referrer":"$http_referer",'
    '"http_user_agent":"$http_user_agent",'
    '"http_x_forwarded_for":"$http_x_forwarded_for",'
    '"host":"$host"'
  '}';

The most obvious downside to this approach is that there are no null values. Every key will always exist with a string value, and empty values are typically denoted with a "-". So when processing, you'll need to make sure to exclude them.

Also, escape=json only escapes characters for use in JSON strings (for example, / becomes \/). The actual JSON formatting is done manually. So, when you're modifying the log_format to add or remove keys, make sure it's still outputting valid JSON. Specifically ensure commas (,) and speech marks (") are in the right place.

Thanks for reading.