Prometheus+Grafana+Alertmanager 搭建监控告警系统

指标监控告警系统

基于Prometheus、Grafana、Alertmanager、Webhook-dingtalk搭建一套指标监控告警系统,整个系统分为三部分:指标数据采集存储端、可视化展示端、告警通知端。实现对服务器、数据库、应用服务等资源的指标监控、可视化展示、指标告警等功能,同时告警通知信息实时推送到钉钉群中。

环境说明

序号

服务名称

版本

作用

部署方式

1

grafana

10.2.4

可视化展示prometheus存储的数据

二进制部署

2

prometheus

2.50.1

收集存储查询采集到数据,配置告警规则

二进制部署

3

node_exporter

1.7.0

采集服务器指标数据

二进制部署

4

dmdb_exporter

0.1

采集DM数据库指标数据

二进制部署

5

alertmanager

0.27.0

接收prometheus发来的警报,进行分组、抑制、静默等操作

二进制部署

6

webhook-dingtalk

2.1.0

对接alertmanager,配置钉钉通知,发送告警通知到钉钉群

二进制部署

1. 指标数据采集存储端

1.1 Prometheus 部署

  1. 安装包下载

下载地址:/

  1. 解压安装

tar -zxvf prometheus-2.50.1.linux-amd64.tar.gz -C /home cd /home mv prometheus-2.50.1.linux-amd64 prometheus

  1. 配置系统服务

vim /usr/lib/systemd/system/prometheus.service

  • 写入

[Unit] Description=prometheus After=network.target [Service] Type=simple User=root ExecStart=/home/prometheus/prometheus \ --config.file=/home/prometheus/prometheus.yml \ --storage.tsdb.path=/home/prometheus \ --storage.tsdb.retention=15d \ --log.level=info Restart=on-failure [Install] WantedBy=multi-user.target

  1. 启动服务

systemctl daemon-reload systemctl start prometheus systemctl enable prometheus

  1. 访问地址

http://部署主机IP:9090

1.2 node_exporter 部署(主机监控)

  1. 安装包下载

下载地址:/

  1. 解压安装

tar -zxvf node_exporter-1.7.0.linux-amd64.tar.gz -C /usr/local cd /usr/local mv node_exporter-1.7.0.linux-amd64 /usr/local/node_exporter

  1. 配置系统服务

vim /usr/lib/systemd/system/node_exporter.service

  • 写入

[Unit] Description=node_exporter Documentation=/ After=network.target [Service] Type=simple User=root ExecStart=/usr/local/node_exporter/node_exporter Restart=on-failure [Install] WantedBy=multi-user.target

  1. 启动服务

systemctl daemon-reload systemctl start node_exporter systemctl enable node_exporter

1.3 dmdb_exporter 部署(达梦数据库监控)

  1. 安装包下载

下载地址:

说明:dmdb_exporter需要下载源码,编译后进行部署,需要安装go语言环境。

  1. 环境检查

go env

  1. 编译打包

go build -o dmdb_exporter

  1. 打包完成后,需要将目录下生成的二进制文件dmdb_exporter和default-metrics.toml都上传到服务器进行启动。

cd /usr/local/dmdb_exporter chmod +x dmdb_exporter

目录结构如下:

  1. 配置系统服务

注意:这里需要在配置文件中,配置达梦数据库的连接信息。

vim /usr/lib/systemd/system/dmdb_exporter.service

  • 写入

[Unit] Description=dmdb_exporter After=network.target [Service] # 配置环境变量,这里需要配置DM数据库的连接信息 Environment=DATA_SOURCE_NAME=dm://SYSDBA:SYSDBA@localhost:5236?autoCommit=true # 启动脚本 ExecStart=/usr/local/dmdb_exporter/dmdb_exporter \ --log.level=info \ --default.metrics=/usr/local/dmdb_exporter/default-metrics.toml \ --web.listen-address=:9161 Restart=always RestartSec=5 StartLimitInterval=0 StartLimitBurst=10 [Install] WantedBy=multi-user.target

  1. 启动服务

systemctl daemon-reload systemctl start dmdb_exporter systemctl enable dmdb_exporter

1.4 prometheus 配置

全局参数说明

配置文件路径: /home/prometheus/prometheus.yml

1.4.1 node_exporter 数据接入

vim /home/prometheus/prometheus.yml

  • 新增job空间,配置采集端信息

scrape_configs: - job_name: "node_exporter" static_configs: - targets: ["192.168.0.15:9100"] labels: server_ip: 192.168.0.15 server_name: 测试环境-数据库服务器 - targets: ["192.168.0.16:9100"] labels: server_ip: 192.168.0.16 server_name: 测试环境-数据库服务器

