Niska
Niska

Reputation: 85

Disable logging for specific useragent in nginx conf

I want to disable logging for a specific useragent. This is a part of my current conf-file.

if ($http_user_agent ~ (bingbot|AhrefsBot|DotBot|Exabot|Baiduspider|SemrushBot) ) { return 403; }

I've tried adding access_log off; but get the following error:

nginx: [emerg] "access_log" directive is not allowed here

I'm assuming this is because I only have a server block. I need a location block also. I've tried the following code:

location / { if ($http_user_agent ~ (bingbot|AhrefsBot|DotBot|Exabot|Baiduspider|SemrushBot) ) { return 403; } }

But I get the following error:

duplicate location "/"

In my conf-file I already have this code:

location / { try_files $uri $uri/ =404; }

Can I combine the two location snippets into one? Or how do I proceed?

Upvotes: 2

Views: 1984

Answers (2)

Shawn C.
Shawn C.

Reputation: 6841

At the http level declare a map like so.

map $http_user_agent $ignore_status_checks {
    default                 0;
    "~Pingdom.*"            1;
    "~*\(StatusCake\)"      1;
    "~*mod_pagespeed*"      1;
    "~*NodePing*"           1;
}

Then in your server's location block add:

if ($ignore_status_checks) {
    access_log      off;
}

This will turn off the access_log for anything returns a 1 in the map. Of course, you can do want ever you want in the if.

Upvotes: 0

Richard Smith
Richard Smith

Reputation: 49712

As your question indicates, the access_log directive cannot be used within an if block unless enclosed within a location. However, the access_log directive does include an if=condition which can be controlled by a map. There is an example at the end of this section of the manual.

For example:

map $http_user_agent $goodagent {
    default                                                    1;
    ~(bingbot|AhrefsBot|DotBot|Exabot|Baiduspider|SemrushBot)  0;
}    

server {
    access_log ... if=$goodagent;

    if ($goodagent = 0) { return 403; }

    ...
}

The map directive must be placed outside of the server block. The access_log statement can be placed inside or outside the server block depending on whether it applies to all server blocks or just one.

Upvotes: 3

Related Questions