我很难调试一个问题,我认为这可能有两个方面 - 两个单独程序中的问题。
主要问题是我在 Ubuntu 14.04 上将 nginx 记录到 syslog,如下所示:
access_log syslog:server=unix:/dev/log,tag=nginx,facility=local7,severity=info combined
Run Code Online (Sandbox Code Playgroud)
我希望能够过滤标记为 nginx 的消息,但没有那么幸运。
filter nginx { facility(local7) and tags("nginx") }
Run Code Online (Sandbox Code Playgroud)
将 and 更改为 or 可以工作,或者只需删除标签部分,因为设施过滤器工作正常。然而,标签过滤器不会。
所以,我想使用记录器进行测试并设置一个基本测试,如下所示:
template nginx { template("timestamp=${ISODATE} host=${HOST} tags=${TAGS} msgheader=${MSGHDR} ${MSG}\n"); template-escape(no); };
filter nginx { tags("nginx"); };
destination nginx { file("/tmp/nginx.log" template(nginx)); };
log { source(s_net); filter(nginx); destination(nginx); };
Run Code Online (Sandbox Code Playgroud)
--
$ logger -n localhost -P 10001 -t nginx -p local7.info -u /tmp/ignored testing 123
Run Code Online (Sandbox Code Playgroud)
我有一个源 s_net,在端口 10001 上侦听 UDP 以进行此测试。使用记录器,我通过 UDP 登录到该端口,使用 local7 设施和信息严重性标记“nginx”,并且过滤再次不起作用。删除过滤器约束可以让消息传递到目的地,就像直接使用 nginx 一样。标签根本不起作用。
此外,该标签不会显示在 $TAGS 宏中,而是显示在 $MSGHDR 宏中。
注意: /tmp/ignored 是 logger < 2.0.2 中的一个解决方法,如果您不提供套接字,它根本不会写入 TCP/UDP 端口,因此提供一个虚拟标志可以让它工作
看来即使使用记录器,我也无法过滤传入的标签。
我对 syslog (特别是 syslog-ng)比较陌生,所以也许我缺少一些东西?文档似乎很稀疏,但这看起来是一个非常简单的用例。有人认为有什么特别错误的地方吗?或者我是否误解了标签的用途?
nginx 配置参数引用的 RFC3164 中定义的 TAG 字段与 Syslog-ng 内部使用的标签过滤器之间存在差异。
您可以在 Nginx 中定义的 TAG 字段被解释为记录当前消息的程序或进程。它位于系统日志数据包的 MSG 部分中,并以第一个非字母数字字符结尾。之后的所有内容都将用作实际消息 (RFC3164#section-4.1.3)。
当您使用 tcpdump 嗅探系统日志流量时,您可以看到:
tcpdump -A -vvv -s0 -n -i venet0 port 514
Run Code Online (Sandbox Code Playgroud)
这是来自 NGINX 的示例,配置如下:
15:25:16.477717 IP (tos 0x0, ttl 63, id 22206, offset 0, flags [DF], proto UDP (17), length 454) loadbalancer.example.com.45470 > log.example.com.514: [udp sum ok] SYSLOG, length: 426
Facility local6 (22), Severity notice (5)
Msg: Mar 10 15:25:16 loadbalancer.example.com nginx_access: "[10/Mar/2017:15:25:16 +0100]" "NO-CACHE" "app.example.com:80" "0.032" "302" "331" "10.235.121.191" "sub.example.com" "GET /location/?parameter=value1 HTTP/1.1" "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.1; Win64; x64; Trident/7.0; .NET CLR 2.0.50727; SLCC2; .NET CLR 3.5.30729; .NET CLR 3.0.30729; .NET4.0C; .NET4.0E; Tablet PC 2.0)"
Run Code Online (Sandbox Code Playgroud)
我有时会使用nginx的TAG字段来区分不同的日志文件:
access_log /var/log/nginx/www.example.com.ssl_access_log proxy;
error_log /var/log/nginx/www.example.com.ssl_error_log warn;
access_log syslog:server=10.0.80.110,facility=local6,tag=nginx_access,severity=notice proxy;
error_log syslog:server=10.0.80.110,facility=local6,tag=nginx_error,severity=error warn;
Run Code Online (Sandbox Code Playgroud)
然后,在接收 syslog-ng 服务器上,我可以对传入消息进行排序,或者将它们转储到一个大文件中:
source s_net { udp(); };
filter f_prg_nginx_access{ program(nginx_access); };
filter f_prg_nginx_error{ program(nginx_error); };
destination d_lb_access { file("/var/log/lb_access.log" perm(0640));};
destination d_lb_error { file("/var/log/lb_error.log" perm(0640)); };
log { source(s_net); filter(f_prg_nginx_access); destination(d_lb_access); };
log { source(s_net); filter(f_prg_nginx_error); destination(d_lb_error); };
Run Code Online (Sandbox Code Playgroud)
正如 Robert Fekete 已经提到的,Syslog-ng 的标签过滤是对到达特定端口或匹配模式的内部标记消息的另一种方式。另外,[2] 表示标记是在 syslog-ng 中对消息进行排序的最快方法,但标记仅在本地可用,不能通过网络发送。
[1] https://www.nginx.com/resources/admin-guide/logging-and-monitoring/ [2] https://www.balabit.com/sites/default/files/documents/syslog-ng- ose-3.6-guides/en/syslog-ng-ose-v3.6-guide-admin/html/tagging-messages.html