By Matej Elias
Last Validated on May 14 2021 · Originally Published on May 14, 2021 · Viewed 2.2k times

Introduction

In this tutorial, you will learn everything you need to know about Nginx logging to help you troubleshoot and quickly resolve any problem you may encounter on your Nginx web server. Logging is a very powerful tool that will give you valuable data about all the operations of your server. You will learn where logs are stored, how to access them, and how to customize log output to fit your needs.


Prerequisites

  • Nginx web server.
  • Sudo privileges.

Step 1 — Locating Nginx Log Files

Nginx writes logs of its events in two different log files:

  • Access Log: In this file, Nginx stores information about incoming requests and user visits.
  • Error Log: This file contains information about errors that the Nginx web server encountered while processing requests.

The location of the access log file is very much dependent upon the operating system on which is Nginx web server running.

Location Of The Access Log

  • On Debian-based operating systems like Ubuntu, the access log file is located /var/log/nginx/access.log

Location Of The Error Log

  • On Debian-based operating systems like Ubuntu, the error log file is located /var/log/nginx/error.log

How To Find Log Files On Different OS

If you are using a different OS than Ubuntu (e.g. CentOS), you can find the location of log files in the server configuration file nginx.conf. The full path to the files will be specified using directives access_log and error_log. See the example below:

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

Step 2 — Viewing Nginx Logs

If you are working from an operating system with the UI, the easiest way to view stored logs is by opening files in the text editor. However, sometimes you need to view the content of the files directly in the terminal. In this case, there are few ways to do it.

You can tail command to view logs in real time:

tail -f /var/log/nginx/access.log

The tail command is used to print the last 10 lines from the selected file. With the -f option, the tail command will be viewing the content of the file in real-time.

To view the full content of the file, you can use the cat command:

cat /var/log/nginx/access.log

You may also want to find a specific term in the file. In that case, you can use the grep command:

grep GET /var/log/nginx/access.log

First, specify the term you want to search for, then specify the actual log file. In this case, we are looking for lines in the access log file where GET therm is present.


Step 3 — Configuring Nginx Access Logs

Access log stores data of incoming requests. This data is very useful when viewing what are users doing in the application and what pages are users visiting.

Enabling Access Log

Access log should be enabled by default. If it's not, you can enable it manually in the Nginx configuration file using the access_log directive.

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

The log entry using the default configuration will look like this:

Output:
127.0.0.1 alice Alice [07/May/2021:10:44:53 +0200] "GET / HTTP/1.1" 200 396 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4531.93 Safari/537.36"

Let's break down the access log message to see what data is logged by default.

  • 127.0.0.1: IP address of the user that made the request
  • alice: Remote log name (Name used to log in a user). If not set, the default value will be used -
  • Alice: Remote username (Username of logged-in user). If not set, the default value will be used -
  • [07/May/2021:10:44:53 +0200] : Date and time of the request
  • "GET / HTTP/1.1" : Request type
  • 200: Response code
  • 396: Size of the response in bytes
  • "-": IP address of the referer (original source)
  • "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4531.93 Safari/537.36" - Detailed browser information

Custom Log Format

If you want to customize the output of the access log you can do it using the log_format directive:

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

First, you need to specify a nickname for the format that will be used as its identifier. Then, you need to create a string representing the log message. You can use predefined variables.

Variables used in the example above:

  • $remote_addr: IP address of the client
  • $remote_user: Information about user making the request
  • $time_local: Servers local date and time
  • $request: Actual request
  • $status: Response code
  • $body_bytes_sent: Size of the response in bytes
  • $http_referer: IP address of the HTTP referer (original source)
  • $http_user_agent: Detailed browser information

You may also use the following variables

  • $upstream_connect_time: The time spent on establishing a connection with an upstream server
  • $upstream_header_time: The time between establishing a connection and receiving the first byte of the response header from the upstream server
  • $upstream_response_time: The time between establishing a connection and receiving the last byte of the response body from the upstream server
  • $request_time: The total time spent processing a request
  • $gzip_ratio: Ration of gzip compression (assuming gzip on setting)

After you created a custom log output format, you can apply it using the access_log directive and provide a second optional parameter - format:

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

Logging Into Multiple Files

You may want to log into multiple files using multiple formats. You can do it by creating custom formats and using access_log directive for each log file.

Let's create a format called agent that will only print detailed browser information and store the logs into agent_access.log. Note that the file has to be manually created before you can log into it.

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

log_format agent "$http_user_agent";

Then, apply the custom format:

access_log /var/log/nginx/access.log custom;
access_log /var/log/nginx/agent_access.log agent;

The current configuration will log browser information into a separate file.


Step 4 — Configuring Nginx Error Logs

Whenever Nginx encounters an error, it stores the event data in the error log. This is especially useful when debugging as it saves time and makes troubleshooting easier and efficient.

Enabling Error Log

Error log should be enabled by default. If it's not, you can enable it manually in the Nginx configuration file using the error_log directive.

error_log /var/log/nginx/error.log;

The error_log directive takes two parameters. The first one is the location of the log file. The second one is optional and sets the severity level of the log. Events with a lower severity level than set, will not be logged.

error_log /var/log/nginx/error.log info;

These are the possible values of severity and their meaning:

  • debug : messages used for debugging (LOWEST)
  • info : informational messages
  • notice : notices
  • warn : warnings
  • error : errors while processing the request (doesn't require immediate action)
  • crit : Critical error that requires prompt action
  • alert : Error that requires immediate action
  • emerg : System is unusable (HIGHEST)

Logging Into Multiple Files

As in the case of the access log, you can log errors into multiple files. Please note that the file has to be manually created before you can log into it.

error_log /var/log/nginx/error.log info;
error_log /var/log/nginx/emerg_error.log emerg;

This configuration will log every event except debug level event in the error.log file and emergency events into a separate emerg_error.log file.


Step 5 — Logging To Syslog

It's possible to set up Nginx to log events into the system log. The syslog utility allows collecting log messages from different devices on a single syslog server. In Nginx logging to syslog is done using syslog: prefix:

error_log  syslog:server=unix:/var/log/nginx.sock debug;
access_log syslog:server=[127.0.0.1]:1234,facility=local7,tag=nginx,severity=info;

Log messages are sent to a server= which can be:

  • The domain name
  • IP address IPv4 or IPv6
  • a UNIX-domain socket path

In the example above, error log messages are sent to a UNIX domain socket at the debug logging level. The access log is written to a syslog server with an IPv4 address and port 1234.

The facility= parameter specifies the type of program that is logging the message.

The tag= parameter applies a custom tag to syslog messages.

The severity= parameter sets the severity level of syslog messages for access log.


Conclusion

In this tutorial, you learned what types of log Nginx web server stores, where you can find those logs, how to understand the formatting, and how to create your custom log formats. Now, you can log into multiple files and set the level of errors to which the server will react. You also learned how to send logs directly to a Syslog. At this point, you know everything you need to efficiently debug your web application.