0

I'm trying to use PaperTrail's filter logs tool to filter out specific paths using RegEx. My log string could look like one of the below:

Should NOT pass and NOT be logged

Sep 03 10:12:40 lastmingear heroku/router:  at=info method=GET path="/orders/SOME_ID?key=USER_KEY" host=www.lastmingear.com...

Should PASS, and BE logged

Sep 03 10:12:40 lastmingear heroku/router:  at=info method=GET path="/orders/SOME_ID?key=USER_KEY&log=true" host=www.lastmingear.com...

The only difference is that the path where I want it to BE logged has an additional params log=true. So the RegEx statement should read verbally, like:

IF a key=USER_KEY is provided, then do NOT pass into logs UNLESS there is also a log=true

4

2 回答 2

2

您可以使用正则表达式,但将查询字符串与这样的模式匹配通常被认为是一种不好的做法。如果参数的顺序不同怎么办?如果它们之间还有其他参数怎么办?如果它们是 URL 编码的呢?

相反,您可能会考虑解析查询字符串并分析键值对:

require 'uri'

def log?(log_line)
  path = log_line[/path="([^"]+)"/, 1]
  uri = URI(path)
  params = URI.decode_www_form(uri.query).to_h
  not params['key'] or params['log'] == 'true'
end

更新:这是一个棘手的正则表达式问题要解决,因为没有办法说 if-this-then-that-or-etc。在正则表达式中。您可以使用断言,但它们只会让您到目前为止。您基本上必须枚举您想要传递的所有模式。我想强调的是,这是相当脆弱的,随着时间的推移,您需要密切关注它,看看模式是否有任何差异。

此模式将 /orders 路由的日志行与数字订单号匹配,并带有可选的查询字符串。如果提供了查询字符串,它必须匹配提供的模式之一。如果提供了数字键编号,则 log 必须为真。

/path="\/orders\/\d+
  (?:\?
    (?:(?!(?<=[?&])key=\d+(?=[&"])).)*?
    |(.+?&)?log=true(&.+?)?
  )?
"/x
于 2016-09-03T18:17:01.670 回答
0

虽然由于他给出的原因我更喜欢@mwp 的答案,但以下正则表达式有什么问题:

/path="[^"]+?\&log=true.*?"/

非贪婪地匹配所有非引号,直到找到&log=true非贪婪的任何内容然后是结束引号。

于 2016-09-03T19:16:29.423 回答