![nginx,单独的机器人访问日志和人类访问日志](https://linux22.com/image/657031/nginx%EF%BC%8C%E5%8D%95%E7%8B%AC%E7%9A%84%E6%9C%BA%E5%99%A8%E4%BA%BA%E8%AE%BF%E9%97%AE%E6%97%A5%E5%BF%97%E5%92%8C%E4%BA%BA%E7%B1%BB%E8%AE%BF%E9%97%AE%E6%97%A5%E5%BF%97.png)
我正在尝试分离机器人访问日志和人类访问日志,因此我使用以下配置:
http {
....
map $http_user_agent $ifbot {
default 0;
"~*rogerbot" 3;
"~*ChinasoSpider" 3;
"~*Yahoo" 1;
"~*Bot" 1;
"~*Spider" 1;
"~*archive" 1;
"~*search" 1;
"~*Yahoo" 1;
"~Mediapartners-Google" 1;
"~*bingbot" 1;
"~*YandexBot" 1;
"~*Feedly" 2;
"~*Superfeedr" 2;
"~*QuiteRSS" 2;
"~*g2reader" 2;
"~*Digg" 2;
"~*trendiction" 3;
"~*AhrefsBot" 3;
"~*curl" 3;
"~*Ruby" 3;
"~*Player" 3;
"~*Go\ http\ package" 3;
"~*Lynx" 3;
"~*Sleuth" 3;
"~*Python" 3;
"~*Wget" 3;
"~*perl" 3;
"~*httrack" 3;
"~*JikeSpider" 3;
"~*PHP" 3;
"~*WebIndex" 3;
"~*magpie-crawler" 3;
"~*JUC" 3;
"~*Scrapy" 3;
"~*libfetch" 3;
"~*WinHTTrack" 3;
"~*htmlparser" 3;
"~*urllib" 3;
"~*Zeus" 3;
"~*scan" 3;
"~*Indy\ Library" 3;
"~*libwww-perl" 3;
"~*GetRight" 3;
"~*GetWeb!" 3;
"~*Go!Zilla" 3;
"~*Go-Ahead-Got-It" 3;
"~*Download\ Demon" 3;
"~*TurnitinBot" 3;
"~*WebscanSpider" 3;
"~*WebBench" 3;
"~*YisouSpider" 3;
"~*check_http" 3;
"~*webmeup-crawler" 3;
"~*omgili" 3;
"~*blah" 3;
"~*fountainfo" 3;
"~*MicroMessenger" 3;
"~*QQDownload" 3;
"~*shoulu.jike.com" 3;
"~*omgilibot" 3;
"~*pyspider" 3;
}
....
}
在服务器部分,我使用:
if ($ifbot = "1") {
set $spiderbot 1;
}
if ($ifbot = "2") {
set $rssbot 1;
}
if ($ifbot = "3") {
return 403;
access_log /web/log/badbot.log main;
}
access_log /web/log/location_access.log main;
access_log /web/log/spider_access.log main if=$spiderbot;
access_log /web/log/rssbot_access.log main if=$rssbot;
但似乎 nginx 会将一些机器人日志写入 location_access.log 和 spider_access.log。
我该如何分离机器人的日志?
还有一个问题是,有些机器人日志没有写入 spider_access.log,但存在于 location_access.log 中。看来我的地图不起作用。我定义“地图”时有什么问题吗?
答案1
工作解决方案,无需涉及任何其他过程:
受到评论的启发。您可以轻松地将其适应几种类型的机器人(坏的/好的),并将语句放在return 403;
正确的部分。想法如下:
在http部分:
map $http_user_agent $bot {
default "";
"~*Googlebot" "yes";
"~*MJ12bot" "yes";
# Add as many as desired
}
map $bot $no_bot {
default "no";
"yes" "";
}
然后,在服务器部分:
access_log /var/log/regular_access.log main if=$no_bot;
access_log /var/log/bots_access.log main if=$bot;
这虽然可行,但当你想使用 nginx 作为反向代理并重定向到多个 Web 服务器时,效果并不好。(定义日志文件名称的方式不是很灵活)。
看上去不错,但不起作用
我本来想使用这个解决方案:
http部分:
map $http_user_agent $bot_header {
default "";
"~*Googlebot" "bots_";
"~*MJ12bot" "bots_";
# Add as many as desired
}
map $server_name $log_filename {
default "unknown";
"site1....." "site1_***.log";
"site2....." "site2_***.log";
}
然后,在每个服务器部分:
server { # simple reverse-proxy...
listen 37........:80;
server_name dev.****.net;
access_log /var/log/nginx/access/$bot_header$log_filename main;
# pass all requests
location / {
# There, your config
}
}
但是第二个不起作用。即使它是正确文件的正确路径,并且具有正确的权限,nginx 也会记录一个错误,说其权限不足。有趣的是,这个错误被记录到一个拥有与无法写入的文件完全相同的所有者和权限的文件中。不知道为什么,或者这是否是一个错误?也许有人可以尝试解决这个问题?
答案2
你正在突破条件 Nginx 的极限if
,这是旨在最低限度使用。
考虑使用 Rsyslog跟踪你的 Nginx 访问日志. Rsyslog 有强大的选项匹配日志字符串的内容并将它们发送到不同的日志。然后,您就可以获得所需的三个单独的日志。