7

As far as I can see Nginx supports by default 2 log files: error_log (tracks issues related to the Nginx server itself) and access_log (tracks requests processed by Nginx). Whilst it is possible to control the format of access_log with the log_format directive, I have been unsuccessful at finding a way of logging only certain requests to a separate file, and therefore would like to ask the question on SF as a reference for future readers:

Is there a way to log certain requests to a different log file than the one defined by access_log?

FYI the reason behind this question is that I have a rule that denies access to unwanted crawlers with a 200 (because 403 would give them a hint that they're being blocked), and filtering those requests out of the access_log becomes more difficult.

8

cjc put me on the right track. Using access_log in an if statement by itself is not possible (You get a nginx: [emerg] "access_log" directive is not allowed here error). So the workaround is as follows:

if ($http_user_agent ~* (crawler) ) {
  set $crawler 'yes';
}
location ~ .* {
  if ($crawler = 'yes') {
    access_log /var/log/nginx/blockedbots.log;
    return 200;
    }
}
| improve this answer | |
  • Um, isn't this an access log inside an if statement..? – Xeoncross Jan 23 '15 at 18:28
  • Yep, the doc says that you can use Context: http, server, location, **if in location**, limit_except – Xeoncross Jan 23 '15 at 18:29
5

access_log supports if:

(access_log path [format [buffer=size [flush=time]] [if=condition]];)

access_log /var/.... if $crawler;

Source:

http://nginx.org/en/docs/http/ngx_http_log_module.html

| improve this answer | |
  • This is the cleaner solution as of NGINX 1.7.0. – Oliver Sep 25 '17 at 7:37
4

You should be able to put an access_log directive inside an if block, according to the documentation:

http://wiki.nginx.org/HttpLogModule

So, you should be able to do something like:

if ($http_user_agent ~* (crawler) ) {
   access_log /path/to/other/log/file ;
}
| improve this answer | |
  • access_log inside if statement by itself isn't possible, see my answer below. – Max Jun 1 '12 at 13:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.