elastic-recheck

“使用 ElasticSearch 对 OpenStack gate 失败进行分类”

  • 开源软件:Apache 许可

想法

确定导致 gate 中瞬态错误的具体 bug 很难。仅仅确定哪个 tempest 测试失败是不够的,因为单个 tempest 测试可能由于许多潜在的 bug 而失败。如果我们能使用日志找到特定 bug 的指纹,那么我们可以使用 ElasticSearch 自动检测该 bug 的任何出现。

使用这些指纹 elastic-recheck 可以

  • 在 ElasticSearch 中搜索 bug 的所有出现。

  • 识别 bug 趋势,例如:它何时开始,bug 是否已修复,是否正在恶化等。

  • 实时分类 bug 失败,并在找到匹配项时报告给 gerrit,以便补丁作者知道测试失败的原因。

queries/

所有查询都存储在 elastic-recheck 代码库顶层的 queries 目录中的单独的 yaml 文件中。这些文件的格式为 ######.yaml(其中 ###### 是 launchpad bug 编号),yaml 应该有一个 query 关键字,它是 elastic search 的查询文本。

良好查询的指南

  • 查询应尽可能接近于定位根本原因。屏幕日志查询(例如 tags:"screen-n-net.txt")通常比控制台查询 (tags:"console") 更好,因为前者匹配的是深度故障,而后者匹配的是表面症状。

  • 查询不应返回任何成功的作业的命中,这是查询不够具体的标志。一个经验法则是 > 10% 的成功命中可能意味着这还不够好。

  • 如果无法构建针对 bug 的查询,请考虑修补上游程序,使其在以特定方式失败时明确说明。

  • 使用“tags”字段而不是“filename”字段进行过滤。这主要是因为 grenade 作业,其中相同的日志文件出现在 grenade 作业的“old”和“new”侧。例如,tags:"screen-n-cpu.txt" 将在 logs/old/screen-n-cpu.txtlogs/new/screen-n-cpu.txt 中查询。 tags:"console" 过滤器也用于在 console.html 以及 tempest 和 devstack 日志中查询。

  • 避免在查询中使用通配符,因为它们可能会给查询引擎带来不必要的负担。通配符的一个常见用例是不应该使用的针对特定 build_name 字段的查询,例如 gate-nova-python26gate-nova-python27。与其使用 build_name:gate-nova-python*,不如使用 OR 列出作业。例如

    (build_name:"gate-nova-python26" OR build_name:"gate-nova-python27")
    

在添加查询时,您可以选择通过在 yaml 文件中添加 suppress-graph: truesuppress-notification: true 来抑制图形和通知的创建。这些可用于确保预期失败不会出现在未分类页面上。

如果可用的唯一签名过于宽泛,并且添加额外的日志无法合理地创建良好的签名,您还可以根据正在检查的运行失败的 test_ids 过滤查询结果。这可以通过在查询文件中添加 test_ids 关键字,然后列出要验证失败的 test_ids 来完成。test_id 也应该排除任何 attrs,这是附加到 test_id 之间的 ‘[]’ 中的 attrs 列表。例如,‘smoke’、‘slow’、任何服务标签等。这是 subunit-trace 默认打印 test id 的方式,如果您正在使用它。如果列出的 test_ids 中的任何一个与正在检查的运行的查询匹配,则会返回匹配项。由于过滤利用 subunit2sql,而 subunit2sql 仅从 gate 管道接收 tempest 测试结果,因此此技术仅适用于 gate 队列中的 tempest 或 grenade 作业。有关更多信息,请参阅 infra subunit2sql 文档 例如,如果您的查询 yaml 文件如下所示

query: >-
  message:"ExceptionA"
test_ids:
  - tempest.api.compute.servers.test_servers.test_update_server_name
  - tempest.api.compute.servers.test_servers_negative.test_server_set_empty_name

只有当 logstash 查询对该运行有命中,并且 test_update_server_name 或 test_server_set_empty name 在该运行期间失败时,才会匹配该 bug。

为了支持快速添加的查询,批准仅添加 1 个新 bug 查询的更改,甚至由核心评审人员自行批准这些更改,在社会上是可以接受的。

添加 Bug 签名

