Read the fields in an Nginx access log
Interpret the combined format, distinguish literal placeholders from variables, and add timing fields that your log parser can reliably consume.
First identify the active log_format; an access log does not have universal column positions. Nginx's predefined combined format includes the client address, a literal dash, authenticated user, timestamp, request, status, response-body bytes, referrer, and user agent.
Read a combined record
The built-in format has this structure. If you define a similar format yourself, give it a distinct name:
log_format site_combined '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
Example:
192.168.1.1 - - [15/Jan/2024:10:30:45 +0800] "GET /api/users HTTP/1.1" 200 1234 "https://example.com/page" "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
| Value | Meaning |
|---|---|
192.168.1.1 |
$remote_addr, the effective client address seen by Nginx. |
First - |
A literal placeholder in this format. |
Second - |
$remote_user; no authenticated username is available. |
| Bracketed timestamp | $time_local, including its numeric timezone offset. |
| Quoted request | Method, request target, and protocol; the target may include a query string. |
200 |
$status, the recorded response status. |
1234 |
$body_bytes_sent, excluding response headers. |
| Quoted referrer | $http_referer, supplied by the client when present. |
| Quoted user agent | $http_user_agent, also supplied by the client. |
Spaces inside quoted fields make naive whitespace splitting unreliable for general parsing. Missing values and escaped characters need handling too.
Add fields for performance analysis
Define a new format inside http, then reference its name in the desired logging context:
log_format performance '$remote_addr [$time_iso8601] "$request" '
'$status $body_bytes_sent '
'request_time=$request_time '
'upstream_time="$upstream_response_time"';
access_log /var/log/nginx/performance.log performance;
$request_time is overall request-processing time in seconds with millisecond resolution. $upstream_response_time describes upstream response timing and may contain multiple values after retries or internal redirects, or - when unavailable. Do not cast the whole field blindly to one number.
$request_length includes the request line, headers, and body. $http_x_forwarded_for is the received forwarding header, not an independently verified client address. Choose only fields needed for diagnosis; URLs and headers may contain sensitive values.
Send a known request, inspect the raw line, then validate the DataKit log collector parser and units. A parser cannot recover timings that Nginx never wrote.
FAQ
Why is remote_addr a proxy address?
That is normally the direct peer. Configure set_real_ip_from and the appropriate real-IP header only for genuinely trusted proxies. Do not trust arbitrary client-supplied forwarding headers.
Can timestamps use ISO 8601?
Yes: $time_iso8601 is suitable for that. $msec provides an epoch timestamp with millisecond resolution; it is a timestamp, not request duration.
Why are some requests missing?
Inspect access_log off, conditional logging, the selected location, buffering and flush behavior, and the actual destination. A request may be logged in the location where processing ends after an internal redirect.
Reference: Nginx access-log formats.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan