更新 #1

更新 #1

我有一个 squid 代理将访问日志记录到一个文件中,然后 syslog-ng 读取这些日志,并根据 squid 的操作设置严重性(信息或通知),并将其作为 syslog 消息转发到 NetXMS 服务器。问题是 NetXMS 服务器收到的消息如下:

1 2024-04-17T11:13:11+02:00 vvsrv-proxy1 1713345191.357 - - [meta sequenceId="5336"]     69 10.30.108.14 TCP_TUNNEL/200 3530 CONNECT api.github.com:443 - HIER_DIRECT/140.82.121.5 -

(空行不是格式错误。)我想将文件中的行按原样转发到 NetXMS,如下所示:

1713345191.357 69 10.30.108.14 TCP_TUNNEL/200 3530 CONNECT api.github.com:443 - HIER_DIRECT/140.82.121.5 -

当前的 syslog-ng 配置(不包括默认部分):

source s_squid {
    file ("/var/log/squid/access.log");
};

filter f_squid_denied {
        message ("TCP_DENIED");
};

destination d_squid {
        syslog ("10.0.0.254" transport("udp") port(514) template("${MSG}"));
};

log {
    source (s_squid);
    filter (f_squid_denied);
    rewrite { set_severity("notice"); };
    destination (d_squid);
};

log {
    source (s_squid);                                                                          
    rewrite { set_severity("info"); };
    destination (d_squid);                                                                   
};

版本信息:

syslog-ng 4 (4.1.1)
Config version: 4.0

当我尝试自己解决这个问题时,我发现来自源的错误 syslog 标头会导致中继 syslog-ng 服务器添加自己的标头,但在我的例子中,源是一个本地文件。我还尝试切换到旧式网络驱动程序 - 而不是 syslog - 但情况仍然相同。

当我使用 rsyslog 将系统日志转发到 NetXMS 时,它没有任何额外的数据,因此 NetXMS 正在按应有的方式解析和处理系统日志消息。

更新 #1

在对 NetXMS 源代码进行一番挖掘后,我发现日期解析方法它只能解析RFC 3164系统日志消息。在阅读有关 syslog-ng 文档后使用传统协议我尝试了以下操作:

destination d_squid {
        network ("10.0.0.254" transport(udp) port(514));
};

但它仍然使用新的RFC 5424格式。

更新 #2

我正在使用,service syslog-ng reload但这还不够,重新启动服务后,它开始使用 BSD 系统日志格式。经过一些调整后,我的目标现在看起来像这样:

destination d_squid {                                                               
        network ("10.0.0.254" transport(udp) port(514) flags(no-multi-line) template(": ${MSG}"));
};

我没有改变配置的任何其他部分,但现在所有日志条目都有通知严重性,而不是包含TCP_DENIED子字符串的条目。

答案1

这是一个更紧凑的版本,与我在上一个答案中给出的评论一致。

@version: current


source s_squid {
    file ("access.log" flags(no-parse));
};

destination d_squid {
        network ("10.0.0.254" transport(udp) port(514) flags(no-multi-line) template ("<$PRI> : ${MSG}"));
};

log {
    source (s_squid);
    rewrite { set-facility("daemon"); };

    if (message("TCP_DENIED")){
        rewrite { set-severity("notice"); };
    } else {
        rewrite { set-severity("info"); };
    };
    destination (d_squid);
};

笔记:

  • 我在这里使用了 if() 语句,但这只不过是过滤器 + 标志(final)的语法糖而已;
  • 我对两种用例重复使用了相同的文件目的地,这样更简单。
  • 您现在发送的格式“<$PRI> : $MSG”既不是 RFC3164 也不是 RFC5424 系统日志,只是指出这一点。不幸的是,有很多使用非标准格式的东西。
  • syslog-ng 中的 syslog() 驱动程序专用于 RFC5424 样式的输出,这不是您的目标所期望的。network() 驱动程序基本上是一种传输任何您想要的内容的方法,因为您可以使用 template() 自定义整个消息
  • file() 源通常假设消息格式也与 syslog 格式匹配,您可以使用标志(no-parse)正确禁用该格式

答案2

正确的配置如下:

source s_squid {
    file ("/var/log/squid/access.log" flags(no-parse));
};

destination d_squid_info {
        network ("10.0.0.254" transport(udp) port(514) flags(no-multi-line) template ("<30> : ${MSG}") persist_name("squid-info"));
};

destination d_squid_notice {
        network ("10.0.0.254" transport(udp) port(514) flags(no-multi-line) template ("<29> : ${MSG}") persist_name("squid-notice"));
};

log {
    source (s_squid);
    filter {message("TCP_DENIED")};
    destination (d_squid_notice);
};

log {
    source (s_squid);
    filter {not message ("TCP_DENIED")};
    destination (d_squid_info);
};

解决方案是使用模板来格式化整个消息包括 RFC 3164 标头,但这需要两个“相同”的目的地,所以我必须添加persist_name两个唯一的目的地。

更新:我必须创建两个过滤器,一个匹配,一个不匹配,TCP_DENIED因为之前的配置为被拒绝的消息发送了重复的条目。

相关内容