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

请求协助:编写Ruby日志解析脚本的正则表达式

解析Heroku Router日志的Ruby正则方案

我太懂你卡在Heroku日志正则这的感受了——这类日志看着复杂,但其实格式非常规整,咱们拆解开来写就能搞定。先看你给出的日志示例:

2014-01-09T06:16:53.766841+00:00 heroku[router]: at=info method=POST path=/logs/save_personal_data host=services.pocketplaylab.com fwd="5.13.87.91" dyno=web.10 connect=1ms service=42ms status=200 bytes=16
2014-01-09T06:16:53.772938+00:00 heroku[router]: at=info method=POST path=/api/users/1000028442...

它的核心结构就是时间戳 + 服务标识 + 一堆键值对,我们可以针对这个结构写正则,再用Ruby的正则分组轻松提取每个字段。

适配的正则表达式

这里给你一套能覆盖所有关键字段的正则,我逐段给你解释:

# 匹配日志整体结构的正则
LOG_PATTERN = /^(?<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+[+-]\d{2}:\d{2}) (?<service>\w+\[\w+\]): (?<fields>.*)$/
# 匹配单个键值对的正则
FIELD_PATTERN = /(?<key>\w+)=("?(?<value>[^" ]+)"?)/

完整Ruby解析脚本示例

直接把下面的代码拿去用,替换成你自己的日志读取逻辑就行:

LOG_PATTERN = /^(?<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+[+-]\d{2}:\d{2}) (?<service>\w+\[\w+\]): (?<fields>.*)$/
FIELD_PATTERN = /(?<key>\w+)=("?(?<value>[^" ]+)"?)/

# 这里可以替换成读取日志文件的逻辑,比如 File.readlines('your_log.log')
log_lines = [
  '2014-01-09T06:16:53.766841+00:00 heroku[router]: at=info method=POST path=/logs/save_personal_data host=services.pocketplaylab.com fwd="5.13.87.91" dyno=web.10 connect=1ms service=42ms status=200 bytes=16',
  '2014-01-09T06:16:53.772938+00:00 heroku[router]: at=info method=POST path=/api/users/1000028442...'
]

log_lines.each do |line|
  # 先匹配日志的时间戳和服务标识
  if match = line.match(LOG_PATTERN)
    log_data = {
      timestamp: match[:timestamp],
      service: match[:service],
      details: {}
    }

    # 逐个提取所有键值对字段
    match[:fields].scan(FIELD_PATTERN) do |key, value|
      # 去掉字段值可能带的引号(比如fwd字段的双引号)
      clean_value = value.gsub(/^"|"$/, '')
      # 自动转换数字类型,方便后续统计
      clean_value = case clean_value
                    when /^\d+$/ then clean_value.to_i
                    when /^\d+\.\d+$/ then clean_value.to_f
                    else clean_value
                    end
      log_data[:details][key.to_sym] = clean_value
    end

    # 这里可以换成写入数据库、生成统计报表等逻辑
    puts "解析完成的日志:"
    p log_data
    puts "---"
  else
    puts "⚠️  无法匹配的日志行: #{line}"
  end
end

正则各部分细节解释

  1. 时间戳匹配:(?<timestamp>\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+[+-]\d{2}:\d{2})
    • 精准匹配Heroku用的ISO8601格式时间,包含毫秒和时区偏移,用命名分组timestamp直接提取。
  2. 服务标识匹配:(?<service>\w+\[\w+\])
    • 匹配heroku[router]这类格式的服务名,命名分组service方便区分不同服务的日志。
  3. 键值对匹配:(?<key>\w+)=("?(?<value>[^" ]+)"?)
    • 同时兼容key=value和key="value"两种格式,处理带引号的字段(比如IP地址),用key和value分组直接提取内容。

小提示

如果你的日志里有特殊格式的字段(比如路径带特殊符号),可以把FIELD_PATTERN里的[^" ]改成[^"],允许值里包含空格——不过Heroku router日志的键值对一般不会有空格,当前版本足够用。

内容的提问来源于stack exchange,提问作者Максим

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:00:19