loganalytics.devOpen analyzer

Guide

Nginx Access Log Format Explained

Every request nginx serves produces one line in the access log. Once you know how that line is built, the whole file stops looking like noise.

The default nginx access log uses the combined format. It packs the client address, the timestamp, the request itself, the response status, how many bytes went back, and two HTTP headers into a single space-separated line. Here is a real line so you can see what you are working with:

203.0.113.42 - - [12/Sep/2026:13:55:36 +0000] "GET /pricing HTTP/1.1" 200 2326 "https://example.com/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0 Safari/537.36"

The combined format, field by field

The combined format is defined inside nginx itself. The directive looks like this, and it lives in thehttp block of your config:

log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

Match each variable against the example line above and the structure falls into place. Here is what each piece means.

FieldVariableWhat it holds
Client IP$remote_addrThe address that opened the connection. Behind a proxy or load balancer this is often the proxy, not the visitor.
Identhard-coded -The old RFC 1413 identity field. Nobody runs identd anymore, so it is always a dash.
Remote user$remote_userThe username from HTTP basic auth. A dash when the request was not authenticated.
Timestamp$time_localLocal server time in the day/month/year:hour:minute:second zone shape, wrapped in square brackets.
Request line$requestThe raw request line: method, path, and protocol, like GET /pricing HTTP/1.1. Quoted because it contains spaces.
Status$statusThe HTTP response code nginx sent back. See the status code reference.
Bytes sent$body_bytes_sentSize of the response body in bytes, not counting headers. Useful for bandwidth math.
Referer$http_refererThe page the visitor came from, if the browser sent it. Often a dash.
User agent$http_user_agentThe client software string. This is where browsers, crawlers, and bots announce themselves.

Common format (CLF)

Before combined became the default, the Common Log Format was the standard. You still see it on older setups and on servers that were configured to match Apache. It is the same line as combined, just without the referer and user agent on the end:

$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent

If your logs stop after the byte count, you are looking at CLF. You lose referer and user agent, which makes bot detection much harder, so most people switch to combined the first time they need to track where traffic comes from.

A note on the request line

The $request field trips up a lot of parsers because it has to be split again into three parts. A malformed request will show up here too. If you see something like "\x16\x03\x01" where a normal request line should be, that is usually someone sending raw TLS bytes at your plain HTTP port, or a scanner probing for something. Those lines often pair with a 400 status.

Customizing the format

You can define your own format and point an access_log directive at it. A common addition is request timing and the real client IP when nginx sits behind a CDN or load balancer:

log_format extended '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent" '
                    'rt=$request_time uct="$upstream_connect_time" '
                    'xff="$http_x_forwarded_for"';

access_log /var/log/nginx/access.log extended;

A few variables worth knowing when you build a custom format:

One thing to watch: if you change the format, anything that parses the log needs to know. A field added in the middle shifts everything after it. Adding new fields to the end is the safer move.

Where to go next

Now that the line structure is clear, the natural next steps are reading the status codes and pulling signal out of the file. Start with the step-by-step analysis guide, or learn to spot unwanted crawlers in how to detect bad bots.

Try the free nginx log analyzer

Paste or drop your access log and get instant parsing, traffic breakdowns, and bot detection. Everything runs in your browser, so the file never leaves your machine.

Open the analyzer