1.4.2 dmdb_exporter 数据接入

vim /home/prometheus/prometheus.yml

  • 新增job空间,配置采集端信息

# 达梦数据库数据采集 - job_name: "dmdb_exporter" static_configs: - targets: ["192.168.0.16:9161"] labels: server_ip: 192.168.0.16 server_name: 测试环境-达梦数据库 - targets: ["192.168.0.15:9161"] labels: server_ip: 192.168.0.15 server_name: 测试环境-达梦数据库

1.5 prometheus web端说明

  1. 监控目标查看
  1. 指标查询

2. 可视化展示端

1. grafana 部署

下载地址:

  1. 解压安装

tar -zxvf grafana-enterprise-10.2.4.linux-amd64.tar.gz -C /home cd /home mv grafana-enterprise-10.2.4.linux-amd64 grafana

  1. 配置系统服务

vim /usr/lib/systemd/system/grafana.service

  • 写入

[Unit] Description=Grafana instance After=network.target [Service] Type=simple # 工作目录 WorkingDirectory=/home/grafana/ ExecStart=/home/grafana/bin/grafana-server Restart=always [Install] WantedBy=multi-user.target

  1. 启动服务

systemctl daemon-reload systemctl start grafana systemctl enable grafana

2. grafana 使用

访问地址:部署主机IP:3000

默认账号密码:admin/admin

配置文件目录:/home/grafana/grafana.ini

  1. 中文配置

首页>管理>概况>默认首选项

  1. 添加数据源

首页>连接>数据源>prometheus

填写数据源名称和prometheus地址即可,其他信息默认。

  1. 导入仪表盘

官方仪表盘地址:/

推荐仪表盘ID:主机列表-8919、主机详情-12633、DM数据库-19109

首页>仪表板

3. 告警通知端

3.1. alertmanager 部署

  1. 安装包下载

下载地址:/

  1. 解压部署

tar -zxvf alertmanager-0.27.0.linux-amd64.tar.gz -C /home cd /home mv alertmanager-0.27.0.linux-amd64 alertmanager

  1. 配置系统服务

vim /usr/lib/systemd/system/alertmanager.service

  • 写入

[Unit] Description=alertmanager After=network.target [Service] Type=simple ExecStart=/home/alertmanager/alertmanager \ --config.file /home/alertmanager/alertmanager.yml \ --storage.path=/home/alertmanager Restart=on-failure [Install] WantedBy=multi-user.target

  1. 启动服务

systemctl daemon-reload systemctl start alertmanager systemctl enable alertmanager

  1. 访问地址

http://部署主机IP:9093

3.2. 告警规则配置

告警规则在prometheus中配置,通过添加配置文件的形式。

  1. 创建告警规则存放路径

mkdir -p /home/prometheus/rules

  1. 配置主机告警规则文件

vim /home/prometheus/rules/node_exporter.yml

3.2.1 内存使用率告警规则

# 相关的规则设置定义在一个group下。在每一个group中我们可以定义多个告警规则(rule) groups: # 组名,报警规则组名称 - name: 内存告警 rules: - alert: 内存使用率超过80%告警 # expr:基于PromQL表达式告警触发条件,用于计算是否有时间序列满足该条件。 #expr: floor(100 * (1 - (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes) / node_memory_MemTotal_bytes)) > 80 expr: floor(100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))) > 80 # for:评估等待时间,可选参数。用于表示只有当触发条件持续一段时间后才发送告警。在等待期间新产生告警的状态为pending。 # for语句会使 Prometheus 服务等待指定的时间, 然后执行查询表达式。(for 表示告警持续的时长,若持续时长小于该时间就不发给alertmanager了,大于该时间再发。for的值不要小于prometheus中的scrape_interval,例如scrape_interval为30s,for为15s,如果触发告警规则,则再经过for时长后也一定会告警,这是因为最新的度量指标还没有拉取,在15s时仍会用原来值进行计算。另外,要注意的是只有在第一次触发告警时才会等待(for)时长。) for: 1m # labels:自定义标签,允许用户指定要附加到告警上的一组附加标签。 labels: # severity: 指定告警级别,有三种等级,分别为:警告、严重、紧急,严重等级依次递增。 severity: '<font color="#0000FF">警告</font>' # annotations: 附加信息,比如用于描述告警详细信息的文字等,annotations的内容在告警产生时会一同作为参数发送到Alertmanager。 annotations: servername: "{{ $labels.server_name }}" server_ip: "{{ $labels.server_ip }}" value: "{{ $value }}" description: "**{{ $labels.server_name }}**内存使用率持续1分钟超过**80%**, 请及时处理! 当前值**{{ $value }}%**。" - alert: 内存使用率超过90%告警 expr: floor(100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))) > 90 for: 1m labels: severity: '<font color="#FFA500">严重</font>' annotations: servername: "{{ $labels.server_name }}" server_ip: "{{ $labels.server_ip }}" value: "{{ $value }}" description: "**{{ $labels.server_name }}**内存使用率持续1分钟超过**90%**, 请马上处理! 当前值**{{ $value }}%**。"

