实施";规则引擎“;用Python
我正在用Python编写一个日志收集/分析应用程序,我需要编写一个“规则引擎”来匹配日志消息并对其执行操作 它需要具备以下特点:实施";规则引擎“;用Python,python,parsing,rules,Python,Parsing,Rules,我正在用Python编写一个日志收集/分析应用程序,我需要编写一个“规则引擎”来匹配日志消息并对其执行操作 它需要具备以下特点: 与消息本身匹配的正则表达式 消息严重性/优先级的算术比较 布尔运算符 我设想一个示例规则可能是这样的: (message ~ "program\\[\d+\\]: message" and severity >= high) or (severity >= critical) class RegexRule(Rule): def __init
- 与消息本身匹配的正则表达式
- 消息严重性/优先级的算术比较
- 布尔运算符
(message ~ "program\\[\d+\\]: message" and severity >= high) or (severity >= critical)
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)
def compile(input):
return eval('lambda message, severity: %s' % parse(input))
我正在考虑使用或类似于实际解析规则并构造解析树
我想到的当前(尚未实现)设计是为每种规则类型创建类,并根据解析树将它们构造和链接在一起。然后,每个规则都会有一个“matches”方法,该方法可以接受消息对象返回,无论它是否与规则匹配
很快,类似于:
(message ~ "program\\[\d+\\]: message" and severity >= high) or (severity >= critical)
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)
def compile(input):
return eval('lambda message, severity: %s' % parse(input))
然后根据消息的解析树将这些规则类链接在一起,并在顶部规则上调用match()方法,该方法将向下级联,直到对所有规则进行求值
我只是想知道这是否是一个合理的方法,或者我的设计和想法是否完全不正常?不幸的是,在大学里,我从来没有机会参加过编译器设计课程或类似的课程,所以我几乎是自发地想出了这些东西
能不能请在这方面有经验的人加入进来并评估一下这个想法
编辑:
到目前为止,有一些很好的答案,这里有一些澄清
该程序的目的是从网络上的服务器收集日志消息,并将其存储在数据库中。除了日志消息的收集之外,收集器还将定义一组规则,这些规则将根据条件匹配或忽略消息,并在必要时标记警报
我看不出规则的复杂性超过中等程度,它们将应用于一个链(列表),直到匹配的警报或忽略规则被命中。然而,这一部分与这个问题不太相关
就语法接近Python语法而言,是的,这是正确的,但是我认为很难将Python过滤到用户不能不经意地使用非预期的规则做一些疯狂的事情的地步。与Python语法本身不同的唯一地方是
消息~”程序\[\d+\\]:message“
部分,因此我想知道您是否真的需要新语法
更新:好的,你要么有可用性问题,要么有安全问题——这是合理的。有几点建议:
- 接受Awk的提示并简化模式匹配语法,例如
而不是/program\[\d+\]:message/
message~“program\\[\d+\\]:message”
- 我将通过在解析输入时转换为Python表达式来实现它,而不是构建一个要求值的对象树,除非您希望对这些对象执行比求值更多的操作。这应该需要更少的代码并运行得更快。顶层可能是这样的:
(message ~ "program\\[\d+\\]: message" and severity >= high) or (severity >= critical)
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)
def compile(input): return eval('lambda message, severity: %s' % parse(input))
我现在就闭嘴。:-)祝你好运 在不知道应用范围的情况下回答这个问题有点困难
- 你想讲什么道理
- 你说的是什么层次的分析
- 你认为规则变得有多复杂
- 不同规则之间的相互作用有多复杂
我要说的是,当前的实现思想对于您正在做的事情来说是很好的。任何更多的问题,我认为您可能会冒着过度设计解决方案的风险。它似乎捕获了您想要的内容,仅根据几个不同的标准匹配日志消息。不要发明另一种规则语言 要么使用Python,要么使用其他现有的、已经调试过的工作语言,如BPEL 只需用Python编写规则,导入并执行它们。生活更简单,调试也更容易,而且您实际上已经解决了实际的日志读取问题,而没有产生其他问题 想象一下这种情况。你的程序中断了。现在要么是规则解析,要么是规则执行,要么是规则本身。您必须调试这三个。如果您用Python编写规则,它就是规则,就是这样 “我认为很难将Python过滤到用户不能不经意地使用非预期的规则做一些疯狂的事情的地步。” 这主要是“我想写一个编译器”的论点 1) 您是主要用户。您将编写、调试和维护这些规则。真的有一群疯狂的程序员会做疯狂的事情吗?真正地如果有任何潜在的疯狂用户,与他们交谈。教他们。不要通过发明一种新的语言来对抗它们(你将不得不永远维护和调试这种语言) 2) 这只是日志处理。这种疯狂没有真正的代价。没有人会去萨博