使用Jiralert实现AlertManager告警对接Jira

使用,jiralert,实现,alertmanager,告警,对接,jira · 浏览次数 : 222

小编点评

**Jiralert 镜像地址:** *quay.io/repository/jiralert/jiralert-linux-amd64?tab=tags **Jiralert 配置:** *Global defaults, applied to all receivers where not explicitly overridden.* **Jiralert receivers:** *name: 'jiralert' *project: 'YOUR-JIRA-PROJECT' *add_group_labels: true *auto_resolve: state: 'Resolve this issue' **Jiralert auto_resolve:** *latest **Jiralert auto_resolve 的 state:** *Resolve this issue* **Jiralert reopen_duration:** *多久时间之内的问题会重新打开,默认是 always reopen **其他疑难情况:** *如果没有正确认证登录导致的,则可能出现以下错误: *The value 'XXX' does not exist for the field 'project'.* **解决方案:** *确保 JIRalert 的所有配置都正确设置。 *检查 JIRalert 的 receivers 配置中是否设置了正确的 transition。 *确保 JIRalert 的 auto_resolve 配置正常运行。 *如果出现错误,请尝试检查 JIRalert 的 logs。

正文

简介

Alertmanager 处理由客户端应用程序(如 Prometheus server)发送的警报。它负责去重(deduplicating),分组(grouping),并将它们路由(routing)到正确的接收器(receiver)集成,如电子邮件,微信,或钉钉。它还负责处理警报的静默/屏蔽(silencing)、定时发送/不发送(Mute)和抑制(inhibition)问题。

AlertManager 作为 开源的为 Prometheus 而设计的告警应用, 已经具备了告警应用各类丰富、灵活、可定制的功能:

Jiralert

用于JIRA的Prometheus Alertmanager Webhook Receiver

JIRAlert实现了Alertmanager的webhook HTTP API,并连接到一个或多个JIRA实例以创建高度可配置的JIRA Issues。每个不同的 Groupkey 创建一个Issue--由Alertmanager的路由配置部分的group_by参数定义--但在警报解决时不会关闭(默认参数, 可调整)。我们的期望是,人们会查看这个issue。,采取任何必要的行动,然后关闭它。如果没有人的互动是必要的,那么它可能首先就不应该报警。然而,这种行为可以通过设置auto_resolve部分进行修改,它将以所需的状态解决jira issue。

如果一个相应的JIRA issue。已经存在,但被解决了,它将被重新打开(reopened)。在解决的状态和重开的状态之间必须存在一个JIRA transition--如reopen_state--否则重开将失败。可以选择定义一个 "won't fix" 的决议(resolution)--由wont_fix_resolution定义:有此决议的JIRA问题将不会被JIRAlert重新打开。

安装 Jiralert

Jiralert 的安装比较简单, 主要由 Deployment、Secret(Jiralert 的配置)和 Service 组成。典型示例如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: jiralert
spec:
  selector:
    matchLabels:
      app: jiralert
  template:
    metadata:
      labels:
        app: jiralert
    spec:
      containers:
      - name: jiralert
        image: quay.io/jiralert/jiralert-linux-amd64:latest
        imagePullPolicy: IfNotPresent
        args:
        - "--config=/jiralert-config/jiralert.yml"
        - "--log.level=debug"
        - "--listen-address=:9097"
        readinessProbe:
          tcpSocket:
            port: 9097
          initialDelaySeconds: 15
          periodSeconds: 15
          timeoutSeconds: 5
        livenessProbe:
          tcpSocket:
            port: 9097
          initialDelaySeconds: 15
          periodSeconds: 15
          timeoutSeconds: 5
        ports:
        - containerPort: 9091
          name: metrics
        volumeMounts:
        - mountPath: /jiralert-config
          name: jiralert-config
          readOnly: true
      volumes:
      - name: jiralert-config
        secret:
          secretName: jiralert-config
---
apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: jiralert-config
stringData:
  jiralert.tmpl: |-
    {{ define "jira.summary" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join "," }}{{ end }}
    
    {{ define "jira.description" }}{{ range .Alerts.Firing }}Labels:
    {{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }}
    {{ end }}
    
    Annotations:
    {{ range .Annotations.SortedPairs }} - {{ .Name }} = {{ .Value }}
    {{ end }}
    
    Source: {{ .GeneratorURL }}
    {{ end }}
    
    CommonLabels:
    {{ range .CommonLabels.SortedPairs }} - {{ .Name }} = {{ .Value}}
    {{ end }}
    
    GroupLabels:
    {{ range .GroupLabels.SortedPairs }} - {{ .Name }} = {{ .Value}}
    {{ end }}
    {{ end }}
  jiralert.yml: |-
    # Global defaults, applied to all receivers where not explicitly overridden. Optional.
    template: jiralert.tmpl
    defaults:
      # API access fields.
      api_url: https://jira.example.com
      user: foo
      password: bar
      # The type of JIRA issue to create. Required.
      issue_type: Bug
      # Issue priority. Optional.
      priority: Major
      # Go template invocation for generating the summary. Required.
      summary: '{{ template "jira.summary" . }}'
      # Go template invocation for generating the description. Optional.
      description: '{{ template "jira.description" . }}'
      # State to transition into when reopening a closed issue. Required.
      reopen_state: "REOPENED"
      # Do not reopen issues with this resolution. Optional.
      wont_fix_resolution: "Won't Fix"
      # Amount of time after being closed that an issue should be reopened, after which, a new issue is created.
      # Optional (default: always reopen)
      # reopen_duration: 30d
    
    # Receiver definitions. At least one must be defined.
    # Receiver names must match the Alertmanager receiver names. Required.
    receivers:
    - name: 'jiralert'
      project: 'YOUR-JIRA-PROJECT'
