How do I write a separate NGINX access log for selected requests?

The Citead team, updated

In short. Use map to derive a selection variable and access_log with if= to write matching requests to a separate destination.

Definition: A separate conditional NGINX access log records requests in a specified destination when the access_log directive's if= condition has a nonempty value other than 0. A map directive derives that condition from a request or response variable.

Key facts

  • As of 17 October 2026, NGINX's request logging reference documents if= for conditional logging and permits several logs at the same configuration level.
  • NGINX's map reference places map in the http context and supports string and regular expression matches.
  • NGINX's logging guide states that an access_log definition at a particular level overrides settings from previous levels.

How does a condition select requests?

NGINX's conditional logging example maps the response status to a variable named $loggable. Status codes beginning with 2 or 3 produce 0; other values produce 1. The conditional destination therefore excludes successful responses and redirects.

The following configuration fragment adapts that example by retaining an unconditional log alongside the selected log. Both paths are illustrative destinations. The directives belong inside the existing http block:

map $status $loggable {
    ~^[23]  0;
    default 1;
}

access_log /path/to/access.log combined;
access_log /path/to/selected.log combined if=$loggable;

The first directive records all requests covered by this configuration. The second records only those passing the condition. The predefined combined format includes the request, response status and User-Agent header. The User-Agent header is the client identification string supplied with a request.

The map documentation also shows $http_user_agent as an input variable, using an Opera Mini expression. That provides the same mapping mechanism for selecting requests by a header value. A regular expression beginning with ~ matches case sensitively; ~* makes the match case insensitive.

Where can the selected log be written?

The access_log reference accepts a file path as its first parameter and uses combined when no format is specified. A destination beginning with syslog: sends log messages through syslog, a standard for collecting log messages.

Paths containing variables have additional constraints: worker processes need permission to create files in the destination directory, buffered writes are unavailable, and files are opened and closed for each write unless their descriptors are cached with open_log_file_cache.

The logging guide explains why the two log directives belong at the same level when both outputs are required. Adding a conditional log inside a server block overrides inherited logging from http. Requests are logged in the location where processing finishes; the request logging reference notes that an internal redirect can change that location.

How is the configuration checked and applied?

NGINX's command-line reference documents the configuration test:

nginx -t

This checks syntax and attempts to open files referenced by the configuration. The same reference documents nginx -T, which additionally prints the configuration files to standard output.

After a successful test, the Beginner's Guide documents reloading with:

nginx -s reload

The master process checks the new configuration and attempts to apply it. If applying it fails, NGINX continues with the old configuration.

FAQ

Can I keep selected requests in the main log too?

Yes. NGINX's logging guide permits multiple access log definitions at one level. An unconditional destination and a conditional destination at that level retain matching requests in both.

Does an empty condition write a log entry?

NGINX's request logging reference excludes a request from the conditional destination when the condition evaluates to an empty string or 0.

Sources

  1. NGINX, "Module ngx_http_log_module", undated
  2. NGINX, "Module ngx_http_map_module", undated
  3. F5 NGINX, "Configuring Logging", undated
  4. NGINX, "Command-line parameters", undated
  5. NGINX, "Beginner's Guide", undated

Check how a page reads to answer engines. Open the GEO score analyzer

Test a page and see what to fix first

The analysis usually takes less than 10 seconds and needs no account.

400,000+ pages scored in the public benchmark