Operations 6 min read

Master Nginx Log Formatting: Customize, Test, and Optimize Your Access Logs

This guide explains how to use Nginx's HttpLogModule to control log output, defines key directives such as access_log, log_format, and open_log_file_cache, provides example configurations, demonstrates testing with curl, and offers practical tips for per‑location log management to improve troubleshooting and performance.

Raymond Ops
Raymond Ops
Raymond Ops
Master Nginx Log Formatting: Customize, Test, and Optimize Your Access Logs

Introduction

In Nginx, controlling log output is straightforward thanks to the HttpLogModule, which allows you to set the log format and related directives.

2. HttpLogModule Module

2.1 Example

HttpLogModule example
HttpLogModule example

2.2 Directives

access_log Syntax:

access_log [format [buffer=size]] | off

Default:

access_log logs/access.log combined;

Context: http, server, location, if in location, limit_except

log_format Syntax:

log_format name [escape=default|json|none] string ...;

Default:

log_format combined "...";

Context: http

open_log_file_cache Syntax:

open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time]; | open_log_file_cache off;

Default:

open_log_file_cache off;

Context: http, server, location

max

– maximum number of file descriptors stored in the cache (LRU eviction).

inactive

– time after which unused descriptors are removed (default 10 s).

min_uses

– minimum accesses before a descriptor is cached (default 1).

valid

– time to check for the existence of the same‑named file (default 60 s).

off

– disables the cache.

2.3 Test

View the default log format:

Default log format
Default log format

After sending a request, the log shows entries such as two "- -" fields – the first comes from the log_format definition, the second is a placeholder for a null $remote_user.

<code>log_format  main  '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$request_time"';</code>
<code>log_format  remote_main  '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for" "$request_time" "$upstream_response_time" "$upstream_addr" "$upstream_status"';</code>

For faster anomaly detection, define logs per

location

instead of a global http block.

Per‑location log configuration
Per‑location log configuration
<code>access_log  /var/log/nginx/app.log  buffer=32k  flush=5s;</code>

Note: with buffering, logs are written only when the buffer reaches 32 KB or after 5 seconds, whichever comes first.

2.4 Test

Execute a request and inspect the log:

<code>curl http://10.0.10.158/</code>
Log output after curl
Log output after curl

The log clearly shows:

Requested URI:

GET /apache/index.html

Total request time:

0.002

s

Backend processing time:

0.002

s

Backend socket:

10.0.10.159:8080

Backend status:

200
operationsNginxserver configurationaccess_loglog formatlog_format
Raymond Ops
Written by

Raymond Ops

Linux ops automation, cloud-native, Kubernetes, SRE, DevOps, Python, Golang and related tech discussions.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.