---
apiVersion: v1
kind: Service
metadata:
  name: jiralert
spec:
  selector:
    app: jiralert
  ports:
  - port: 9097
    targetPort: 9097                

相应 AlertManager 的配置:

...
receivers:
- name: jiralert
  webhook_configs:
  - send_resolved: true
    url: http://jiralert:9097/alert
routes:
- receiver: jiralert
  matchers:
  - severity = critical
  continue: true
...

📝 说明:

  • 官方 jiralert 镜像地址: https://quay.io/repository/jiralert/jiralert-linux-amd64?tab=tags
    • 官方 jiralert latest 镜像: <quay.io/jiralert/jiralert-linux-amd64:latest>
  • jiralert.tmpl 类似 AlertManager 的 Template, 发送到 Jira 的 Issue 会以此为模板
  • jiralert.yml Jiralert 的配置文件
    • defaults 基础版配置
    • receivers 可以设置多个 receiver, 届时 AlertManager 要发到哪个 Jira 的receiver就需要与这个 jiralert 的receiver 同名. (比如上面的例子, 都是jiralert)

Jiralert 配置

经过生产实践的 Jiralert 完整配置如下:

# Global defaults, applied to all receivers where not explicitly overridden. Optional.
template: jiralert.tmpl
defaults:
  # API access fields.
  api_url: https://example.atlassian.net
  user: <your-account-email>
  password: '<your-account-api-token>'
  # The type of JIRA issue to create. Required.
  issue_type: Support
  # Issue priority. Optional.
  priority: High
  # Go template invocation for generating the summary. Required.
  summary: '{{ template "jira.summary" . }}'
  # Go template invocation for generating the description. Optional.
  description: '{{ template "jira.description" . }}'
  # State to transition into when reopening a closed issue. Required.
  reopen_state: "Back to in progress"
  # Do not reopen issues with this resolution. Optional.
  wont_fix_resolution: "Won't Do"
  # Amount of time after being closed that an issue should be reopened, after which, a new issue is created.
  # Optional (default: always reopen)
  reopen_duration: 30d

# Receiver definitions. At least one must be defined.
# Receiver names must match the Alertmanager receiver names. Required.
receivers:
- name: 'jiralert'
  project: <your-project-code>
  add_group_labels: true
  auto_resolve:
    state: 'Resolve this issue'

📝详细说明如下:

  1. api_url: Jira 的地址, 如果用的是 Jira 的 SaaS 服务, 就是https://<tenant>.atlassian.net
  2. 认证:
    1. 对于公有云版的 Jira, 只能用 userpassword, 其中:
      1. user 填写你的账号邮箱地址;
      2. password 需要先在 API Token | Atlassian account 申请 API Token. (🐾注意: 登录用的密码是无法认证通过的)
    2. 对于其他版本, 也可以填写使用 personal_access_token 进行认证. 其值为: user@example.com:api_token_string 的 base64 编码后字符串. 具体说明见: Basic auth for REST APIs (atlassian.com)
  3. issue_type: 根据您的 Jira Issue Type 来填写, 可能是: Alert Support Bug New Feature 等等或其他
  4. priority 根据您的 Issue priority 来填写, 可能是: Critical High Medium Low 等等或其他
  5. reopen_state: Jira 的问题已经关闭, 要重新打开, 需要的 transition, 如: Back to in progress. (🐾注意: 这里需要填写的是您自定义的 transition, 而非 status)
  6. wont_fix_resolution: 带有这个 resolution (解决方案)的问题就不会重新打开. 如: Won't Do Won't Fix, 需要根据自己的 resolution 定义内容来填写.
  7. reopen_duration: 多久时间之内的问题会重新打开, 默认是 always reopen, 可以设置为如: 30d, 表示这个问题如果30天以前有同样的问题, 新开一个 Issue, 而不是重新打开老的 Issue.
  8. receivers: 可以定义多个 receivers, 指向不同 project
  9. project: Jira 的 Project ID, 是 Project 详细名字的首字母大写. 如 Project 是 For Example, 这里就填写 FE
  10. add_group_labels: 是否要将 AlertManager 的 Group Labels 加到 Jira 的 Labels. (🐾注意: Jira Labels 的 Value 是不能有空格的, 所以如果你的 AlertManager 的 Group Label 的Value如果有空格, 不要开启此项功能)
  11. auto_resolve: 最新 1.2 版本新增的功能, 当告警恢复了, 可以自动 resolve 对应的 Jira Issue.
    1. state: 'Resolve this issue' 这里也是要填写您预定义的 Jira 解决该问题的 transition 而非 status, 如'Resolve this issue'.