3.2.2 CPU使用率告警规则

- name: CPU告警 rules: - alert: CPU使用率超过80%告警 expr: floor(100 - (irate(node_cpu_seconds_total{mode="idle"}[1m]) * 100)) > 80 for: 1m labels: severity: '<font color="#0000FF">警告</font>' annotations: servername: '{{ $labels.server_name }}' server_ip: '{{ $labels.server_ip }}' value: '{{ $value }}' description: '**{{ $labels.server_name }}**CPU使用率持续1分钟超过**80%**, 请及时处理! 当前值**{{ $value }}%**。' - alert: CPU使用率超过90%告警 expr: floor(100 - (irate(node_cpu_seconds_total{mode="idle"}[1m]) * 100)) > 90 for: 1m labels: severity: '<font color="#FFA500">严重</font>' annotations: servername: "{{ $labels.server_name }}" server_ip: "{{ $labels.server_ip }}" value: "{{ $value }}" description: "**{{ $labels.server_name }}**CPU使用率持续1分钟超过**90%**, 请马上处理! 当前值**{{ $value }}%**。"

3.2.3 CPU负载告警规则

- name: CPU告警 rules: - alert: CPU负载超过80%告警 expr: node_load1 > (0.8 * count(node_cpu_seconds_total{mode='idle'}) by (instance,job,server_ip,server_name)) for: 1m labels: severity: '<font color='#0000FF'>警告</font>' annotations: servername: '{{ $labels.server_name }}' server_ip: '{{ $labels.server_ip }}' value: '{{ $value }}' description: '**{{ $labels.server_name }}**CPU负载最近1分钟超过**90%**, 请及时处理! 当前值**{{ $value }}**。' - alert: CPU负载超过90%告警 expr: node_load1 > (0.9 * count(node_cpu_seconds_total{mode='idle'}) by (instance,job,server_ip,server_name)) for: 1m labels: severity: '<font color='#FFA500'>严重</font>' annotations: servername: '{{ $labels.server_name }}' server_ip: '{{ $labels.server_ip }}' value: '{{ $value }}' description: '**{{ $labels.server_name }}**CPU负载最近1分钟超过**80%**, 请马上处理! 当前值**{{ $value }}**。'

3.2.4 磁盘使用率告警规则

- name: 磁盘告警 rules: - alert: 磁盘 **/** 目录使用率超过90%告警 expr: floor(100 * ((node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_avail_bytes{mountpoint="/"}) / node_filesystem_size_bytes{mountpoint="/"})) >90 for: 30m labels: severity: '<font color="#0000FF">警告</font>' annotations: servername: "{{ $labels.server_name }}" server_ip: "{{ $labels.server_ip }}" value: "{{ $value }}" description: "**{{ $labels.server_name }}**磁盘 **/** 目录使用率已经超过阈值**90%**, 请及时处理! 当前值**{{ $value }}%**。" - alert: 磁盘 **/home** 目录使用率超过90%告警 expr: floor(100 * ((node_filesystem_size_bytes{mountpoint="/home"} - node_filesystem_avail_bytes{mountpoint="/home"}) / node_filesystem_size_bytes{mountpoint="/home"})) >90 for: 30m labels: severity: '<font color="#0000FF">警告</font>' annotations: servername: "{{ $labels.server_name }}" server_ip: "{{ $labels.server_ip }}" value: "{{ $value }}" description: "**{{ $labels.server_name }}**磁盘 **/home** 目录使用率已经超过阈值**90%**, 请及时处理! 当前值**{{ $value }}%**。" - alert: 磁盘 **/data** 目录使用率超过90%告警 expr: floor(100 * ((node_filesystem_size_bytes{mountpoint="/data"} - node_filesystem_avail_bytes{mountpoint="/data"}) / node_filesystem_size_bytes{mountpoint="/data"})) >90 for: 30m labels: severity: '<font color="#0000FF">警告</font>' annotations: servername: "{{ $labels.server_name }}" server_ip: "{{ $labels.server_ip }}" value: "{{ $value }}" description: "**{{ $labels.server_name }}**磁盘 **/data** 目录使用率已经超过阈值**90%**, 请及时处理! 当前值**{{ $value }}%**。"

