如何在Elastic Beanstalk环境中阻止健康检查请求写入Nginx访问日志
你的核心问题是:配置了/health路径关闭访问日志,但健康检查请求依然出现在日志里。这是因为你的/health请求最终被转发到了处理.php的location块,而该块没有关闭日志记录。
问题原因分析
你当前的/health location配置里用了try_files $uri $uri/ /index.php?$query_string,当服务器上不存在/health文件或目录时,请求会被转发到index.php处理。此时请求会匹配到location ~ \.php$块,而这个块没有设置access_log off,所以健康检查请求的日志会在这里被记录下来。
解决方案
方案1:直接在/health location返回健康状态(推荐)
如果你的健康检查不需要经过PHP应用处理,直接返回固定响应即可,这样请求不会落到PHP的location块:
location /health { access_log off; return 200 'OK'; add_header Content-Type text/plain; } location ~ \.php$ { try_files $uri $uri/ /index.php?$query_string; include /etc/nginx/fastcgi_params; fastcgi_index index.php; fastcgi_intercept_errors on; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass php-fpm; } location / { try_files $uri $uri/ /index.php?$query_string; }
方案2:如果健康检查必须经过PHP处理
如果你的/health需要PHP应用生成响应,可在.php的location块中针对健康检查请求关闭日志:
location /health { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { # 针对/health请求关闭日志 if ($request_uri = /health) { access_log off; } try_files $uri $uri/ /index.php?$query_string; include /etc/nginx/fastcgi_params; fastcgi_index index.php; fastcgi_intercept_errors on; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass php-fpm; } location / { try_files $uri $uri/ /index.php?$query_string; }
方案3:全局过滤健康检查请求日志
也可以通过map指令全局过滤掉ELB健康检查的请求,不管请求路径是什么:
新建.platform/nginx/conf.d/elasticbeanstalk/log-filter.config文件,内容如下:
map $http_user_agent $loggable { default 1; # 匹配ELB健康检查的User-Agent,不记录日志 "ELB-HealthChecker/2.0" 0; } server { access_log /var/log/nginx/access.log main if=$loggable; }
这个方法会过滤所有User-Agent为ELB-HealthChecker/2.0的请求,适合不想单独配置路径的场景。
验证方法
修改配置后,重新部署Elastic Beanstalk环境,或者手动执行sudo service nginx restart重启Nginx服务,之后查看/var/log/nginx/access.log,确认健康检查请求不再被记录。
内容的提问来源于stack exchange,提问作者Abdulkadir Mete