其他疑难情况

如果你碰到各种诡异的日志, 原因大部分都是因为没有正确认证登录导致的, 典型的比如这个报错:

The value 'XXX' does not exist for the field 'project'.

事实上就是因为没有正确认证登录导致的.

具体可以参考这里: Solved: REST error "The value 'XXX' does not exist for the... (atlassian.com)

还有一类报错, 提示您无法 transition an issue, 这往往是因为以下几种原因:

  1. Jiralert 中reopen_stateauto_resolvestate 没有填写正确的 transition
  2. 您用的账号没有相应的权限
  3. 该 Issue 现在所处的状态(比如 Closed)不允许再进行 transition

具体可以参考这里: I can't transition an issue in my Jira project - W... - Atlassian Community

最终效果

如下图:

Jiralert 效果

可以创建 Issue, 更新 Summary, 更新 Description, 更新 Resolution, 更新 Status; 同样问题再次出现, reopen 之前的 Issue...

🎉🎉🎉

📚️ 参考文档

三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.

与使用Jiralert实现AlertManager告警对接Jira相似的内容:

使用Jiralert实现AlertManager告警对接Jira

简介 Alertmanager 处理由客户端应用程序(如 Prometheus server)发送的警报。它负责去重(deduplicating),分组(grouping),并将它们路由(routing)到正确的接收器(receiver)集成,如电子邮件,微信,或钉钉。它还负责处理警报的静默/屏蔽(

使用Cloudflare Worker加速docker镜像

前言 开发者越来越难了,现在国内的docker镜像也都️了,没有镜像要使用docker太难了,代理又很慢 现在就只剩下自建镜像的办法了 GitHub上有开源项目可以快速搭建自己的镜像库,不过还是有点麻烦,还好Cloudflare暂时还活着‍ 本文记录一下使用 Cloudf

使用C#/.NET解析Wiki百科数据实现获取历史上的今天

创建一个webapi项目做测试使用。 创建新控制器,搭建一个基础框架,包括获取当天日期、wiki的请求地址等 创建一个Http请求帮助类以及方法,用于获取指定URL的信息 使用http请求访问指定url,先运行一下,看看返回的内容。内容如图右边所示,实际上是一个Json数据。我们主要解析 大事记 部

Pybind11和CMake构建python扩展模块环境搭建

使用pybind11的CMake模板来创建拓展环境搭建 从Github上下载cmake_example的模板,切换分支,并升级pybind11子模块到最新版本 拉取pybind11使用cmake构建工具的模板仓库 git clone --recursive https://github.com/mr

说说RabbitMQ延迟队列实现原理?

使用 RabbitMQ 和 RocketMQ 的人是幸运的,因为这两个 MQ 自身提供了延迟队列的实现,不像用 Kafka 的同学那么苦逼,还要自己实现延迟队列。当然,这都是题外话,今天咱们重点来聊聊 RabbitMQ 延迟队列的实现原理,以及 RabbitMQ 实现延迟队列的优缺点有哪些? 很多人

使用FModel提取游戏资产

目录前言FModel简介FModel安装FModel使用初次使用资产预览资产导出附录dumperDumper-7生成usmap文件向游戏中注入dll 前言 这篇文章仅记录我作为初学者使用FModel工具提取某款游戏模型的过程。 FModel简介 FModel是一个开源软件,可以用于查看和提取UE4-

使用GSAP制作动画视频

GSAP 3Blue1Brown给我留下了深刻印象。利用动画制作视频,内容简洁,演示清晰。前两天刚好碰到一件事,我就顺便学习了一下怎么用代码做动画。 以javascrip为例,有两个动画引擎,GSAP和Animajs。由于网速的原因,询问了GPT后,我选择了GSAP来制作我的第一个动画视频。 制作动

使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类就这么简单!

前言 今天大姚给大家分享一个.NET开源、免费、跨平台(支持Windows、Linux、macOS多个操作系统)的机器学习框架:ML.NET。并且本文将会带你快速使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类。 ML.NET框架介绍 ML.NET 允许开发人员在其 .NET 应用程序

使用libzip压缩文件和文件夹

简单说说自己遇到的坑: 分清楚三个组件:zlib、minizip和libzip。zlib是底层和最基础的C库,用于使用Deflate算法压缩和解压缩文件流或者单个文件,但是如果要压缩文件夹就很麻烦,主要是不知道如何归档,在zip内部形成对应的目录。这时就需要用更高级别的库,也就是minizip或li

使用gzexe加密shell脚本

使用 gzexe 加密 shell 脚本是一个相对简单的过程。以下是具体的步骤: 编写你的 shell 脚本:首先,你需要有一个 shell 脚本文件,比如 myscript.sh。 确保脚本可执行:使用 chmod 命令确保你的脚本文件是可执行的: chmod +x myscript.sh 使用