4

I'm configuring the nginx access_log to output in JSON format to use with other tools.

The data I want includes info about the compression. I have gzip on, but the only thing I'm getting for the gzip_ratio is -.

To confirm, the embedded var is $gzip_ratio.

http://nginx.org/en/docs/http/ngx_http_gzip_module.html

Here's the definition of my log_format:

log_format  main_json '{"time": "$time_iso8601", '
                  '"remote_addr": "$remote_addr", '
                  '"body_bytes_sent": "$body_bytes_sent", '
                  '"gzip_ratio": "$gzip_ratio", '
                  '"status": "$status", '
                  '"request": "$request_time", '
                  '"request_method": "$request_method", '
                  '"http_referrer": "$http_referer", '
                  '"http_user_agent": "$http_user_agent", '
                  '"http_x_forwarded_for": "$http_x_forwarded_for", '
                  '"request_time": "$request_time", '
                  '"upstream_response_time": "$upstream_response_time"}';

Here are the gzip settings in nginx.conf:

gzip  on;
gzip_proxied any;
gzip_types text/plain text/xml text/css application/x-javascript text/javascript application/xml+rss text/json application/json;

And here is the output in the access_log:

{
    "time":"2015-02-03T14:26:26+00:00",
    "remote_addr":"[IP]",
    "body_bytes_sent":"574",
    "gzip_ratio":"-",
    "status":"200",
    "request":"0.064",
    "request_method":"GET",
    "http_referrer":"-",
    "http_user_agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2293.0 Safari/537.36",
    "http_x_forwarded_for":"-",
    "request_time":"0.064",
    "upstream_response_time":"0.064"
}

So, it appears that things are not being compressed. However, I've run cURL to test for compression, and here are the results:

[~]$ curl https://[URL] --silent --write-out "size_download=%{size_download}\n" --output /dev/null
size_download=3297
[~]$  curl https://[URL] --silent -H "Accept-Encoding: gzip,deflate" --write-out "size_download=%{size_download}\n" --output /dev/null
size_download=859

So, from actually measuring the size of the response, it seems it is being compressed. However, the logs are still missing the gzip_ratio. The body_bytes_sent in each request's log matches up to the bytes reported by cURL (slight variation w/ compressed response).

{"time": "2015-02-03T14:57:11+00:00", "remote_addr": "[IP]", "body_bytes_sent": "3297", "gzip_ratio": "-", "status": "200", "request": "0.477", "request_method": "GET", "http_referrer": "-", "http_user_agent": "curl/7.37.0", "http_x_forwarded_for": "-", "request_time": "0.477", "upstream_response_time": "0.477"}
{"time": "2015-02-03T14:57:20+00:00", "remote_addr": "[IP]", "body_bytes_sent": "871", "gzip_ratio": "-", "status": "200", "request": "0.676", "request_method": "GET", "http_referrer": "-", "http_user_agent": "curl/7.37.0", "http_x_forwarded_for": "-", "request_time": "0.676", "upstream_response_time": "0.676"}

Anyone know how I can get the actual gzip_ratio?

2 Answers 2

1

Either you are using a buggy version of nginx or your test method had some flaws. I have just confirmed that $gzip_ratio in a log_format definition works perfectly fine in nginx 1.9.1.

I have seen $gzip_ratio to only equal - when no compression was performed. In all other cases it held a numeric value.

4
  • That's the same link I referenced in my question, our settings are nearly identical, less text/json, and I put faith in curl. All of that was included in the question.
    – gotmikhail
    Commented Jun 8, 2015 at 12:20
  • Sorry, I actually let some days pass between reading your question and writing my answer. I will removed these parts that you have already referred to. I also know that my answer ("you must have done something wrong") might not be the most helpful one, but I figured this is better than leaving this un-answered forever. I think the crucial insight here is that this is not an nginx bug which would need to be reported. Commented Jun 8, 2015 at 12:23
  • I noticed the detail I left out was the second log, which had a larger value in body_bytes_sent. So, looks like it was compressing, but there at least was a bug with the $gzip_ratio field. I actually haven't checked this in quite a while, I found another solution, but will review the nginx version and report back.
    – gotmikhail
    Commented Jun 8, 2015 at 12:30
  • When testing with curl, I also did not see gzip compression ratio in Nginx logs. Works fine when browser is used. BTW; GeoIP in Nginx logs also does not work with curl testing.
    – Gusjew
    Commented Nov 7, 2019 at 3:34
0

Encountered the same recently.

$gzip_ratio is only available if nginx does the compression itself. It will NOT be available if it actually is the upstream server that does the compression in a reverse-proxy/load-balancer scenario; that would match all your symptoms (response is actually compressed when tested with cURL).

A way to log that scenario is to include $sent_http_content_encoding and/or $upstream_http_content_encoding in your logs; it will contain "gzip".

Also worth checking for gzip_min_length and gzip_types config options to make sure responses actually qualify for gzipping.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .