23

我正在用 Python 编写一个日志收集/分析应用程序,我需要编写一个“规则引擎”来匹配和处理日志消息。

它需要具有:

  • 消息本身的正则表达式匹配
  • 消息严重性/优先级的算术比较
  • 布尔运算符

我设想一个示例规则可能是这样的:

(message ~ "program\\[\d+\\]: message" and severity >= high) or (severity >= critical)

我正在考虑使用PyParsing或类似方法来实际解析规则并构造解析树。

我想到的当前(尚未实现)设计是为每种规则类型设置类,并根据解析树构造并将它们链接在一起。然后每个规则将有一个“匹配”方法,该方法可以返回一个消息对象,无论它是否匹配规则。

很快,类似:

class RegexRule(Rule):
    def __init__(self, regex):
         self.regex = regex

    def match(self, message):
         return self.regex.match(message.contents)

class SeverityRule(Rule):
    def __init__(self, operator, severity):
         self.operator = operator

    def match(self, message):
         if operator == ">=":
             return message.severity >= severity
         # more conditions here...

class BooleanAndRule(Rule):
    def __init__(self, rule1, rule2):
         self.rule1 = rule1
         self.rule2 = rule2

    def match(self, message):
          return self.rule1.match(message) and self.rule2.match(message)

然后,这些规则类将根据消息的解析树链接在一起,并在顶部规则上调用 match() 方法,该方法将向下级联,直到所有规则都被评估。

我只是想知道这是否是一种合理的方法,或者我的设计和想法是否完全不合时宜?不幸的是,我从来没有机会在大学学习编译器设计课程或类似的课程,所以我几乎是自己想出了这些东西。

在这些事情上有一些经验的人可以插话并评估这个想法吗?

编辑: 到目前为止有一些很好的答案,这里有一些澄清。

该程序的目的是从网络上的服务器收集日志消息并将它们存储在数据库中。除了收集日志消息外,收集器还将定义一组规则,这些规则将根据条件匹配或忽略消息,并在必要时标记警报。

我看不到规则的复杂性超过中等,它们将被应用在一个链(列表)中,直到匹配的警报或忽略规则被命中。但是,这部分与问题不太相关。

就语法接近 Python 语法而言,是的,这是真的,但是我认为很难将 Python 过滤到用户不会无意中使用不希望的规则做一些疯狂的事情的程度。

4

5 回答 5

67

不要发明另一种规则语言。

要么使用 Python,要么使用其他现有的、已经调试过的工作语言,如 BPEL。

只需用 Python 编写规则,导入并执行它们。生活更简单,更容易调试,而且您实际上已经解决了实际的日志读取问题,而不会产生另一个问题。

想象一下这个场景。你的程序中断了。现在是规则解析、规则执行或规则本身。您必须调试所有三个。如果你用 Python 编写规则,那就是规则,就是这样。

“我认为很难将 Python 过滤到用户不会无意中使用非预期的规则做一些疯狂的事情的程度。”

这主要是“我想编写一个编译器”的论点。

1)您是主要用户。您将编写、调试和维护规则。真的有一群疯狂的程序员会做疯狂的事情吗?真的吗?如果有任何潜在的疯狂用户,请与他们交谈。教他们。不要通过发明一种新语言来对抗它们(然后你将不得不永远维护和调试它。)

2)这只是日志处理。这种疯狂并没有真正的代价。没有人会用错误的日志处理来颠覆世界经济体系。不要将几十行 Python 的小任务放到一个 1000 行的解释器上来解释一些规则语言的几十行。只需编写几十行 Python。

只需尽可能快速清晰地用 Python 编写它,然后继续下一个项目。

于 2009-01-22T11:22:15.387 回答
5

您可能还想查看PyKE

于 2009-12-18T01:07:25.163 回答
0

与 Python 语法本身唯一不同的地方就是该message ~ "program\\[\d+\\]: message"部分,所以我想知道您是否真的需要一种新语法。

更新:好的,你有可用性或安全问题——这是合理的。几个建议:

  • 从 Awk 中获取提示并简化模式匹配语法,例如,/program\[\d+\]: message/而不是message ~ "program\\[\d+\\]: message".

  • 我将通过在解析输入时转换为 Python 表达式来实现它,而不是构建要评估的对象树,除非您希望对这些事情执行比评估更多的操作。这应该需要更少的代码并且运行得更快。顶层可能类似于:

    def compile(input):
        return eval('lambda message, severity: %s' % parse(input))
    

另一个更远的想法:用 Lua 编写你的应用程序。它是为非程序员设计的,可以安全地合理扩展程序,而无需学习很多东西。(我被告知,它已经成功地使用了这种方式,并且您可以进行沙箱评估,因此用户的代码无法获得您没有明确传递给它的任何功能。)

我现在就闭嘴。:-) 祝你好运!

于 2009-01-22T01:20:11.563 回答
0

在不知道应用程序范围的情况下回答这个问题有点困难。

  • 你想推理什么?
  • 你说的是什么级别的分析?
  • 您认为规则变得多么复杂?
  • 不同规则之间的相互作用有多复杂?

一方面是您提出的一种简单的一次性方法。如果规则很少,相对简单,并且您没有做任何比聚合与指定规则匹配的日志消息更复杂的事情,这很好。

另一方面是重量级的推理系统,例如具有Python 接口的CLIPS。这是一个具有推理功能的真正规则引擎,并提供进行复杂推理的能力。如果您正在构建类似诊断引擎的东西,它可以根据程序日志运行,这可能更合适。

编辑:

我会说当前的实现思路很适合你正在做的事情。还有更多,我认为您可能会冒过度设计解决方案的风险。它似乎捕获了您想要的内容,仅根据几个不同的标准匹配日志消息。

于 2009-01-22T02:56:07.360 回答
0

您可能还想看看pyDMNrules。它从决策模型表示法 (DMN) 规则表构建规则引擎。

于 2021-11-03T22:02:12.617 回答