3.2.5 服务器离线告警规则

- name: 离线告警 rules: - alert: 服务器离线告警 expr: up{instance =~ ".*:(9100|9200)"} == 0 for: 30s labels: severity: '<font color="#FF0000">紧急</font>' annotations: servername: "{{ $labels.server_name }}" server_ip: "{{ $labels.server_ip }}" value: "{{ $value }}" description: "**{{ $labels.server_name }}**离线了,可能出现宕机情况, 请立即检查处理! "

3.2.6 数据库离线告警规则
  1. 配置DM数据库告警规则文件

vim /home/prometheus/rules/dmdb_exporter.yml

  • 写入

groups: - name: 达梦数据库告警 rules: - alert: 达梦数据库离线告警 expr: dmdb_up{instance =~ ".*:9161"} == 0 for: 30s labels: severity: '<font color="#FFA500">严重</font>' annotations: servername: "{{ $labels.server_name }}" server_ip: "{{ $labels.server_ip }}" value: "{{ $value }}" description: "**{{ $labels.server_name }}**服务离线了,可能出现数据库停止情况, 请马上检查处理! "

3.3 告警信息推送

  1. 修改prometheus.yml文件

修改完成后需要重启prometheus服务

  1. 告警规则查看

访问prometheusweb端查看配置的规则

  1. 告警信息查看

访问alertmanagerweb端查看触发的告警

3.4 webhook_dingtalk 部署

  1. 安装包下载

下载地址:

  1. 解压安装

tar -zxvf prometheus-webhook-dingtalk-2.1.0.linux-amd64.tar.gz -C /home cd /home mv prometheus-webhook-dingtalk-2.1.0.linux-amd64 prometheus-webhook-dingtalk

  1. 配置系统服务

vim /usr/lib/systemd/system/prometheus-webhook-dingtalk.service

  • 写入

[Unit] Description=The prometheus webhook dingtalk After=network-online.target Wants=network-online.target [Service] WorkingDirectory=/home/prometheus-webhook-dingtalk ExecStart=/home/prometheus-webhook-dingtalk/prometheus-webhook-dingtalk \ --config.file=config.yml \ --web.enable-lifecycle \ --web.enable-ui KillSignal=SIGQUIT Restart=always RestartPreventExitStatus=1 6 SIGABRT TimeoutStopSec=5 KillMode=process PrivateTmp=true LimitNOFILE=1048576 LimitNPROC=1048576 [Install] WantedBy=multi-user.target

  1. 启动服务

systemctl daemon-reload systemctl start prometheus-webhook-dingtalk systemctl enable prometheus-webhook-dingtalk

  1. 访问地址

http://部署主机IP:8060/ui

3.5 告警通知模版配置

  1. 创建模版存放目录

mkdir -p /home/prometheus-webhook-dingtalk/templates

  1. 配置模版文件

vim /home/prometheus-webhook-dingtalk/templates/template2.tmpl

  • 写入

{{ define "__subject" }} [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ end }} {{ define "__alert_list" }}{{ range . }} --- {{ if .Labels.owner }}@{{ .Labels.owner }}{{ end }} --- **告警名称**: {{ .Labels.alertname }} **告警主机**: {{ .Labels.server_ip }} **告警级别**: {{ .Labels.severity }} **告警描述**: {{ index .Annotations "description" }} **告警时间**: {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }} **查看详情**: http://192.168.0.22:3000 {{ end }}{{ end }} {{ define "__resolved_list" }}{{ range . }} --- **告警名称**: {{ .Labels.alertname }} **告警主机**: {{ .Labels.server_ip }} **告警级别**: {{ .Labels.severity }} **告警描述**: {{ index .Annotations "description" }} **告警时间**: {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }} **恢复时间**: {{ dateInZone "2006.01.02 15:04:05" (.EndsAt) "Asia/Shanghai" }} {{ end }}{{ end }} {{ define "default.title" }} {{ template "__subject" . }} {{ end }} {{ define "default.content" }} {{ if gt (len .Alerts.Firing) 0 }} **====== 侦测到{{ .Alerts.Firing | len }}个告警 ======** {{ template "__alert_list" .Alerts.Firing }} --- {{ end }} {{ if gt (len .Alerts.Resolved) 0 }} **====== 恢复{{ .Alerts.Resolved | len }}个故障 ======** {{ template "__resolved_list" .Alerts.Resolved }} {{ end }} {{ end }} {{ define "ding.link.title" }}{{ template "default.title" . }}{{ end }} {{ define "ding.link.content" }}{{ template "default.content" . }}{{ end }} {{ template "default.title" . }} {{ template "default.content" . }}

