When working with Nginx, many developers coming from Apache background miss the straightforward %I
(bytes received) and %O
(bytes sent) log format variables. Nginx handles this differently but provides equivalent capabilities through its log module variables.
Nginx provides these essential variables for request/response measurement:
$request_length
- Total size of request (headers + body)$bytes_sent
- Number of bytes sent to client (headers + body)$body_bytes_sent
- Body bytes sent (excluding headers)
Here's how to configure your nginx.conf to log these values:
log_format detailed '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'req_size=$request_length resp_size=$bytes_sent';
access_log /var/log/nginx/access.log detailed;
For more comprehensive logging including response time and upstream data:
log_format full_tracking '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'$request_time $upstream_response_time '
'req=$request_length resp=$bytes_sent '
'upstream=$upstream_bytes_received';
server {
access_log /var/log/nginx/full_access.log full_tracking;
# ... other server configuration
}
1. For accurate POST/PUT request body sizes, ensure client_body_buffer_size is properly configured
2. $bytes_sent
includes both headers and body, while $body_bytes_sent
shows body only
3. These variables won't show compressed sizes when gzip is enabled
After making changes, test with:
sudo nginx -t
sudo systemctl reload nginx
Sample log output will then show:
192.168.1.100 - - [01/Mar/2023:10:15:32 +0000] "GET /api/data HTTP/1.1" 200 1234 "https://example.com" "Mozilla/5.0" req_size=567 resp_size=2345
In web server administration, tracking the size of HTTP requests and responses is crucial for performance monitoring, debugging, and security analysis. While Apache uses %I
and %O
for this purpose, Nginx requires a different approach.
Nginx provides built-in variables that capture various aspects of request and response sizes:
$request_length - Total size of request (including headers and body)
$bytes_sent - Number of bytes sent to client (response size)
$body_bytes_sent - Response body size excluding headers
$upstream_response_length - Size of response from upstream server
To log these values, modify your nginx.conf or server block configuration:
log_format extended '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'req_size=$request_length resp_size=$bytes_sent';
server {
access_log /var/log/nginx/access.log extended;
# ... other server configurations
}
For more granular control with OpenResty or Nginx+Lua:
log_format lua_extended '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'req_hdr=$req_headers_size req_body=$req_body_size';
server {
access_log /var/log/nginx/access.log lua_extended;
set_by_lua_block $req_headers_size {
return #ngx.req.raw_header()
}
set_by_lua_block $req_body_size {
ngx.req.read_body()
return #ngx.req.get_body_data() or 0
}
}
Your logs will now show entries like:
192.168.1.100 - - [10/Oct/2023:14:30:45 +0000] "GET /api/data HTTP/1.1" 200 1423 "https://example.com" "Mozilla/5.0" req_size=583 resp_size=1624
While these logging options are useful, be aware that:
- Logging additional variables increases disk I/O
- For high-traffic sites, consider sampling or conditional logging
- Reading request bodies with Lua may impact performance