【问题标题】:Logstash filter regular expression difference in JRuby and RubyJRuby和Ruby中Logstash过滤器正则表达式的区别
【发布时间】:2014-10-18 02:40:06
【问题描述】:

用于解析我们的 syslog 流的 Logstash 过滤器正则表达式变得越来越复杂,这导致我编写测试。我只是在主 Logstash 存储库中复制了 Grok 测试的结构,对其进行了一些修改,然后使用 bin/logstash rspec 作为 explained here 运行它。在与正则表达式语法斗争了几个小时后,我发现修饰符必须如何转义有所不同。以下是对日志消息中涉及方括号的过滤器的简单测试,您必须在过滤器正则表达式中对其进行转义:

require "test_utils"
require "logstash/filters/grok"

describe LogStash::Filters::Grok do
  extend LogStash::RSpec

  describe "Grok pattern difference" do
    config <<-CONFIG
      filter {
        grok {
          match => [ "message", '%{PROG:theprocess}(?<forgetthis>(: )?(\\[[\\d:|\\s\\w/]*\\])?:?)%{GREEDYDATA:message}' ]
          add_field => { "process" => "%{theprocess}" "forget_this" => "%{forgetthis}" }
        }
      }
    CONFIG

    sample "uwsgi: [pid: 12345|app: 0|req: 21/93281] BLAHBLAH" do
      insist { subject["tags"] }.nil?
      insist { subject["process"] } == "uwsgi"
      insist { subject["forget_this"] } == ": [pid: 12345|app: 0|req: 21/93281]"
      insist { subject["message"] } == "BLAHBLAH"
    end
  end
end

另存为,例如grok_demo.rb 并用bin/logstash rspec grok_demo.rb 测试它,它会工作。但是,如果您删除正则表达式中的双转义符,则不会。

我想在直接的 Ruby 中尝试同样的事情,使用与 Logstash 相同的正则表达式库,并遵循directions given here。以下测试按预期工作,无需双重转义:

require 'rubygems'
require 'grok-pure'
grok = Grok.new
grok.add_patterns_from_file("/Users/ulas/temp/grok_patterns.txt")

pattern = '%{PROG:theprocess}(?<forgetthis>(: )?(\[[\d:|\s\w/]*\])?:?)%{GREEDYDATA:message}'
grok.compile(pattern)

text1 = 'uwsgi: [pid: 12345|app: 0|req: 21/93281] BLAHBLAH'
puts grok.match(text1).captures()

我不是 Ruby 程序员,对于造成这种差异的原因有点迷茫。 heredoc 配置规范是否可能需要双重转义?还是与正则表达式传递到 Logstash 中的正则表达式库的方式有关?

【问题讨论】:

    标签: ruby regex jruby logstash


    【解决方案1】:

    我以前从来没有为logstash编写过测试,但我猜双重转义是因为你在字符串中嵌入了字符串。

    部分:

    <<-CONFIG
      # stuff here
    CONFIG
    

    是 ruby​​ 中的 heredoc(这是一种生成字符串的奇特方式)。所以filtergrokmatchadd 和所有的括号/大括号实际上都是字符串的一部分。在此字符串中,您正在转义转义序列,因此结果字符串具有单个文字转义序列。我猜这个字符串会在某处被评估,以便所有filter 等东西都根据需要实现,这就是使用单个转义序列的地方。

    当使用“straight ruby​​”时,你不会做这种双重解释。你只是将一个字符串直接传递给方法来编译它。

    【讨论】:

      猜你喜欢
      • 2020-04-09
      • 1970-01-01
      • 2023-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      相关资源
      最近更新 更多