« Back to Web

How to log only some requests to a log file in nginx

Nginx is flexible when it comes to what should be logged in the access.log. With the combination of a map and if-statement, this can be achieved very easily!"

Log only some events by HTTP status

Creating a map using $status

The $status variable contains the HTTP status code that is normally returned to each request. We can leverage this status code to set a so-called boolean (true/false, or 1/0). Let’s define first the map and use the HTTP status.

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

So this example has a few options in it. Every status code that is considered good is typically in 200 or 300 range (200=OK, 301=Redirect, etc). By using a regular expression we can state that if the status code starts with a 2 or a 3, it is good. Let’s say that we are not interested in those for our custom logging. We give it therefore a value of zero.

If we want to define another specific value outside this 2xx/3xx range, like 444 (no response), we can define that as well. Again, we don’t want to log those, so we give it also a value of zero. All other responses (401, 403, 404, 5xx, etc) are not defined, so they will be caught by our catch-all, which is part of the keyword default. In this case it will get a value of one, as we do want to log them.

Next step is defining our access log.

Define access_log with if-condition

Like in a normal configuration, we have to use the access_log statement to define where to log our requests. But in this case we add an if-statement to it. The if=$loggable will only “activate” the line when it receives a positive value.

server {
    access_log /var/log/nginx/custom.log combined if=$loggable;
    access_log /var/log/nginx/access.log;
}

In this piece of configuration we defined our custom log, where we only store those requests with the status codes that we are interested in. In the line below, we define our access_log again, yet this time without any conditions. This way we can still store all events there, for something like log file processing or for other purposes. Our custom.log will be much smaller, as most of the events won’t be stored in there.

Feedback

Small picture of Michael Boelen

This article has been written by our Linux security expert Michael Boelen. With focus on creating high-quality articles and relevant examples, he wants to improve the field of Linux security. No more web full of copy-pasted blog posts.

Discovered outdated information or have a question? Share your thoughts. Thanks for your contribution!

Mastodon icon