在 gate 中看到的瞬态 bug 中,大多数不是与特定 tempest 测试失败相关的 tempest 中的 bug,而是堆栈中某个地方的问题,可能导致许多 tempest 测试失败。

  1. 在 gate 期间看到瞬态 bug 时,请浏览 日志 并尝试找到与失败相关的日志。越接近根本原因越好。

    • 请注意,查询只能针对 INFO 级别及更高日志消息编写。这是为了避免使搜索集群不堪重负。

    • 由于不允许非投票作业在 gate 队列中,并且 e-r 主要用于跟踪 gate 队列中的 bug,因此它不会花时间跟踪非投票作业中的竞争失败,因为它们本身被认为是不可稳定的(因为它们不投票)。

      • 但是,有一个特殊的“allow-nonvoting”键可以添加到查询 yaml 文件中,以允许跟踪非投票作业 bug 失败的图形。它们不会显示在 bot 中(IRC 或 Gerrit 注释)。

  2. 转到 logstash.openstack.org 并创建一个 elastic search 查询来查找步骤 1 中的日志消息。要查看可以搜索的字段,请单击一个条目。Lucene 查询语法可在 lucene.apache.org 上找到。

  3. 在提交的页脚中添加 Related-Bug 标签,或在 bug 中添加注释,其中包含您识别的查询以及指向该查询搜索的 logstash URL。

    将 logstash 查询链接放在 bug 报告中,在罕见的故障超出日志结果存储的窗口时也很有价值。在这种情况下,bug 可能会被标记为 Incomplete,并且 e-r 查询可能会被删除,仅在故障再次出现时才会被删除。如果 bug 报告中有一个指向查询的链接,则可以轻松跟踪它何时再次开始出现。

  4. 将查询添加到 elastic-recheck/queries/BUGNUMBER.yaml(所有查询都可以在 git.openstack.org 上找到)并推送补丁进行审核。

您还可以帮助分类 未分类的失败作业,这是所有失败的投票 gate 作业的集合,当前没有 elastic-recheck 指纹。

删除 Bug 签名

不再在 logstash 中命中的旧查询以及与已修复或不完整的 bug 关联的查询会定期删除。这是为了尽可能降低在检查作业失败时对 elastic-search 引擎的负载。如果标记为 Incomplete 的 bug 再次出现,则应重新打开该 bug,并添加失败链接以及恢复 e-r 查询。

在查询中具有“suppress-graph: true”的查询通常不应删除,因为我们基本上想保留这些查询,它们是持久的基础设施问题,不会消失。

自动化清理

  1. 运行 elastic-recheck-cleanup 命令

    $ tox -e venv -- elastic-recheck-cleanup -h
    ...
    usage: elastic-recheck-cleanup [-h] [--bug <bug>] [--dry-run] [-v]
    
    Remove old queries where the affected projects list the bug status as one
    of: Fix Committed, Fix Released
    
    optional arguments:
         -h, --help   show this help message and exit
         --bug <bug>  Specific bug number/id to clean. Returns an exit code of
                      1 if no query is found for the bug.
         --dry-run    Print out old queries that would be removed but do not
                      actually remove them.
         -v           Print verbose information during execution.
    

    注意

    您可能希望先使用 --dry-run 选项运行,并在提交之前对删除的查询进行理智检查。

  2. 提交更改并将其推送进行审核

    $ git commit -a -m "Remove old queries: `date +%F`"
    $ git review -t rm-old-queries
    

手动清理

  1. 转到 所有 Pipelines 页面。

  2. 查找底部以灰色突出显示的内容,这意味着它在 10 天内没有命中。

  3. 从这些内容中,查找 Launchpad 中状态为 Fixed/Incomplete/Invalid/Won’t Fix 的内容 - 这些是删除的候选对象。

注意

有时,bug 仍然是 New/Confirmed/Triaged/In Progress,但已经超过 10 天没有命中。应重新评估这些 bug,以查看它们现在是否已修复或不完整/无效,标记为如此,然后删除相关的查询。

本地运行查询

您可以本地执行单个查询并分析搜索结果

$ elastic-recheck-query queries/1331274.yaml
total hits: 133
build_status
  100% FAILURE
build_name
  48% check-grenade-dsvm
  15% check-grenade-dsvm-partial-ncpu
  13% gate-grenade-dsvm
  9% check-grenade-dsvm-icehouse
  9% check-grenade-dsvm-partial-ncpu-icehouse
build_branch
  95% master
  4% stable/icehouse

注意事项

  • html 生成将生成与 Kibana3 的 logstash.json 仪表板一起使用的链接。如果您希望这些生成的文件中的链接正常工作,则需要托管一个带有该仪表板的 Kibana3。

  • 在此处查看 OpenStack ElasticSearch 集群健康状况

开发

除了使用 tox 之外,您还可以运行 make 以列出当前的容器构建和测试命令。

未来工作

  • 将配置文件移动到单独的目录

  • 使单元测试更加健壮

  • 添加调试模式标志

  • 扩展 gating 测试

  • 清理和更好地记录代码

  • 添加检查已解决的 bug 是否返回的能力

  • 停止轮询 ElasticSearch 以发现它是否准备就绪

  • 添加夜间作业以提出删除没有返回命中的 bug 查询的补丁 - Bug 已经 2 周没有出现,必须关闭