仅为特定请求创建单独的 Nginx 访问日志文件

仅为特定请求创建单独的 Nginx 访问日志文件

据我所知,Nginx 默认支持 2 个日志文件:(error_log跟踪与 Nginx 服务器本身相关的问题)和access_log(跟踪由 Nginx 处理的请求)。虽然可以access_log使用以下格式来控制log_format指令,我一直无法找到将某些请求仅记录到单独文件的方法,因此想在 SF 上提出这个问题,作为未来读者的参考:

有没有办法将某些请求记录到与定义的日志文件不同的日志文件中access_log

仅供参考,这个问题背后的原因是我有一条规则,拒绝访问不需要的爬虫程序,代码为 200(因为 403 会暗示它们被阻止了),并且过滤掉这些请求access_log变得更加困难。

答案1

cjc让我走上正轨。单独access_log在语句中使用是不可能的(您会得到错误)。因此解决方法如下:ifnginx: [emerg] "access_log" directive is not allowed here

if ($http_user_agent ~* (crawler) ) {
  set $crawler 'yes';
}
location ~ .* {
  if ($crawler = 'yes') {
    access_log /var/log/nginx/blockedbots.log;
    return 200;
    }
}

答案2

access_log 支持以下情况:

(access_log 路径 [格式 [缓冲区=大小 [刷新=时间]] [if=条件]];)

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

来源:

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

答案3

根据文档,您应该能够将access_log指令放在块内:if

http://wiki.nginx.org/HttpLogModule

因此,你应该能够做类似的事情:

if ($http_user_agent ~* (crawler) ) {
   access_log /path/to/other/log/file ;
}

答案4

当我看到这篇文章时,我正在寻找一种方法将 AWS ELB 健康检查日志发送到单独的文件,因为它们被堵塞了access.log。我从来没能在块内access_log工作,而且这也行不通:iflocation

map $http_user_agent $healthcheck {
    "ELB-HealthChecker/2.0" 1;
    default 0;
  }

access_log /var/log/nginx/elb-healthcheck.log main if=$healthcheck;
access_log /var/log/nginx/access.log main if=!$healthcheck;

在大括号的海洋中,人们很容易忘记 NGINX 配置文件不是一种编程语言。

尽管看上去有些笨重,但最终我得到的是这样的:

map $http_user_agent $not_elb {
    "ELB-HealthChecker/2.0" 0;
    default 1;
}
map $http_user_agent $elb {
    "ELB-HealthChecker/2.0" 1;
    default 0;
}

access_log /var/log/nginx/access.log main if=$not_elb;
access_log /var/log/nginx/elb-healthcheck.log main if=$elb;

常规流量转至access.log,ELB 健康检查日志转至elb-healthcheck.log

相关内容