3.6 创建告警机器人

  1. 在钉钉上建一个告警通知群
  2. 添加一个告警机器人

3. 填写以下内容,并复制出加签后生成的码

  1. 复制Webhook 地址

3.7 告警信息发布钉钉配置

  1. 修改alertmanager.yml文件,修改配置后需要重启alertmanager服务。

vim /home/alertmanager/alertmanager.yml

  • 如下

# 这个部分定义了警报路由规则,指定了如何处理不同类型的警报。 route: # 根据警报名称(alertname)对警报进行分组,这意味着具有相同警报名称的警报将被分组在一起. group_by: ['alertname'] # 在相同组内的警报被发送到接收器之前等待的时间。在这里,设置为30秒,意味着在同一组中的所有警报被收集后,将等待30秒,然后将它们发送到接收器。 group_wait: 30s # 组间发送警报的时间间隔。在这里,设置为30秒,意味着每隔30秒发送一次警报。 group_interval: 30s # 如果警报持续存在,多长时间重复发送一次。在这里,设置为1小时,意味着如果警报持续存在,则每隔1小时重复发送一次。 repeat_interval: 1h # 指定接收警报的接收器的名称。在这里,设置为名为 `web.hook` 的接收器。 receiver: 'web.hook' # 这个部分定义了接收警报的接收器。 receivers: # 接收器的名称,这个名称与上面的路由规则中指定的接收器名称相匹配。 - name: 'web.hook' # 配置用于发送警报的 Webhook 信息。 webhook_configs: # 指定接收警报的 Webhook 的 URL 地址,即 webhook_dingtalk 地址,只需修改IP和端口 - url: 'http://192.168.0.2:8060/dingtalk/webhook1/send' # 设置为 false,表示不发送已解决的警报。 send_resolved: false # 这个部分定义了抑制规则,用于指定哪些警报应该被抑制,以避免出现重复或不必要的警报。 inhibit_rules: # 指定了要匹配的源警报的属性。 - source_match: severity: 'critical' # 指定了要匹配的目标警报的属性。 target_match: severity: 'warning' # 指定了在这两种类型的警报中匹配的属性列表。在这里,设置为匹配警报名称、开发环境和实例。这意味着当源警报和目标警报都具有相同的警报名称、开发环境和实例时,目标警报将被抑制。 equal: ['alertname', 'dev', 'instance']

  1. 配置webhook-dingtalk配置文件,配置完成要重启prometheus-webhook-dingtalk服务

/home/prometheus-webhook-dingtalk/config.yml

  • 如下

# 请求超时时间 # timeout: 5s # 禁用内置的模板,内置模板通常是在生成警报消息时使用的默认模板。 #no_builtin_template: true # 这个部分定义了警报消息的模板文件路径。在这里,使用了两个模板文件 templates: - templates/template1.tmpl - templates/template2.tmpl ## You can also override default template using `default_message` ## The following example to use the 'legacy' template from v0.3.0 #default_message: # title: '{{ template "legacy.title" . }}' # text: '{{ template "legacy.content" . }}' # 这个部分定义了目标(或称为 "profiles")。在这个配置中,有一个名为 `webhook1` 的目标,它定义了如何将警报发送到指定的 Webhook URL。 targets: webhook1: # 指定了接收警报的 Webhook 的 URL 地址,这里是钉钉机器人的 Webhook URL。 url: # 如果需要对发送的消息进行签名,可以指定一个密钥(secret),这个密钥用于生成消息的签名,以确保消息的完整性和安全性,这里是钉钉机器人的密钥(secret)。 secret: SEC071b965b933794a3f5a39349ef9538a81b1412776 # 定义了要发送的消息内容,这里使用了两个模板,即之前配置好的模版。 message: # 指定了消息的标题,使用模板 `ding.link.title` 来生成。 title: '{{ template "ding.link.title" . }}' # 指定了消息的正文内容,使用模板 `ding.link.content` 来生成。 text: '{{ template "ding.link.content" . }}'

  1. 配置完成后,重启prometheus-webhook-dingtalk服务,访问 prometheus-webhook-dingtalkweb端查看模版是否生效
  1. 模版生效后,在产生告警时会将告警信息发布到钉钉群中。效果如下:

查看详情可以配置成grafana的地址