解释器模式实战:实现自定义的告警规则功能

大家好,我是征哥,今天分享一种设计模式,解释器模式。

先来看一个需求:

在告警系统中,有很多规则的配置,如果配置的规则被触发,监控系统就通过短信、微信、邮件等方式发送告警给开发者。比如,每分钟 API 总出错数超过 100 或者每分钟 API 总调用数超过 10000 就触发告警。配置的规则如下:

api_error_per_minute > 9 || api_count_per_minute > 10000

在监控系统中,告警模块只判断是否触发告警。至于每分钟 API 接口出错数、每分钟接口调用数等统计数据的计算,是由其他模块来负责的。其他模块将统计数据放到一个 dict 中,数据的格式如下所示:

apiStat = {}
apiStat["api_error_per_minute"] = 10
apiStat["api_count_per_minute"] = 987

接下来,编写程序,输入是一个字典,代表统计数据 apiStat,和一个字符串,代表告警规则 "api_error_per_minute > 9 || api_count_per_minute > 10000",输出:True 或 False,True 表述满足告警规则,False 表示不满足。

为了简化代码实现,我们假设自定义的告警规则只包含“||、&&、>、<、==”这五个运算符,其中,“>、<、==”运算符的优先级高于“||、&&”运算符,“&&”运算符优先级高于“||”。在表达式中,任意元素之间需要通过空格来分隔。

除此之外,用户可以自定义要监控的 key,比如前面的 api_error_per_minute、api_count_per_minute。

那么如何写代码实现呢?

更具体一点,请将以下 pass 语句替换成可以执行的代码,其中 rule 字符串是可以自由变化的:

class AlertRuleInterpreter:
    def __init__(self, ruleExpression: str):
        pass

    def interpret(self, stats: dict) -> bool:
        pass


if __name__ == "__main__":
    rule = "key1 > 100 && key2 < 30 || key3 < 100 || key4 == 88"
    interpreter = AlertRuleInterpreter(rule)
    stats = {}
    stats["key1"] = 101
    stats["key3"] = 121
    stats["key4"] = 88
    alert = interpreter.interpret(stats)
    print(alert)

你可以先暂停,思考下怎么写,然后和我这里对比一下:

基础版本

思路:先把字符串按照 || 分割成子串,每一个字串内部的逻辑关系就是 &&,再将字串按照 && 分割成子子串,每一个子子串的内部逻辑关系就三种:>、<、==,这是不是很像一个树?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值