Splunk HEC:避免多行事件因内部时间戳拆分且保留时间戳识别的方法
针对你遇到的多行日志被错误拆分,同时又不想禁用时间戳识别的问题,有几种更精准的配置方案可以解决:
方法1:通过LINE_BREAKER和SHOULD_LINEMERGE严格控制事件拆分逻辑
这是最可靠的方案,直接定义事件的分隔规则,只有当行首出现你指定的日志时间戳格式时,才会触发新事件的拆分。
在props.conf中针对你的 sourcetype 添加如下配置:
[your_custom_sourcetype] SHOULD_LINEMERGE = false # 匹配行首的时间戳格式,前面的[\r\n]+表示换行符作为事件分隔符 LINE_BREAKER = ([\r\n]+)\[\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}:\d{3}\] # 指定时间戳的起始位置是行首的[之后 TIME_PREFIX = ^\[ # 对应你日志中时间戳的格式 TIME_FORMAT = %Y-%m-%d %H:%M:%S:%3N
原理:LINE_BREAKER告诉Splunk,只有当换行后紧跟[YYYY-MM-DD HH:MM:SS:SSS]格式的内容时,才会拆分出一个新事件。中间行的2022-02-08T07:00:00 UTC不符合这个规则,所以会被合并到上一个事件中,同时TIME_PREFIX和TIME_FORMAT确保Splunk能正确提取每个事件开头的时间戳。
方法2:通过TIME_PREFIX精准限定时间戳位置
如果你的日志格式比较固定,所有合法的事件起始行都以[时间戳]开头,而中间行的时间戳没有这个前缀,可以通过限定时间戳的提取范围来避免错误拆分:
[your_custom_sourcetype] SHOULD_LINEMERGE = true # 只从行首的[开始提取时间戳 TIME_PREFIX = ^\[ TIME_FORMAT = %Y-%m-%d %H:%M:%S:%3N # 保持默认的DATETIME_CONFIG即可,不用设为NONE
原理:Splunk默认会在合并行的过程中寻找时间戳,通过TIME_PREFIX = ^\[,我们告诉Splunk只在行首的[后面寻找时间戳,中间行的时间戳因为不在行首,不会被当作新事件的起始时间,自然也就不会触发事件拆分。
方法3:调整MAX_EVENTS(适用于短多行日志)
如果你的多行日志行数固定且不多,可以设置MAX_EVENTS来确保整个事件被完整合并,同时配合时间戳规则:
[your_custom_sourcetype] SHOULD_LINEMERGE = true MAX_EVENTS = 10 # 设置为足够容纳整个事件的行数 TIME_PREFIX = ^\[ TIME_FORMAT = %Y-%m-%d %H:%M:%S:%3N
这种方法的局限性是如果日志行数不固定,可能会出现合并不完整或者过度合并的情况,所以优先推荐前两种方法。
这些方案都不需要设置DATETIME_CONFIG = NONE,既能保证多行日志被正确合并为单个事件,又能让Splunk正常识别每个事件的时间戳。
内容的提问来源于stack exchange,提问作者Debargha Roy

