变量子字符串的 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()
,配置 :
作为分隔符。
我是 运行 容器中的 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()
,配置 :
作为分隔符。