Otel Collector Router正则匹配问题咨询及配置排查
OpenTelemetry Collector 日志处理问题解答
配置文件
receivers: filelog/nginx/1: include: - /opt/nginx/log/access.log include_file_path: true include_file_name: false operators: - type: router routes: - output: parse1 expr: 'body matches "^\\[\\d"' attributes: debug_body_router: '${body}' default: parse2 - type: regex_parser id: parse1 # Example line: # [28/Jan/2025:04:32:25 +0000] 127.0.0.1 34096 /__cq/status ... regex: '^\[(?P<timestamp>\d{2}\/[A-Za-z]{3}\/\d{4}:\d{2}:\d{2}:\d{2}\s+[+\-]\d{4})\]\s+(?P<ip>\S+)\s+(?P<port>\d+)\s+(?P<path>\S+).*$' timestamp: parse_from: attributes.timestamp layout: '%d/%b/%Y:%H:%M:%S %z' attributes: debug_body_parse1: '${body}' - type: regex_parser id: parse2 # Example lines: # 127.0.0.1 - - [29/Jan/2025:08:33:22 +0000] ... # 127.0.0.1 - MitigatorConnector [28/Jan/2025:14:23:46 +0000] ... regex: '^(?P<ip>\S+)\s+-\s+(?P<service>\S+)\s+\[(?P<timestamp>\d{2}\/[A-Za-z]{3}\/\d{4}:\d{2}:\d{2}:\d{2}\s+[+\-]\d{4})\]\s+(?P<msg>.*)$' timestamp: parse_from: attributes.timestamp layout: '%d/%b/%Y:%H:%M:%S %z' attributes: debug_body_parse2: '${body}' exporters: debug: verbosity: "detailed" # comment this out to minimize logging service: pipelines: logs: receivers: [filelog/nginx/1] processors: [] exporters: [debug] telemetry: logs: level: debug
导出的日志记录
LogRecord #1 ObservedTimestamp: 2025-01-30 09:15:19.792630808 +0000 UTC Timestamp: 2025-01-30 09:15:19 +0000 UTC SeverityText: SeverityNumber: Unspecified(0) Body: Str([30/Jan/2025:09:15:19 +0000] 127.0.0.1 37158 /__cq/cache/info /__cq/cache/info 200 214 "python-requests/2.25.1" 0.000 "-" "-" "-" "-" "14183" "167" "-" "localhost:9999" - -) Attributes: -> path: Str(/__cq/cache/info) -> log.file.path: Str(/opt/nginx/log/access.log) -> debug_body_router: Str() -> timestamp: Str(30/Jan/2025:09:15:19 +0000) -> ip: Str(127.0.0.1) -> port: Str(37158) Trace ID: Span ID:
用户疑问
- 为何路由会出现正则不匹配的报错?路由的作用不就是不匹配时走下一个路由或默认路由吗?
- 若路由正则未匹配,为何导出的日志中仍存在debug_body_router属性?
- 最重要的是,如何在路由表达式中正确匹配body?
解答
1. 路由出现正则不匹配报错的原因
这是因为你开启了service.telemetry.logs.level: debug调试级别。在debug模式下,Collector会输出所有路由匹配尝试的细节,包括未匹配的情况——这只是调试日志,不是真正的错误,完全不影响路由逻辑的正常执行。路由确实会在不匹配时走默认路由,这条日志只是告诉你当前这条日志没命中该路由规则,属于正常的调试输出。
2. 未匹配路由却存在debug_body_router属性的原因
你把debug_body_router的属性配置放在了路由条目里,但实际上只要日志经过这个router operator,不管有没有匹配成功,属性都会被添加。没匹配上时${body}变量无法正确赋值,所以属性值为空字符串。
如果想让属性只在匹配成功时添加,你的配置逻辑是对的,但出现空值大概率是转义问题导致路由匹配异常,或者是其他未匹配日志的调试干扰——从导出日志里的path/ip等属性来看,这条日志其实已经命中了parse1规则。
3. 正确在路由表达式中匹配body的方法
问题出在转义处理上,修复步骤如下:
- Otel的expr使用RE2正则语法,匹配
[(正则特殊字符)必须转义; - 在YAML单引号字符串中,反斜杠需要用双反斜杠转义,所以正确的表达式应该写成:
或者用expr: 'body matches "^\\[[0-9]"'\d表示数字:expr: 'body matches "^\\[\\d"' - 确认body类型:filelog接收器默认会把每行日志作为字符串body,无需额外处理;
- 调试日志里的报错可能来自其他未匹配的日志条目,可降低日志级别或过滤调试日志来确认匹配效果。
内容的提问来源于stack exchange,提问作者kaushal agrawal
相关产品推荐
相关产品推荐

