Saturday, December 6, 2014

Nginx Error Logging and Access Logging

Our first foray into logging dealt with tailing our server's syslogs in my post about securing an Ubuntu instance. We've since revisited that topic in this article about basic log rotation. Now, we'll be touching specifically on Nginx logs.

Prerequisites: You'll want to set up Nginx on a server using this guide. This article was written for both Mac OS X and Linux Ubuntu users. These config steps are for Ubuntu, but if you're on a Mac, just replace all instances of /etc/nginx with wherever brew installs your Nginx. Will most likely be located at /usr/local/etc/nginx.

Nginx Error Logs

Setting Up Severity Levels

Now that you've set up your Nginx server, you'll want to configure error logging in your Nginx configuration file. If you're on Ubuntu, this is usually located at /etc/nginx/nginx.conf. On Mac OS X, provided you installed Nginx with homebrew, you'll find this file at /usr/local/etc/nginx/nginx.conf. We'll be modifying this file so make sure to make a copy of nginx.conf before making any changes to it. You should already see the following directives in the http block of your configuration file, which tell Nginx where to store its logs.

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

Notice that we've set our error_log level to warn, which will log severity levels of warn, error, crit, alert, and emerg. I find that warn provides the ideal amount of logging, with other options giving either too much or too little information. To log the maximum amount of messages, set the level to debug.

Warning: If you set the log level to debug, make sure to revert it back to warn, especially on a high traffic site.

Nginx Logs for Specific Locations

Set up your server block like so to set domain or path-specific logging:

server {
    server_name example.com
    # domain-specific logging
    error_log    /var/logs/nginx/example.com.error.log;
    location /admin/ { 
        # location-specific
        error_log /var/logs/nginx/admin-error.log debug; 
    }         
}

Logging Errors from Specific IPs

Just add the following line to the events block in your /etc/nginx/nginx.conf file and replace 1.1.1.1 with the IP address you want to target.

events {
    debug_connection 1.1.1.1;
}

Access Logs

Log Formatting

Nginx's access log is located at the path specified in your /etc/nginx/nginx.conf file. You're allowed to override the default settings in your nginx configuration file's http block using the log_format directive. Notice how we create the log format first, and then link the access_log directive, accordingly.

http {
    log_format compression '$remote_addr - $remote_user [$time_local] '
                           '"$request" $status $body_bytes_sent '
                           '"$http_referer" "$http_user_agent" "$gzip_ratio"';

    server {
        gzip on;
        access_log /var/log/nginx/nginx-access.log compression;
        ...
    }
}

The above example extends the standard combined format with gzip compression.

Conditional Logging

You can also configure Nginx to exclude certain logs based on certain conditions. In the following example, we're excluding requests with 2xx and 3xx response codes.

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

access_log /var/log/nginx/access.log combined if=$loggable;

Logging to Syslog

Sometimes its easier to consolidate your Nginx logs into the syslog, which standardizes log formatting to make it easier to collect and parse log messages to a single syslog server. The following example specifies the server location, facility or type of program logging the message, tag and severity. Other options for facility include auth, authpriv, daemon, cron, frp, lpr, kern, mail, news, syslog, user, uucp, and local0 through local7, with the default being local7.

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

Log Rotation

Manual

Add the following lines to a bash script and execute, as needed.

# moves the current log to a new file for archiving
# increase the .# suffix the older the file is so .0 .1 .2
# ...with .0 always being the most recent
mv /path/to/access.log /path/to/access.log.0

# sends a signal to nginx, telling it to reload its log files
kill -USR1 `cat /var/run/nginx.pid`

# gives the process time to complete
sleep 1

# add any post-process commands below

Using Logrotate

Nginx on Ubuntu comes packaged with a custom logrotate script. It's located at /etc/logrotate.d/nginx. Make sure to check this article for a logrotate 101.

That concludes this article. Make sure to read about the log module here, if you'd like to learn more.

1 comment: