You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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: 

用户疑问

  1. 为何路由会出现正则不匹配的报错?路由的作用不就是不匹配时走下一个路由或默认路由吗?
  2. 若路由正则未匹配,为何导出的日志中仍存在debug_body_router属性?
  3. 最重要的是,如何在路由表达式中正确匹配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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:34:53