我正在用Python编写一个日志收集/分析应用程序,并且我需要编写一个“规则引擎”来匹配和处理日志消息。
它需要具备以下特点:
message itself
我设想一个示例规则可能是这样的:
(message ~ "program\\[\d+\\]: message" and severity >= high) or (severity >= critical)
我正在考虑使用PyParsing或类似的方法来实际解析规则并构造解析树。
我考虑的当前设计(尚未实现)是为每种规则类型创建类,并根据解析树将它们构造和链接在一起。然后,每个规则都将有一个" matches“方法,该方法可以获取消息对象的返回值,而不管它是否与规则匹配。
非常快,就像这样:
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()方法,该方法将向下递减,直到所有规则都被求值。
我只是想知道这是一种合理的方法,还是我的设计和想法完全不正常?不幸的是,我从来没有机会在Unviersity上过编译器设计课程或类似的课程,所以我基本上是自发地想出了这个东西。
对这类事情有一定经验的人可以加入进来,评估一下这个想法吗?
编辑:到目前为止有一些不错的答案,这里有一点澄清。
该程序的目的是从网络上的服务器收集日志消息,并将其存储在数据库中。除了收集日志消息外,收集器还将定义一组规则,这些规则将根据条件匹配或忽略消息,并在必要时标记警报。
我看不出这些规则的复杂度超过中等程度,它们将在一个链(列表)中应用,直到匹配的警告或忽略规则被命中。然而,这一部分与问题并不是很相关。
就语法接近Python语法而言,是的,这是真的,但是我认为很难过滤Python,使用户不会无意中对规则做一些不想要的疯狂事情。
发布于 2009-01-22 11:22:15
不要再发明另一种规则语言了。
要么使用Python,要么使用其他一些现有的、已经调试好的工作语言,比如BPEL。
只需用Python编写规则,导入并执行即可。生活更简单,更容易调试,您实际上已经解决了实际的日志读取问题,而不会产生另一个问题。
想象一下这个场景。你的程序中断了。现在要么是规则解析,要么是规则执行,要么就是规则本身。您必须调试所有这三个组件。如果规则是用Python编写的,那么它就是规则,就是这样。
“我认为很难对Python进行过滤,使用户不会无意中对规则做一些不想做的疯狂事情。”
这在很大程度上是“我想写一个编译器”的论点。
1)您是主要用户。您将编写、调试和维护规则。真的有一大群疯狂的程序员会做疯狂的事情吗?真的?如果有任何潜在的疯狂用户,请与他们交谈。教他们。不要通过发明一种新的语言来对抗它们(然后你将不得不永远维护和调试它)。
2)这只是日志处理。这种疯狂并没有真正的代价。没有人会因为错误的日志处理而颠覆世界经济体系。不要在一个1000行的解释器上完成一个只有几十行Python的小任务来解释一些规则语言的几十行。只需编写几十行Python即可。
只需尽可能快速而清晰地用Python编写它,然后继续下一个项目。
发布于 2009-12-18 09:07:25
您可能还想看看PyKE。
发布于 2009-01-22 01:20:12
唯一与Python语法本身不同的是message ~ "program\\[\d+\\]: message"
部分,所以我想知道您是否真的需要一个新的语法。
更新:好的,你有可用性或安全方面的考虑--这是合理的。以下是一些建议:
Python从Awk得到提示,并简化模式匹配语法,例如,在解析输入时,message ~ "program\\[\d+\\]: message"
.
定义编译(输入):返回求值(‘λ消息,严重性:%s’% parse(input))
另一个想法是:用Lua编写你的应用程序。它是为非程序员设计的,可以合理安全地扩展程序,而不需要学习很多东西。(它已经被成功地使用了,而且你可以用沙箱进行评估,这样用户的代码就不能获得任何你没有显式传递给它的功能,我被告知。)
我要闭嘴了。:-)祝你好运!
https://stackoverflow.com/questions/467738
复制相似问题