变量子字符串的 syslog-ng 值映射

syslog-ng value mapping for variable sub-string

我是 运行 容器中的 syslog-ng balabit/syslog-ng:3.35.1

我想为 vpnrd 变量

中的值做值映射

下面是值映射的配置+CSV文件的例子


parser p_json {
    json-parser(prefix(".json."));
};

parser p_acd_vrf {
    add-contextual-data(
        selector("${.json.vpnrd}")
        database("vrf_map.csv")
        default-selector("UNKNOWN")
        prefix(".meta_vrf.")
    );
};

CSV 文件的内容:

111,vrf_id,vrf_1
222,vrf_id,vrf_2
zzz,vrf_id,vrf_example
UNKNOWN,vrf_id,[No VRF; Global Instance peer]
...

问题是 vpnrd 包含格式为 xxx:yyy:zzz 的字符串,我需要将其拆分(分隔符 :)并仅使用最后一部分 zzz,因为仅此而已部分与值映射相关。

有没有办法在 syslog-ng 中做到这一点?

我正在查看自定义 python 解析器,在其中可以轻松执行此类操作,但后来我不知道如何将 python 解析器的结果与值映射解析器连接起来。

感谢指点


更新:我基于 this blog 编写了 python 解析器,但不幸的是映射仍然不起作用,我总是得到 [No VRF; Global Instance peer] 映射为默认值。 我也看不到来自 python 脚本的日志(它们被发送到哪里?)所以很难判断发生了什么

parser p_py_vrf_id {
    python(
        class("GetVrfId")
    );
};

python {
from syslogng import Logger
logger = Logger()
class GetVrfId(object):
    def parse(self, log_message):
        """
        extract vrf_id from rd variable
        """
        logger.info(f'log: {log_message}')
        try:
            vpnrd = log_message['.json.rd'].split(':')[-1].strip()
            log_message['.json.vpnrd'] = vpnrd
            logger.info(f'vpnrd: {vpnrd}')
        except KeyError:
            log_message['.json.vpnrd'] = 'UNKNOWN'
            logger.error(f'key-error: rd not present')
        except Exception as e:
            logger.error(f'catch-all-error: {e}')
        # return True, other way message is dropped
        return True
};

您在这里有多种选择,其中之一是在 Python 中编写您自己的解析器。

解析器通常会生成新的名称-值对。 add-contextual-data() 和您的解析器之间的连接将是您在 selector() 中指定的键。

LogMessage字段是Python3中的bytes对象,所以在转换之前必须解码成字符串(例如:log_message['.json.vpnrd'].decode("utf-8"))。

syslogng.Logger 登录 internal() 来源。


xxx:yyy:zzz好像是定长的,去掉不需要的部分即可(不需要自定义解析器):

parser p_acd_vrf {
    add-contextual-data(
        selector("$(substr ${.json.vpnrd} 8)")
        database("vrf_map.csv")
        prefix(".meta_vrf.")
    );
};

或者,$(explode) 可用于将字符串拆分为列表(+ $(list-nth) 到 select 最后一个元素)。


另一种选择是使用内置的 csv-parser(),配置 : 作为分隔符。