NGINX Access & Error Logs

NGINX is the most popular web server in the world, powering close to 35% of all sites according to w2techs. As a popular part of your software stack, it is good to understand its logs. NGINX write two specific types of logs: Error.log and Access.log. This article will dive into each one respectively.

Log & Configuration Locations

Before you get started, it's best to orient yourself with where things are located. Below are the two most important locations to know as it pertains to logs:



Name Description
Log Locationn /var/log/nginx
Config Locationn /etc/nginx/nginx.conf

NGINX Access Logs

The NGINX access log exist to record the activity of all the visitors to your site. You can use these logs to see what pages are being visited, what files are being requested, where users are coming from, and the list goes on. It also contains sensitive information like the users IP, the date and time of the request, and even the type of application being used to access the site (e.g., Chrome vs Firefox, Mobile vs Desktop). This log is especially helpful when you're trying to better understand your visitor behavior.

By default, all access logs have a standard format are set in the nginx.conf file with the access_log directive. The format looks like this:

access_log log_file log_format;

It is set like this:

http {
       ...
       ...
       access_log /var/log/nginx/access.log;
       ...
       ...
}

1. Access Log Format

By default, NGINX will record all all logs in the combined format, which records the following information:



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


You are not limited to this format, however. A format can be changed by specifying the format you want to use. For example, let's assume you create a custom format and this format is focused on adding the X-Forwarded-For values to the log.

You would create the new log format:



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


Now using the same structure above, you simply add the format type to the end of the configuration file:

http {
       ...
       ...
       access_log /var/log/nginx/access.log custom;
       ...
       ...
}


2. Access Log Sample

Here is an example of a log entry recorded in an access log file:

192.168.33.1 - - [15/Oct/2019:19:41:46 +0000] "GET / HTTP/1.1" 200 396 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36"

This is how it corresponds to the default log format:



Format Value Description
$remote_addr 192.168.33.1 The IP address of the client making the request.
$remote_user - HTTP Authenticated User. When the user name is not set, this field shows -.
[$time_local] [15/Oct/2019:19:41:46 +0000] Local server time.
$request GET / HTTP/1.1 The request type, path and protocol.
$status 200 The server response code
$body_bytes_sent 396 The size of server response in bytes.
$http_referer - The URL of the referral.
$http_user_agent Mozilla/5.0 ... The user agent of the client (web browser).

NGINX Error Logs

The NGINX error log exists to record any issues, glitches, that the application might encounter. Maybe there is an error in a configuration file, or a conflict with a dependency. Maybe the application is forced to reboot, or fails to initialize. This is the log you want to analyze when something goes wrong as it usually contains a bit more detail and can help point you in the right direction. It's also extremely helpful to spend time analyzing the warnings, they can be indicative a problem.

By default, all error logs have a standard format and are set in the nginx.conf with the error_log directive. The format looks like this:

error_log log_file log_level;

It is set like this:

http {
      ...
      ...
      error_log /var/log/nginx/error.log;
      ...
      ...
}

1. Error Log Sample

The log starts with the date, time, followed by the criticality of the event (error, warn, crit) and the details of the problem. Watching these logs is critical to understanding your server and detecting problems that might be impacting your users.

Example log:


2022/05/14 19:55:51 [error] 6689#6689: *16764375 FastCGI sent in stderr: "PHP message: PHP Warning: Division by zero in /var/www/html/my.php on line 438" while reading upstream, client: 10.1.1.1, server: mytest.com, request: "GET /my.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.2-fpm.sock:", host: "my.test.com"

In this log, it is categorized as [error], because of a warning from the PHP engine due a division by zero.

2. Log Severity

Speaking of which, the NGINX error logs provide 8 unique severity levels you should be aware of.



Name Description
1. emerg Emergency messages when your system may be unstable.
2. alert Alert messages of serious issues.
3. crit Critical issues that need to be taken care of immediately.
4. error An error has occurred. Something went wrong while processing a page.
5. warn A warning messages that you should look into it.
6. notice A simple log notice that you can ignore.
7. info Just an information messages that you might want to know.
8. debug Debugging information used to pinpoint the location of error.

3. Common Error Types

These are the common nginx error logs that you might have on your server:



Name Description
FastCGI sent in stderr Error coming from the FastCGI module (often from your web application).
PHP message: PHP Warning If your web application uses PHP and generates a warning, you may get this type of error. We recommend passing to the developers to investigate and fixing them.
2022/05/14 07:08:37 [crit] 6689#6689: *16721837 SSL_do_handshake() failed (SSL: error:1420918C:SSL routines:tls_early_post_process_client_hello:version too low) while SSL handshaking The SSL_do_handshake happens whenever the client/server can't complete the SSL handshaking or it is ended too soon in the process. It can happen many times on a busy server and is often not a cause for concern.

NGINX Logs by Domain

By default, NGINX will store all the logs as one log entry on the server, but if you're deploying multiple domains on the same server this is highly impractical. This is why you have an option to configure logs for each domain (both access and errors) and you do this via the VirtualHosts file on the server.

Using the examples, formatting, provided above, this is how your virtual hosts file would look like for unique domains:

http {
      ...
      ...
      error_log /var/log/nginx/error_log;
      server {
            listen 80;
            server_name domain1.com;
            access_log /var/log/nginx/domain1.access.log;
            error_log /var/log/nginx/domain1.error_log warn;
            ...       }
      server {
            listen 80;
            server_name domain2.com;
            access_log /var/log/nginx/domain1.access.log;
            error_log /var/log/nginx/domain2.error_log debug;
            ...
      }
}


In the example above you see domain1 and domain2 each have their own access and error logs set. You also notice that you have the option to set the severity level for each domain as well (e.g., warn, debug).



Posted in   log-guide   nginx-logs     by Tony Perez (@perezbox)

Simple, affordable, log management and analysis.