Recommended Free Tools
NGINX request logging is provided by the ngx_http_log_module. On a normal Linux package installation you usually do not install a separate module: define a log_format, point access_log at a writable file (or a syslog destination), test the configuration, reload NGINX, and generate a request to verify the result.
Need a server to try this on? Antihost offers Linux VPS plans with NVMe storage, full root access and a 14-day free trial.
The exact configuration and log paths depend on how your binary was built. Start with nginx -V instead of assuming that every distribution uses /etc/nginx/nginx.conf and /var/log/nginx/access.log. The build arguments and the active include files are the authority for the server you are changing.
As an Amazon Associate I earn from qualifying purchases.
Free tools Windows power users keep installed
One-click scans. No signup required.
What the NGINX log module does
The ngx_http_log_module writes HTTP request logs in a format you specify. Its two directives do different jobs:
log_formatdefines the fields and layout of each record.access_logselects the destination and the format, and can also control buffering, compression, flushing, and conditional logging.
Logging is separate from NGINX’s error log. The access log records requests such as method, URI, response status, bytes sent, referrer, and user agent. The error log records startup failures, upstream errors, permission problems, and other diagnostics. Enabling one does not automatically change the other.
#1 Best Overall
access_log is valid in the http, server, location, if in location, and limit_except contexts. A setting in a more specific context can override an inherited setting, including access_log off;.
Find the configuration and log paths used by your binary
Package layouts vary between distributions, containers, source builds, and manually installed binaries. Run this command as the same user or shell environment that normally starts NGINX:
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchnginx -V 2>&1 | awk -F: '/configure arguments/ {print $2}' | xargs -n1
The output lists configure arguments. Pay particular attention to:
--conf-path: the primarynginx.confpath.--error-log-path: the compiled-in default error-log path.--http-log-path: the compiled-in primary request-log path.- Module and prefix arguments that indicate where an installation keeps includes, modules, and runtime files.
An official package example uses /etc/nginx/nginx.conf and places access and error logs below /var/log/nginx/, but those are examples, not universal paths. Use the paths reported by your installed build and inspect the include statements in the active configuration.
If the command fails because the executable is not in your shell’s PATH, locate the service’s binary first (for example, with your distribution’s package information or the command shown in the service unit), then run that binary with -V. Do not edit a similarly named configuration file for a different NGINX installation.
Inspect the effective configuration and includes
The main file commonly includes a directory of virtual-host files. A setting in an included file is part of the same configuration tree. To print the complete configuration that NGINX would load, use:
Rank #2
sudo nginx -T
Review the output for the active http block, every log_format, each access_log, and any access_log off;. This also helps when a distribution’s visible template differs from the file actually loaded by the service.
Do you need to install or compile a module?
For ordinary request logging, usually not. NGINX’s package documentation distinguishes modules compiled into the main binary from selected modules delivered as dynamic packages. The main package is built with modules that do not require additional libraries, while some optional features are shipped separately. Request logging is normally available in a standard HTTP build; confirm by testing the directives rather than downloading an unrelated module package.
A dynamic module must be loaded with a top-level load_module directive before its directives can be used. Do not add load_module for a module that is already compiled into the binary, and do not guess a module filename. If NGINX reports an unknown log_format or access_log directive, check that the service is using the binary you inspected, that the configuration is not from another installation, and that the build includes HTTP support. Only after those checks should you consider replacing the package or building from source.
When a source build is appropriate
Compile NGINX only when you have a concrete requirement that the available package cannot meet, such as a controlled custom build, a required third-party feature, or a distribution policy that does not provide the needed module. Preserve the existing configure arguments where possible; changing them can silently remove features used by current virtual hosts.
The source-build documentation identifies --http-log-path=path as the build-time primary request-log path. That value establishes the initial filename, but it is not a permanent restriction: after installation, you can change the filename in nginx.conf with access_log. A source build still needs a writable destination and a service account with permission to create or append the file.
Configure a basic access log
Put log_format in the http context. Put access_log in http for a default that applies to servers, or in a particular server or location when only that traffic should be recorded.
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
access_log /var/log/nginx/access.log main;
server {
listen 80;
# server settings...
}
}
This format is a conventional combined-style record. It captures the client address, authenticated user (when present), local time, request line, status, response size, referrer, and user agent. Replace /var/log/nginx/access.log with the path appropriate to your build and operating system.
Choose where the directive belongs
| Context | Effect | Typical use |
|---|---|---|
http |
Default for all applicable virtual servers unless overridden. | One common format and destination for the whole installation. |
server |
Applies to one virtual server and its locations unless overridden. | Separate files for different sites or applications. |
location |
Applies only to matching requests. | Different detail or retention for an API, static files, or an administrative path. |
if in location or limit_except |
Allows the directive in the specific contexts documented by NGINX. | Narrow, conditional policies; use only when you understand inheritance. |
Define a named format once in http; do not duplicate the same log_format in each virtual host. If a virtual server inherits an access_log and you want it silent, explicitly use access_log off; in that server or location.
Design a useful log format
Start with the fields needed to answer operational questions. Common variables include:
$remote_addrfor the peer address seen by NGINX.$remote_userfor the authenticated username, if authentication supplied one.$time_localfor the local timestamp.$requestfor the request line.$statusfor the final HTTP status.$body_bytes_sentfor response bytes excluding the response header.$http_refererand$http_user_agentfor the corresponding request headers.
Application-specific variables can be added when they are available in the request or response context. Every extra field increases line length and may contain personal or confidential data. Decide what operators actually need before logging headers wholesale.
JSON-like records for ingestion
If a log collector parses structured records, define a consistent delimiter and escape strategy. NGINX’s variables can be empty, and unescaped user-controlled values can contain characters that confuse a downstream parser. Keep the format documented alongside the service configuration and test it with representative requests, including missing referrers and unusual user-agent strings.
Set the destination, buffering, and compression
The basic syntax is:
access_log path format [buffer=size] [gzip[=level]] [flush=time] [if=condition];
The path may be a file or a syslog destination as supported by the installed NGINX version. The format name must match a log_format defined in an enclosing http context.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Clear out junk files and repair common Windows errorsFree Scan →Rank #4
File permissions and variable paths
Ensure the directory exists before reloading. The worker process must be able to open the file for append, and the service account may need permission to create the file after rotation or restart. A static path is easiest to operate. Variable-based paths add flexibility but have file-opening and permission constraints documented by NGINX; they can also create many files and complicate rotation. Use them only with a deliberate directory layout and tested ownership and modes.
Check both directory and file permissions, not just the filename:
sudo ls -ld /var/log/nginx
sudo ls -l /var/log/nginx/access.log
If the target does not exist, create the directory with the ownership and mode used by your distribution’s NGINX package. Avoid making a log directory world-writable simply to bypass a permission error.
Buffered writes
A buffer groups records before writing them. This can reduce the frequency of disk writes, but records remain in memory until the buffer fills or a flush occurs. Do not choose a buffer so large that a crash would discard an unacceptable amount of recent logging.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Compression
The gzip parameter compresses buffered records before writing. Compression requires NGINX to have been built with zlib. It can reduce storage and I/O, at the cost of CPU and additional operational complexity. Verify the build and benchmark the effect under your workload before enabling it on a busy server.
Flush intervals
flush=time sets a maximum interval for flushing a non-empty buffer. Short intervals make records visible sooner; longer intervals generally reduce write activity. Choose based on how quickly operators must see a request and how much write overhead the host can absorb.
Best Value
Exclude low-value requests with conditional logging
High-volume health checks or successful static responses can dominate an access log. Conditional logging uses a variable produced by map and the if parameter on access_log. The map belongs in http:
http {
map $status $skip_access_log {
200 1;
204 1;
default 0;
}
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent"';
access_log /var/log/nginx/access.log main if=$skip_access_log;
}
That example illustrates the syntax but would skip successful responses and retain other statuses. Before using it, decide whether losing successful records is acceptable for incident investigation, capacity analysis, compliance, or billing. A safer policy is often to exclude only a narrowly identified health endpoint, or to keep a separate low-retention file for routine probes.
Forward logs to a centralized collector
Local files are useful for immediate troubleshooting, but centralized collection helps when you have multiple servers, short-lived instances, or a need to search requests across hosts. NGINX’s logging guidance covers forwarding records to syslog. A centralized design should define:
- Transport and destination, including whether the channel is local or remote.
- Field format and hostname or instance identity.
- Retention, access control, and deletion requirements.
- Back-pressure behavior when the collector is unavailable.
- Whether sensitive headers or addresses must be redacted before forwarding.
Keep a local fallback during rollout so a collector outage does not remove your only copy of diagnostic data. Test both normal delivery and the failure mode, then document who owns retention and alerting.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Validate, reload, and prove that logging works
Make a backup or use version control for the configuration file you are about to edit. Then follow this sequence:
- Edit the active file. Add
log_formatunderhttpandaccess_login the chosen context. Confirm that any included file is actually loaded by the main configuration. - Check the destination. Create the directory if necessary and verify that the NGINX worker identity can write there. Check mandatory access-control policy if your operating system enforces one.
- Test syntax and references. Run
sudo nginx -t. A successful result reports that the syntax is okay and the test is successful. Do not reload after a failed test. - Reload the service. Use the service manager used by your installation, commonly
sudo systemctl reload nginx. A reload asks the master process to validate and apply the new workers without unnecessarily dropping existing connections. - Generate a request. Send a request to the correct address and virtual-host name, for example
curl -i http://127.0.0.1/. If the server selects hosts by name, add the appropriateHostheader or use the production hostname. - Read the configured file. Follow it with
sudo tail -f /var/log/nginx/access.log, replacing the path with the configured destination. Confirm that the new line contains the expected status, request, and client fields. - Test an error and an excluded case. Request a known missing resource to produce a 404, and exercise any health-check or conditional rule. This verifies both that records are being written and that the policy behaves as intended.
The exact service command and path are deployment-specific. If your installation is managed by another init system, container supervisor, or orchestration platform, use that platform’s reload operation after nginx -t succeeds.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Troubleshoot missing or incorrect access logs
nginx -t says the directive is unknown
- Run
nginx -Von the exact binary used by the service, not merely the first executable in your interactivePATH. - Use
nginx -Tto confirm that the file containinglog_formatis included. - Check that
log_formatis underhttpand thataccess_logis in an allowed context. - Confirm that you did not add a dynamic-module directive for a module that is already static, or omit a required
load_modulefor a genuinely dynamic module. - If the binary lacks the required HTTP functionality, install a vendor package that includes it or rebuild deliberately while preserving needed configure arguments.
The test passes but no file appears
- Inspect
nginx -Tfor a more specificaccess_log off;or anotheraccess_logthat overrides the one you edited. - Verify the request reached the intended virtual server and location. A different
server_name, port, or protocol may use another log. - Check the directory and file ownership, modes, and mandatory access-control denials.
- Look at the error log for “open() … failed” messages and other permission or path errors.
- If buffering is enabled, generate more traffic or wait for the flush interval before concluding that writes are absent.
- If logging is conditional, inspect the map variable and test a request that should produce a record.
The file exists but fields are empty or wrong
- Confirm that each variable is valid for the request phase in which it is logged.
- Remember that
$remote_addris the address seen by NGINX; a proxy or load balancer may require a separately configured real-IP policy if you need the original client address. - Check quoting and delimiters in custom formats with requests that have no referrer, no authenticated user, or unusual header characters.
- Ensure that the collector’s parser matches the exact deployed format and that no second configuration writes a different format to the same destination.
Logs stop after rotation
Rotation changes or renames files while workers may still hold open file descriptors. Use the rotation procedure supplied by your distribution or service manager, and verify ownership and permissions on the newly created file. After rotation, send a test request and confirm that the current file receives it.
Operational and privacy decisions
Access logs can contain IP addresses, URLs, query strings, account identifiers, referrers, and user-agent data. Treat them as operational data with an explicit retention period and access policy. Avoid logging credentials, authorization headers, session tokens, or unnecessary personal information. If a query string can contain secrets, remove or rewrite it before it reaches a long-lived log destination.
Quick Recap
Balance diagnostic value against resource cost:
| Choice | Benefit | Trade-off |
|---|---|---|
| Default combined-style format | Fast setup and familiar troubleshooting fields. | Limited application context and potentially noisy volume. |
| Custom fields | Better correlation with application events and response outcomes. | Larger records, parser maintenance, and possible sensitive data exposure. |
| Conditional logging | Less storage and I/O for predictable, low-value traffic. | Removed records cannot be recovered during an incident. |
| Buffered or compressed writes | Lower write frequency or storage consumption. | Delayed visibility, CPU cost, and more complex failure behavior. |
| Centralized collection | Cross-host search, retention controls, and shared alerting. | Network dependency, transport security, and collector capacity planning. |
Quick verification checklist
- Record
--conf-path,--http-log-path, and relevant configure arguments fromnginx -V. - Use
nginx -Tto confirm the effective include tree. - Define
log_formatinhttpand placeaccess_login the intended context. - Confirm the destination directory exists and is writable by the NGINX worker identity.
- Run
sudo nginx -tbefore every reload. - Reload with the service manager that owns the installation.
- Generate a known request with
curland read the configured destination. - Test a status that should be logged and one that a conditional rule should omit.
- Review rotation, retention, privacy, and centralized-forwarding behavior before putting the configuration into long-term production use.
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




