syslog-ng - 使用 wildcard_file 时将 FILENAME 从客户端传递到服务器

syslog-ng - Passing FILENAME from client to server when using wildcard_file

我正在使用 syslog-ng,远程记录同一镜像的多个容器的应用程序日志。我正在使用如下的源配置。

source s_wild { wildcard-file(
    base-dir("/var/myapp/logs")
    filename-pattern("*")
    recursive(no)
    flags(no-parse)
    follow-freq(1)
); };

当我在本地机器上使用日志记录(出于测试目的)时,使用 MACRO ${FILE_NAME},它起作用了。但是在使用远程服务器进行测试时,文件名没有通过网络传递。

Aug  3 19:39:46 46fc878e92cf syslog-ng[2320]: Error opening file for writing; filename='', error='Is a directory (21)'

大约有 20-25 个文件,我正在寻找客户端和服务器端文件名的自动映射。可能吗。不确定 wildcard_file 如何映射到远程服务器。从逻辑上讲这可能是不可能的。仍在寻找解决方案。

我想知道是否可以通过定义多个源和目标或使用 log_prefix 来避免手动 1-1 映射。

$FILE_NAME 宏仅在 syslog-ng 从文件或 wildcard-file 源接收消息时有效,它不适用于 network()。您可以通过网络传递文件名的几个选项是:

  1. 使用 RFC 5424 系统日志消息的 structured-data 部分
  2. 使用template() with json-parser()从client-side发送消息并在服务器端解析它们
  3. 使用支持传递结构化消息的ewmm()(Enterprise-wide消息模型)

在第一种方法中,发送 RFC5424 格式的 (IETF-syslog) 消息允许您在 SDATA field. Use the syslog() on the source and destination side instead of network() to send the messages using IETF syslog protocol. The source file wildcard can be defined like this 中设置 FILE_NAME。整个配置如下所示:

syslog-ng客户端
source s_wild {
        wildcard-file(
                base-dir("/var/log_syslog")
                filename-pattern("*")
                recursive(no)
                follow-freq(1)
                );

};

rewrite r_set_filename{
    set(
        "$FILE_NAME",
         value(".SDATA.file@18372.4.name")
        );
};

rewrite r_use_basename {
  subst(
        "/var/log_syslog/",
        "",
        value(".SDATA.file@18372.4.name")
        type("string")
        flags("prefix")
       );
};

destination d_container_logs {
        syslog(
              "192.168.10.48"
               transport("tcp")
               port(5141)
        );
};

log {source(s_wild); rewrite(r_set_filename); rewrite(r_use_basename); destination(d_container_logs);};

r_set_filename 获取文件的绝对路径,我们 chop-off 路径位并使用 r_use_basename

仅保留文件名 syslog-ng 服务器端
source s_network {
        syslog(
        transport("tcp")
        port(5141)
        keep_hostname(yes)
        );
};


destination d_container_logs {
    file(
        "/var/sys_log/${.SDATA.file@18372.4.name}"
        create_dirs(yes)
        );
};

log {source(s_network); destination(d_container_logs);};