ElastAlert 规则过滤器(filter)编写指南:从 Query DSL 到 Kibana 导入的完整实战
发布时间:2026/9/26 2:17:08 作者:尧图编辑部 阅读量:1,286
编写指南:从 Query DSL 到 Kibana 导入的完整实战)
告警异常检测【免费下载链接】elastalertEasy Flexible Alerting With ElasticSearch项目地址https://gitcode.com/gh_mirrors/el/elastalert点击查看免费下载ElastAlert 的每条规则都通过filter字段定义什么样的日志事件需要被处理它本质上是 Elasticsearch Query DSL 过滤条件的子集。本文围绕 docs/source/recipes/writing_filters.rst 展开系统讲解query_string、term、terms、wildcard、range等常用过滤器类型的写法与版本差异并结合仓库源码揭示过滤器在 ElastAlert 内部如何被组装成真实查询最后给出从 Kibana 3 仪表盘直接加载过滤器的两种方式。读完本文你将能独立为任意规则编写正确、可复用的过滤器配置并理解过滤条件与规则类型frequency、spike、change 等之间的协作关系。filter 在规则中的位置与底层查询构造规则配置文件中的 filter 字段filter是 ElastAlert 规则配置文件的必需字段之一。在 example_rules/example_frequency.yaml 中可以找到最基础的写法# (Required) # A list of Elasticsearch filters used for find events # These filters are joined with AND and nested in a filtered query # For more info: http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl.html filter: - term: some_field: some_value注释中明确了两点关键事实filter 是一个过滤器列表多个过滤器之间以 AND 语义连接并被嵌套进一个 filtered query。在配置模式层面elastalert/schema.yaml 中将其定义为filter: filter {}——一个开放对象即不限定具体结构任何合法的 Query DSL 过滤器片段都可以直接写入这给了规则编写者最大的自由度。过滤器是如何变成一次真实查询的原文档中给出的示意结构为filter: and: filters: - [filters from rule.yaml]从源码层面看这一结构对应 ElastAlert 在 elastalert/elastalert.py 中get_query方法对过滤器的实际组装逻辑。该方法会把规则中的过滤器列表放入 bool 查询的must数组并自动插入时间范围过滤与排序es_filters {filter: {bool: {must: filters}}} if starttime and endtime: es_filters[filter][bool][must].insert(0, {range: {timestamp_field: {gt: starttime, lte: endtime}}}) if five: query {query: {bool: es_filters}} else: query {query: {filtered: es_filters}} if sort: query[sort] [{timestamp_field: {order: desc if desc else asc}}]这里five标志表示目标 Elasticsearch 是否为 5.x 及以上5.x 使用bool查询包装5.x 之前使用filtered查询包装。无论哪种情况规则里的过滤器都只是被原样放进must数组中的一个元素因此你写入的每个过滤器都必须自身独立合法——这与原文档filter section 原样传给 Elasticsearch的描述完全一致。另外注意ElastAlert 会把每次查询的起止时间自动作为第一个 range 过滤条件插入因此不要在规则里手动为时间戳字段写过滤条件否则可能与 ElastAlert 自身的调度时间窗口产生冲突。符合该过滤器条件的每一条文档结果都会被交给规则做进一步处理frequency 统计、spike 突增判断等所以 filter 写得好不好直接决定了告警的精准度。常用过滤器类型详解以下类型全部取自原文档均为 Elasticsearch Query DSL 中特别实用的子集。所有示例都是 YAML 列表项可直接复制进规则文件的filter:下。query_stringLucene 语法全文检索query_string遵循 Lucene 查询语法适合对多个字段做部分匹配或全文匹配是用途最广的类型filter: - query: query_string: query: username: bob - query: query_string: query: _type: login_logs - query: query_string: query: field: value OR otherfield: othervalue - query: query_string: query: this: that AND these: those关键点每个query_string过滤器都必须包裹在query:键之下query: query_string: ...这是 Query DSL 中过滤上下文内的查询的标准写法支持AND、OR、NOT布尔逻辑与字段限定如field: value OR otherfield: othervalue对被分析analyzed的字符串字段做全文匹配时应使用query_string而不是term详见下文 term 的说明元字段如_type同样可以作为查询目标字段。term精确匹配term用于字段的精确匹配不做分词filter: - term: name_field: bob - term: _type: login_logs原文档特别提醒了一个高频踩坑点如果字段是被分析的term 查询可能不符合直觉。默认情况下很多字符串字段会按空白分词例如一个看起来值是 foo bar 的字段实际上被切成了 foo 和 bar 两个词项用term查询foo bar可能匹配不到该字段除非该字段不分析反过来用term查询foo却能匹配到 foo bar 和 foo baz 这类被分词后的字段。因此对 analyzed 字段做完整文本匹配请改用query_stringterm更适合 keyword 型、未分析字段或枚举值状态码、用户名、日志类型等。terms多值 OR 匹配terms是多个term的便捷组合语义是字段值命中列表中任意一个即通过filter: - terms: field: [value1, value2] # value1 OR value2也可以同时对多个字段做匹配字段之间仍为 AND 语义每个字段内部是 OR- terms: fieldX: [value1, value2] fieldY: [something, something_else] fieldZ: [foo, bar, baz]当需要表达status 为 500 或 502 或 503 之一这类白名单/黑名单集合判断时terms是最简洁的写法。wildcard通配符匹配通配符匹配需要包在query:下*匹配任意字符序列filter: - query: wildcard: field: foo*bar例如field: error*可以匹配error,error_code,error_message等。注意通配符查询在大数据集上性能开销较高且同样受字段分析方式影响建议用于明确的命名前缀/后缀场景。range数值与时间范围对字段做范围过滤例如 HTTP 状态码 500599filter: - range: status_code: from: 500 to: 599range同样适用于时间字段如timestamp的from/to但由于 ElastAlert 会自动注入查询时间窗口规则中一般只需对业务字段做范围限制。from/to均为闭区间语义如需开区间可使用gt/gte/lt/lte形式。not / and / or布尔组合的版本差异Elasticsearch 2.x 时代任意过滤器都可以嵌入not、and、or中进行布尔组合filter: - or: - term: field: value - wildcard: field: foo*bar - and: - not: term: field: value - not: term: _type: somethingElasticsearch 5.x 起这种写法不再有效布尔逻辑必须改用query_string表达filter: - query: query_string: query: somefield: somevalue OR foo: bar这一版本差异在源码中有明确印证modify_rule_for_ES5见 elastalert/elastalert.py会针对 ES 5.x 移除过滤器顶层的query包装# In ES5, filters starting with query should have the top wrapper removed new_filters [] for es_filter in new_rule.get(filter, []): if es_filter.get(query): new_filters.append(es_filter[query]) else: new_filters.append(es_filter) new_rule[filter] new_filters也就是说ES 5.x 环境中规则里- query: query_string: ...写法依然可用ElastAlert 会自动剥掉外层query包装以适配新语法而not/and/or这类 2.x 时代结构则不再兼容应统一收敛到query_string。从源码结构看ElastAlert 通过elasticsearch_client探测目标版本is_atleastfive()来区分上述行为因此同一份规则文件在不同 ES 版本上的过滤器写法要求是不同的。从 Kibana 3 仪表盘加载过滤器如果过滤器已经在 Kibana 3 仪表盘中配置好ElastAlert 提供两种方式直接复用避免手工重写。方式一download_dashboard 动态下载在规则的filter字段中直接指定仪表盘名称filter: download_dashboard: My Dashboard NameElastAlert 启动时会从 Elasticsearch 下载该仪表盘的 schema并取出其中配置的过滤器作为规则的 filter。对应的加载逻辑在 elastalert/elastalert.pyif download_dashboard in new_rule[filter]: # Download filters from Kibana and set the rules filters to them db_filters self.filters_from_kibana(new_rule, new_rule[filter][download_dashboard]) if db_filters is not None: new_rule[filter] db_filters else: raise EAException(Could not download filters from %s % (new_rule[filter][download_dashboard]))配置模式上download_dashboard在 elastalert/schema.yaml 中被定义为字符串类型而filters_from_kibanaelastalert/elastalert.py最终委托 elastalert/kibana.py 的filters_from_dashboard完成转换。这一方式的局限必须注意原文档明确强调转换发生在ElastAlert 启动时属于一次性加载如果仪表盘名称发生变化或启动时 Elasticsearch 连接出现问题规则将无法加载ElastAlert 会以 Could not download filters from ... 之类的错误退出因此这种方式适合仪表盘稳定、网络可靠的场景不建议在频繁变更或弱网环境下依赖它。filters_from_dashboard展示了 Kibana 3 过滤器到规则过滤器的一一映射关系可作为仪表盘里哪些设置会被转成什么的参考if filter_type querystring: config_filter {query: {query_string: {query: filter[query]}}} if filter_type field: config_filter {term: {filter[field]: filter[query]}} if filter_type range: config_filter {range: {filter[field]: {from: filter[from], to: filter[to]}}} if filter[mandate] mustNot: config_filter {not: config_filter} if filter[mandate] either: or_filters.append(config_filter) else: config_filters.append(config_filter)可以看到Kibana 的 querystring 型过滤器转为query_stringfield 型转为termrange 型转为rangemustNot被包上noteither任选其一的过滤器们被汇总成一个or列表其余过滤器按顺序追加最终返回一个可直接写入规则filter:的 YAML 列表。方式二elastalert-rule-from-kibana 生成配置第二种方式是一次性生成配置文件避免运行时对 Kibana 的依赖。运行elastalert-rule-from-kibana命令按提示输入 Elasticsearch 地址、端口和仪表盘名称$ elastalert-rule-from-kibana Elasticsearch host: elasticsearch.example.com Elasticsearch port: 14900 Dashboard name: My Dashboard Partial Config file ----------- name: My Dashboard es_host: elasticsearch.example.com es_port: 14900 filter: - query: query_string: {query: _exists_:log.message} - query: query_string: {query: some_field:12345}该交互式脚本的实现位于 elastalert/rule_from_kibana.py它向kibana-int索引查询_id等于仪表盘名称的 dashboard 文档取出dashboard字段的 JSON交给filters_from_dashboard转换后用yaml.safe_dump打印出一份部分配置文件partial config file。这份输出可以直接当作规则文件的起点把name、es_host、es_port、filter复制进规则 YAML再补齐type、index、alert等必需字段schema 要求required: [type, index, alert]见 elastalert/schema.yaml即可运行。相比download_dashboard这种方式生成的过滤器是静态固化在规则文件里的运行时不依赖 Kibana仪表盘改名或网络抖动都不会影响规则加载推荐在生成后人工检查并固化过滤器。综合实战一份带过滤器的完整规则结合前面的过滤器类型写一个实际可用的规则示例假设要监控登录日志中的失败状态码并避免命中自身系统账号name: Login failure monitor type: frequency index: login_logs-* num_events: 5 timeframe: minutes: 5 filter: - query: query_string: query: event_type: login_failure - range: status_code: from: 401 to: 403 - terms: source_ip: [10.0.0.1, 10.0.0.2] # 排除已知监控源 IP - not: term: username: elastalert alert: - email email: - opsexample.com要点回顾query_string做事件类型匹配多个query_string之间自动 ANDrange限定状态码范围terms用多值 OR 排除一批已知来源notterm排除特定账号注意not结构仅适用于 Elasticsearch 2.x5.x 请改写为query_string: NOT username: elastalertnum_events、timeframe等规则类型参数与 filter 相互独立filter 只负责选哪些文档统计与告警逻辑交给规则类型本身。此外blacklist/whitelist等规则类型还会在运行时向过滤器列表追加query_string过滤器见 elastalert/elastalert.py因此即使filter本身写得很简单最终查询里也可能包含 ElastAlert 动态生成的过滤条件调试时可以通过 ElastAlert 日志中的 debug 信息查看完整查询。总结filter是规则配置中的必需字段内容为合法的 Elasticsearch Query DSL 过滤器列表多个过滤器以 AND 语义合并ElastAlert 会自动注入查询时间窗口与排序优先掌握query_string、term、terms、wildcard、range五种类型对 analyzed 字段做全文匹配用query_string精确匹配用term/terms范围判断用range布尔组合not/and/or仅适用于 Elasticsearch 2.x5.x 及以上必须改用query_string表达ElastAlert 的modify_rule_for_ES5会同步处理query包装的差异从 Kibana 3 复用过滤器有两条路径download_dashboard启动时动态下载依赖仪表盘稳定与网络可用或elastalert-rule-from-kibana一次性生成并固化静态配置推荐过滤器直接决定了进入规则处理的数据范围写好 filter 是精确告警的第一步建议先在 Elasticsearch 侧验证查询结果再固化到规则中。赞分享告警异常检测【免费下载链接】elastalertEasy Flexible Alerting With ElasticSearch项目地址https://gitcode.com/gh_mirrors/el/elastalert点击查看免费下载相关推荐Yelp/elastalert 规则过滤器编写指南Yelp/elastalert 规则过滤器编写指南 前言 在 Yelp/elastalert 项目中过滤器是规则配置中最核心的部分之一。它们决定了哪些 Ela告警异常检测如何高效部署Label Studio数据标注平台3分钟快速入门完整指南如何高效部署Label Studio数据标注平台3分钟快速入门完整指南 Label Studio是一款功能强大的多类型数据标注工具支持图像、文本、音频、视频数据标注人工智能Play Framework 过滤器Filter实战指南从 Filter API 到 EssentialFilter 全解析Play Framework 过滤器Filter实战指南从 Filter API 到 EssentialFilter 全解析 本文是 Play Frame后端Web框架上一篇VoidNovelEngine自定义扩展指南如何创建自定义节点与插件下一篇Pest框架核心类解析Expectation类的设计与实现创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考