TSDB
(时序数据库)2.8.1
--storage.tsdb.path
启动参数表示数据存储的位置,我的数据目录为: /prometheus
pull
和push
两种对应的数据采集传输方式
pull
是指:客户端安装已有的exporter(客户端插件)在系统后,exporter以守护进程的模式运行并开始采集数据,exporters本身也是和thhp,会建立一个端口,共外界访问.push
是指:客户端或者服务端安装官方提供的pushgateway
插件,然后使用我们运维自行开发的各种脚本把监控数据组织成key/value的形式,metrices形式发送给pushgateway之后,pushgateway会在推送给Prometheus.实现数据的监控-h, --help 显示帮助信息
--version 显示版本
--config.file="prometheus.yml" 指定配置文件
--web.listen-address="0.0.0.0:9090" 指定监听的端口
--web.max-connections=512 最大连接数
--web.enable-lifecycle 是否开启reload和shutdown的远程API
--web.enable-admin-api 是否开启管理API
--web.console.templates="consoles" 控制台模板目录
--web.console.libraries="console_libraries" 控制台库文件目录
--storage.tsdb.path="data/" 数据存储路径
--storage.tsdb.retention.time 数据保留时间,默认15天
--query.timeout=2m 查询超时时间
--query.max-concurrency=20 最大并发查询数量
--query.max-samples=50000000 单次查询返回的最大样本数
--log.level=info 日志级别: [debug, info, warn, error]
--log.format=logfmt 日志输出格式:[logfmt, json]
IP | houstname | 配置 | 备注 |
---|---|---|---|
192.168.0.212 | ops-002 | 4c8g + 290G | centos7 |
# repo系统源和docker源
curl -o /etc/yum.repos.d/Centos-7.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -o /etc/yum.repos.d/docker-ce.repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y update
ntpdate ntp2.aliyun.com
/sbin/hwclock --systohc
官网
# 下载最新版本的prometheus的各个组件
docker pull prom/prometheus
docker pull prom/node-exporter
docker pull grafana/grafana
docker pull google/cadvisor
docker pull prom/blackbox-exporter
docker pull quay.io/prometheus/alertmanager
docker pull timonwong/prometheus-webhook-dingtalk
# 创建目录,容器中使用的是65534用户启动的
mkdir -p /data/prometheus/conf
chown -R 65534. /data/prometheus
vim /data/prometheus/conf/prometheus.yml
global:
scrape_interval: 15s # 采集数据的时间间隔,默认15s
evaluation_interval: 15s # 评估规则的间隔时间,默认15s
alerting: # alertmanagers用于告警
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
rule_files: # 规则配置文件
# - "first_rules.yml"
# - "second_rules.yml"
scrape_configs: # 抓取哪里的数据到TSDB(时序数据库)
- job_name: prometheus
static_configs:
- targets: ['localhost:9090']
- job_name: docker
static_configs:
- targets: ['192.168.0.212:8080']
# 启动prometheus服务端
docker run --restart=always -p 9090:9090 -v /data/prometheus/conf/prometheus.yml:/etc/prometheus/prometheus.yml -v /data/prometheus/data:/prometheus -d prom/prometheus
# docker宿主机上启动cadvisor
docker run --restart=always -v/var/run:/var:rw -v /sys/fs/cgroup/:/sys/fs/cgroup:ro -v /var/lib/docker/:/var/lib/docker:ro -p 8080:8080 -d google/cadvisor
插件 | 说明 | 备注 |
---|---|---|
cadvisor | cadvisor可以搜集一台机器上所有运行的容器信息, 且提供基础查询界面和http接口 | |
alertmanagers | 实现告警功能 | |
node_exporter | 为server端提供被监控基础数据信息 | |
blackbox_exporter | 监控端口,http、dns、tcp、icmp 的监控数据采集 | |
mysql_exporter | 监控mysql | |
… |
下载插件
node_exporter
实现服务器基础监控node_exporter
相当于是agent端, 在被监控的节点上安装# 我下载的1.2.2版本,做好软连接,控制版本
tar xf node_exporter-1.2.2.linux-amd64.tar.gz
ln -s /opt/node_exporter-1.2.2.linux-amd64 /opt/node_exporter
ln -s /opt/node_exporter/node_exporter /usr/bin/node_exporter
which node_exporter
vim /lib/systemd/system/node_exporter.service
[Unit]
Description=https://prometheus.io
[Service]
ExecStart=/opt/node_exporter/node_exporter
Restart=on-failure
[Install]
WantedBy=multi-user.target
# 启动服务,启动后还是检查一下是否起来并检查端口,默认是9100端口
systemctl daemon-reload
systemctl enable node_exporter;systemctl restart node_exporter
# 通过--web.listen-address=":9100"这条参数改默认端口,改了端口后,记得在server端也要改配置文件.
node_exporter --help
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:9090']
- job_name: cadvisor-docker
static_configs:
- targets: ['192.168.0.212:8080']
- job_name: node_exporter-agent
static_configs:
- targets: ['192.168.0.31:9100','192.168.0.212:9100']
模板下载
# 持久化并启动
mkdir /data/grafana
chmod -R 777 /data/grafana
docker run --restart=always --name=grafana -d -p 3000:3000 -v /data/grafana:/var/lib/grafana grafana/grafana
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yhJLdilm-1633345453676)(images/image-20210811104242314.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Tf24hP4-1633345453680)(images/image-20210811113913428.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KIBiCTHZ-1633345453681)(images/image-20210811104109616.png)]
qlite3 /data/grafana/grafana.db
.tables
# 查看表中数据
select * from user;
# 更改密码为admin
update user set password = '59acf18b94d7eb0694c61e60ce44c110c7a683ac6a8f09580d626f90f4a242000746579358d77dd9e570e83fa24faa88a8a6', salt = 'F3FAxVm33R' where login = 'admin';
官网解释
pull
部署在k8s或主机上的各种类别的监控指标数据,然后基于 PromQL
对这些已经存储在本地存储 HDD/SSD
的 TSDB
中的指标定义阈值警报规则 Rules
。Prometheus会根据配置的参数周期性的对警报规则进行计算,如果满足警报条件,生产一条警报信息,将其推送到 Alertmanager 组件,Alertmanager 收到警报信息之后,会对警告信息进行处理,进行 分组 Group
并将它们通过定义好的路由 Routing
规则转到 正确的接收器 receiver
push
的方式来实现Email
Slack
钉钉、企业微信 Robot(webhook)
企业微信
等,最终异常事件 Warning
、Error
通知给定义好的接收人,其中如钉钉是基于第三方通知来实现的,对于通知人定义是在钉钉的第三方组件中配置PromQL
定义规则,更多时候是对相关的多条警报进行分组后统一定义。这些定义会在后面说明与其管理方法。可以把 Alertmanager 中的分组 Grouping
、抑制 Inhibition
、延迟 Silences
# 填自己的钉钉token
docker run --restart=always -d --name webhook -p 8060:8060 -v /data/webhook/conf/config.yml:/etc/prometheus-webhook-dingtalk/config.yml timonwong/prometheus-webhook-dingtalk:latest --ding.profile="webhook1=https://oapi.dingtalk.com/robot/send?access_token=cd5e56c8446ad667b5b6acf21e27a26aec3b2e76f33883eb6727e60952f1f24f"
alertmanager.yml
for
,经历evaluation_interval
间隔后由inactive
转换成pending
,再经历evaluation_interval
间隔后由pending
转换成firing
, 因此至少需要2倍的evaluation_interval
,告警才会触发global:
resolve_timeout: 5m
# root route
route:
group_by: ['docker', 'node', 'prometheus', 'instance']
group_interval: 5m
group_wait: 30s
repeat_interval: 3h
receiver: webhook
# will remain at the root node and be dispatched to 'default-receiver'.
routes:
# A set of regex-matchers an alert has to fulfill to match the node.
# - match_re:
# service: ^(node|docker)$
# receiver: webhook
# If any child route does not match, it will be sent directly to the recipient through the parent route configuration
- match:
severity: 'Critical'
receiver: 'webhook'
- match_re:
severity: ^(Warning|Disaster)$
receiver: 'webhook'
# - receiver: ops
# group_wait: 10s
# match:
# status: 'High'
receivers:
- name: 'webhook'
webhook_configs:
- url: http://192.168.0.212:8060/dingtalk/webhook1/send
send_resolved: true
#inhibit_rules:
# - source_match:
# status: 'High'
# target_match:
# status: 'Warning'
# equal: ['alertname','operations', 'instance']
docker run -d -p 9093:9093 --restart=always --name alertmanager -v /data/alertmanager/conf/alertmanager.yml:/etc/alertmanager/alertmanager.yml -v /data/alertmanager/data:/alertmanager prom/alertmanager
模板语法是 golang 的 text/template, 需要一定的学习来掌握,可以使用 sprig 提供的各种工具简化模板编写。
prometheus自带的模板如果不习惯可以自定义模板,前提是得支持中文
/etc/prometheus-webhook-dingtalk/templates/default.tmpl
Go
语言的语法,复制即可**触发时间:** {{ .StartsAt.Format "2006-01-02 15:04:05" }}
我用的是容器默认的模板,不支持中文,效果还行,先把之前的模板cp出来在修改.
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p5sl3Myl-1633345453684)(images/image-20210818111020141.png)]
{{ define "__subject" }}[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .GroupLabels.SortedPairs.Values | join " " }} {{ if gt (len .CommonLabels) (len .GroupLabels) }}({{ with .CommonLabels.Remove .GroupLabels.Names }}{{ .Values | join " " }}{{ end }}){{ end }}{{ end }}
{{ define "__alertmanagerURL" }}{{ .ExternalURL }}/#/alerts?receiver={{ .Receiver }}{{ end }}
{{ define "__text_alert_list" }}{{ range . }}
**Labels**
{{ range .Labels.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}
**Annotations**
{{ range .Annotations.SortedPairs }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}
**Source:** [{{ .GeneratorURL }}]({{ .GeneratorURL }})
{{ end }}{{ end }}
{{ define "default.__text_alert_list" }}{{ range . }}
**告警主题:** {{ .Annotations.summary }}
**报警描述:** {{ .Annotations.description }}
**触发时间:** {{ dateInZone "2006.01.02 15:04:05" (.StartsAt) "Asia/Shanghai" }}
**告警展示:** []({{ .GeneratorURL }})
**详细列表:**
{{ range .Labels.SortedPairs }}{{ if and (ne (.Name) "severity") (ne (.Name) "summary") }}> - {{ .Name }}: {{ .Value | markdown | html }}
{{ end }}{{ end }}
{{ end }}{{ end }}
{{/* Default */}}
{{ define "default.title" }}{{ template "__subject" . }}{{ end }}
{{ define "default.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**
{{ if gt (len .Alerts.Firing) 0 -}}
![警报 图标](https://img1.baidu.com/it/u=506861484,357083329&fm=26&fmt=auto&gp=0.jpg)
**告警触发**
{{ template "default.__text_alert_list" .Alerts.Firing }}
{{- end }}
{{ if gt (len .Alerts.Resolved) 0 -}}
**告警恢复**
{{ template "default.__text_alert_list" .Alerts.Resolved }}
{{- end }}
{{- end }}
{{/* Legacy */}}
{{ define "legacy.title" }}{{ template "__subject" . }}{{ end }}
{{ define "legacy.content" }}#### \[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}\] **[{{ index .GroupLabels "alertname" }}]({{ template "__alertmanagerURL" . }})**
{{ template "__text_alert_list" .Alerts.Firing }}
{{- end }}
{{/* Following names for compatibility */}}
{{ define "ding.link.title" }}{{ template "default.title" . }}{{ end }}
{{ define "ding.link.content" }}{{ template "default.content" . }}{{ end }}
--web.external-url=http://yg.prometheus.com
,这只域名,告警消息就会匹配到Warning
的告警, CPU占用80%有一个Critical
的告警,当容器使用了85%的CPU,那么就会触发2条告警gorouting
- alert: Goroutines_High
expr: go_goroutines{job="prometheus"} > 100
for: 3m
labels:
status: Warning
annotations:
summary: "Instance {{$labels.instance}}: too much gorouting"
description: "{{$labels.instance}} of job {{ $labels.job }} gorouting is {{ $value }}"
- alert: Goroutines_High
expr: go_goroutines{job="prometheus"} > 200
for: 3m
labels:
status: Critical
annotations:
summary: "Instance {{$labels.instance}}: too much gorouting"
description: "{{$labels.instance}} of job {{ $labels.job }} gorouting is {{ $value }}"
latermanage.yml
配置inhibit_rules:
- source_match:
# ddaltername: 'Goroutines_High' # 可以加上,也可以不加,不加就匹配所有的
status: 'Critical'
target_match:
status: 'Warning'
equal: ['node', 'instance']
inhibit_rules:
- source_match:
status: 'Critical'
target_match:
status: 'Warning'
equal: ['node', 'instance', 'port', 'ssl', 'push']
- source_match:
target: 'Blackbox'
target_match:
target: 'Blackbox_Managed'
equal: ['port','ssl']
- source_match:
target: Cadvisor
target_match:
target: Cadvisor_Managed
equal: ['port','docker']
- source_match:
target: Node
target_match:
target: Node_Managed
equal: ['port','node']
比如要临时调整服务器,需要关闭服务器,那么自己肯定知道会在什么时候报警,为防止告警风暴,配置静默规则
prometheus告警的静默只需要打开AlertManager
Web界面,点击Silence
,再点击New Silence
按钮创建规则,不需要配置文件
__metrics_path__
默认为/metrics
__scheme__
默认为http
__param_*
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zDriQq9s-1633345453687)(images/image-20210819163234171.png)]
# 案例:覆盖标签内容
- job_name: docker
scheme: https
metrics_path: /moremetrics
static_configs:
- targets: ["192.168.0.232:9091"]
# 通过targets查看时,元属性就变成了: https://192.168.0.232:9091/moremetrics
relabel_configs
, 可以在target被抓取之前动态重写目标的标签集。每个scrape
可以配置多个relabel,对不同的标签进行不同的操作。relable的过程可以分为:relabel之前,relabel期间,relabel之后。relabel_configs不能操作指标中的标签,只能操作relabel之前的标签。即__
开头的和job
这些relabel之前,除了自定义的标签外,还有一些其他的标签job
,这个标签的值是配置文件中job_name
配置的值__address__
这个标签的值是要抓取的地址和端口 :
instance
这个标签,在relabel之前是没有的,如果relabel期间也没有设置instance
标签,默认情况下instance标签的值就是__address__
的内容__scheme__
: http或https__metrics_path__
: metrics的路径__param_
: http请求参数,
就是参数名replace
: 根据 regex 的配置匹配 source_labels 标签的值(注意:多个 source_label 的值会按照separator 进行拼接),并且将匹配到的值写入到 target_label 当中,如果有多个匹配组,则可以使用 ${1}, ${2}确定写入的内容。如果没匹配到任何内容则不对 target_label 进行重新, 默认为 replacekeep
: 丢弃 source_labels 的值中没有匹配到正则表达式内容的 Target 实例drop
: 丢弃 source_labels 的值中匹配到正则表达式内容的 Target 实例hashmod
: 将 target_label 设置为关联的 source_label 的哈希模块labelmap
: 根据 正则去匹配 Target 实例所有标签的名称(注意是名称),并且将捕获到的内容作为为新的标签名称, 正则匹配到标签的的值作为新标签的值,如果节点的标签少可以用这个来添加标签labeldrop
: 对 Target 标签进行过滤,会移除匹配过滤条件的所有标签labelkeep
: 对 Target 标签进行过滤,会移除不匹配过滤条件的所有标签# 案例
scrape_configs:
- job_name: pushgateway
static_configs:
- targets: ['192.168.0.212:10250']
relabel_configs:
- source_labels: [__address__]
regex: '(.*):10250'
replacement: '${1}:9100'
target_label: __address__
action: replace
# 最终192.168.0.212:10250变为192.168.0.212:9100
- job_name: 'nacos_cluster'
static_configs:
- targets: ["192.168.0.212:8848"]
labels:
service: "cluster" # 添加一个标签service为cluster的标签
altermanager
加入prometheus
中vim /data/prometheus/conf/prometheus.yml
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['192.168.0.212:9093']
rule_files:
- "prom/rules/*-rule.yml"
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ['localhost:9090']
- job_name: node
file_sd_configs:
- files:
- prom/targets/node-target.yaml
refresh_interval: 2m
- job_name: docker
file_sd_configs:
- files:
- prom/targets/docker-target.yaml
refresh_interval: 2m
- job_name: pushgateway
static_configs:
- targets: ['192.168.0.212:9091']
vim /data/prometheus/conf/server/node-rules.yml
groups:
- name: node
rules:
- alert: CPU_High
expr: (1 - (sum(increase(node_cpu_seconds_total{mode="idle"}[1m])) by (instance) / sum(increase(node_cpu_seconds_total[1m])) by (instance))) * 100 > 10
for: 3m
labels:
status: Critical
annotations:
summary: "Instance {{ $labels.instance }}: High CPU usage"
description: "{{ $labels.instance }} of job {{ $labels.job }} CPU usage is {{ $value }}"
- alert: Free_High
expr: 100 - (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes) / node_memory_MemTotal_bytes*100 > 80
for: 3m
labels:
status: Critical
annotations:
summary: "Instance {{ $labels.instance }}: High Free usage"
description: "{{ $labels.instance }} of job {{ $labels.job }} Free usage is {{ $value }}"
- alert: Partition_High
expr: 100 - node_filesystem_free_bytes{fstype=~"xfs|ext4"} / node_filesystem_size_bytes{fstype=~"xfs|ext4"} * 100 > 80
for: 3m
labels:
status: Critical
annotations:
summary: "Instance {{ $labels.instance }}: High Partition usage"
description: "{{ $labels.instance }} of job {{ $labels.job }} Partition usage is {{ $value }}"
- alert: Load_High
expr: node_load5 > on(instance) 2 * count(node_cpu_seconds_total{mode="idle"}) by (instance)
for: 3m
labels:
status: Critical
annotations:
summary: "Instance {{ $labels.instance }}: High Load usage"
description: "{{ $labels.instance }} of job {{ $labels.job }} Load is {{ $value }} "
- alert: Server_Down
expr: up == 0
for: 1s
labels:
status: Disaster
annotations:
summary: "{{$labels.instance}}: Server is Down"
description: "{{$labels.instance}} of job {{ $labels.job }} Server is Down"
KEY | 说明 |
---|---|
name | 警报规则组的名称 |
alert | 警报规则的名称 |
expr | PromQL表达式 |
lable_name | 自定义标签,允许自行定义标签附加在警报上,比如high, warning |
annotations | 用来设置有关警报的一组描述信息,其中包括自定义的标签,以及expr计算后的值 |
for | 在第一次遇到新的表达式输出向量元素,和将此警告作为此元素的触发计数之间等待一段时间,在这种情况下,Prometheus将在每次评估期间检查警报是否继续处于活动状态时间,然后再触发警报。 处于活动状态但尚未触发的元素处于pending状态。 |
labels | 允许指定要附加到警报的一组附加标签。 任何现有的冲突标签都将被覆盖。 标签值可以是模板化的。 |
ecording rules
是提前设置好一个比较花费大量时间运算或经常运算的表达式,其结果保存成一组新的时间序列数据。当需要查询的时候直接会返回已经计算好的结果,这样会比直接查询快,同时也减轻了PromQl的计算压力,同时对可视化查询的时候也很有用,可视化展示每次只需要刷新重复查询相同的表达式即可record
需要注意,其他的基本上是一样的,一个 groups
下可以包含多条规则 rules
,Recording
和 Rules
保存在 group
内,Group
中的规则以规则的配置时间间隔顺序运算,也就是全局中的 evaluation_interval
设置# 这个配置的规则其实就是根据 record 规则中的定义,Prometheus 会在后台完成 expr 中定义的 PromQL 表达式周期性运算,以 job 为维度使用 sum 聚合运算符 计算 函数rate 对http_requests_total 指标区间 10m 内的增长率,并且将计算结果保存到新的时间序列 job:http_requests_total:rate10m 中,同时还可以通过 labels 为样本数据添加额外的自定义标签,但是要注意的是这个 Lables 一定存在当前表达式 Metrics 中
groups:
- name: http_requests_total
rules:
- record: job:http_requests_total:rate10m
expr: sum by (job)(rate(http_requests_total[10m]))
lables:
team: operations
- record: job:http_requests_total:rate30m
expr: sum by (job)(rate(http_requests_total[30m]))
lables:
team: operations
{{ $lable.node}} # 可以获取当前警报实例中的标签是node的实例
{{ $value }} # 变量可以获取当前PromQL表达式的计算样本值
FIRING就是altermanager已经触发了告警.# 后面还有很多需要改prometheus配置文件的,为了不一直重启,启动prometheus用热加载配置文件的方式
# 启动时加上--web.enable-lifecycle启用远程热加载配置文件,调用指令是curl -X POST http://localhost:9090/-/reload
docker run -d --restart=always --name prometheus -p 9090:9090 -v /data/prometheus/conf/prometheus.yml:/etc/prometheus/prometheus.yml -v /data/prometheus/conf/prom:/etc/prometheus/prom -v /data/prometheus/data:/prometheus prom/prometheus --config.file=/etc/prometheus/prometheus.yml --storage.tsdb.path=/prometheus --web.console.libraries=/usr/share/prometheus/console_libraries --web.console.templates=/usr/share/prometheus/consoles --web.external-url=http://124.71.81.11:9090
分位数
# HELP prometheus_tsdb_wal_fsync_duration_seconds Duration of WAL fsync.
# TYPE prometheus_tsdb_wal_fsync_duration_seconds summary
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.5"} 0.012352463
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.9"} 0.014458005
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.99"} 0.017316173
prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
prometheus_tsdb_wal_fsync_duration_seconds_count 216
# 从上面的样本中可以得知当前Prometheus Server进行wal_fsync操作的总次数为216次,耗时2.888716127000002s,其中中位数(quantile=0.5)的耗时为0.012352463,9分位数(quantile=0.9)的耗时为0.014458005s。
prometheus查询语句叫做表达式,运用大量数学运算,简单的四则运算,难的微积分,代数,求导等
任何表达式或者子表达式都可以归为四种类型:
instant vector
瞬时向量 , 一组时间序列,包含每个时间序列的单个样本,所有时间序列都共享相同的时间戳range vector
范围向量,一组时间序列,包含每个时间序列随时间变化的一系列数据点scalar
标量,一个简单的浮点值string
字符串, 一个当前没有被使用的简单字符串+
(加)-
(减)*
(乘)/
(除)%
(取余)^
(乘方)==
(等于)!=
(不等于)>
(大于)<
(小于)>=
(大于等于)<=
(小于等于)and
(交集)or
(并集)unless
(补集)sum
:(计算总和)min
:(选择最小值)max
:(选择最大值)avg
:(计算平均值)stddev
:(计算总体标准偏差)stdvar
:(计算总体标准方差)count
:(计算向量中元素的数量)count_values
:(计算具有相同值的元素的数量)bottomk
:(k个最小的采样值)topk
:(k个最大的采样值)quantile
:计算 φ-quantile (0 ≤ φ ≤ 1)without
: 用于从计算结果中移除匹配到的的标签
offset
: 偏移量,查询当前时间点之前的数据
offset 5m
by
: 只显示匹配到的标签
by (name)
参考
PromQL
// 这样就截取了CPU总使用时间在1分钟内的增量
increase(node_cpu[1m])
使用频率很频繁,求和的意思
例如
// 所有节点1分钟CPU增量的和
sum(increase(node_cpu[1m]))
生产上肯定是多台服务器的监控,如果用sum就会把所有的服务器的CPU值全部加到一起,就变成服务器集群总CPU平均值了.这样的监控毫无意义,于是就引出了by (instance)
注意by后面有个空格,这个函数可以把sum加合到一起的数数值,按照指定的一个方式进行一层的拆分,instance代表的是机器名.
// 每台服务器的1分钟空闲CPU的增量的和
sum(increase(node_cpu{mode="idle"}[1m])) by (instance)
// 每台服务用户态CPU的使用时间
sum(increase(node_cpu{mode="user"}[1m])) by (instance)
// 内核态
sum(increase(node_cpu{mode="system"}[1m])) by (instance)
// io等待
sum(increase(node_cpu{mode="iowait"}[1m])) by (instance)
// 每台服务器1分钟CPU增量的和
sum(increase(node_cpu[1m])) by (instance)
// 有了上面2个值,那么就可以进行计算了,空闲的除以使用的.就得到空闲的百分比了
sum(increase(node_cpu{mode="idle"}[1m])) by (instance) / sum(increase(node_cpu[1m])) by (instance)
// 要得到CPU使用的百分比
(1 - (sum(increase(node_cpu{mode="idle"}[1m])) by (instance) / sum(increase(node_cpu[1m])) by (instance))) * 100
irate()
类似// rate()函数经常用到的是采集1s钟的数据,比如流量,CPU,free,IO等.这种rate()好用,几分钟采集一次的increase()比较好用.
rate(node_network_receive)bytes[1m])
// 比如rate(1m)取流量,1分钟内增加的量除以秒数,就是1秒钟的增量和rate(5m)取流量,5分钟内增加的量除以秒数,就是1秒钟的增量,比如都是每秒钟16的增量,但是出图却不一样,这是什么原因呢
// rate()和increase()区别是rate会除以秒数,而increase取的是增量.他们两个的用法比较相似.
rate(node_network_receive)bytes[1m])
increase(node_network_receive)bytes[1m])
// 比如count_netstat_wait_connections取出来有几十个数据,前面加个3就表示取前3个的数据.
topk(3,count_netstat_wait_connections)
// 出当前(或者历史)TCP 等待数大于200的机器数量
count(count_netstat_wait_connections > 200)
float
转为int
# 得到百分比一般都会有小数点很多位数,利用这个函数可以得到整数
floor(sum(container_memory_rss{image!=""}) by(name, instance) / sum(container_spec_memory_limit_bytes{image!=""}) by(name, instance) * 100 != +inf) > 80
# 内存使用率
100 - (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes) / node_memory_MemTotal_bytes*100 > 80
# 这个也是内存使用
(1 - (node_memory_MemAvailable_bytes{job="node"} / (node_memory_MemTotal_bytes{job=~"node"})))* 100 > 80
# 分区使用率
max(100 - (node_filesystem_free_bytes{fstype=~"xfs|ext4"} / node_filesystem_size_bytes{fstype=~"xfs|ext4"} * 100)) by(instance,mountpoint) > 80
# CPU使用率
(1 - (sum(increase(node_cpu_seconds_total{mode="idle"}[1m])) by (instance) / sum(increase(node_cpu_seconds_total[1m])) by (instance))) * 100 > 80
# 分区使用率
max((node_filesystem_size_bytes{job="node",fstype=~"ext.?|xfs"} - node_filesystem_free_bytes{job="node",fstype=~"ext.?|xfs"}) * 100 / (node_filesystem_avail_bytes {job="node",fstype=~"ext.?|xfs"} + (node_filesystem_size_bytes{job="node",fstype=~"ext.?|xfs"} - node_filesystem_free_bytes{job="node",fstype=~"ext.?|xfs"}))) by(instance,mountpoint) > 80
# 服务器down机
up == 0
# 前5分钟的负载大于CPU核心数的2倍,说明负载高了
node_load5 > on(instance) 2 * count(node_cpu_seconds_total{mode="idle"}) by (instance)
# 出当前(或者历史)TCP 5分钟内等待数大于200的机器数量
count(count_netstat_wait_connections[5m] < 200)
# prometheus的http请求数不是200和302的,5分钟前的值,offset表示前移多少时间
sum(prometheus_http_requests_total{code!~"200|302"} offset 5m)
# eth0网卡在范围向量为1小时的范围每秒收到(下载)的流量是多少kb
sum(rate(node_network_receive_bytes_total{device="eth0"}[60m])) / 1024
# 选中的节点eth0网卡在范围向量为1小时的范围每秒发送(上传)的流量是多少kb,可以自己扩展
sum(rate(node_network_transmit_bytes_total{device="eth0"}[60m])) / 1024
# 显示每个节点一小时下载的流量是多少M
increase(node_network_receive_bytes_total[60m]) / 1024^2
# 显示每个节点的已经建立的TCP连接,可以在服务器上输入看netstat |grep -i 'estab'
node_netstat_Tcp_CurrEstab{job="node"}
# TCP连接的TIMEWAIT,这个阈值根据自己设置可以看内核文件,TCP状态基本和这些类似
node_sockstat_TCP_tw > 4900
# 已使用的文件打开数大于50000的,ulimit -n可以看到设定的值
node_filefd_allocated > 50000
# prometheus查询相应时间,这里使用的quantile,也叫分位数,利用的是prometheus的histogram_quantile函数
prometheus_engine_query_duration_seconds
prometheus_engine_query_duration_seconds{quantile="0.5",slice="queue_time"} > 2
prometheus_engine_query_duration_seconds{quantile="0.9",slice="queue_time"}
prometheus_engine_query_duration_seconds{quantile="0.99",slice="queue_time"}
# prometheus请求延时时间,单位秒
histogram_quantile(0.5, sum(rate(prometheus_http_request_duration_seconds_bucket[5m])) by (le, handler)) > 2
# 0.9分位数(prometheus只取0到1,所以是百分之90的查询时间,单位是秒),prometheus内部测评查询时间(监控是否是慢查询),同样0.5, 0.99是一样的
sum(prometheus_engine_query_duration_seconds{quantile="0.9",slice="inner_eval"}) by (job,instance) > 1
# 容器cpu使用超过80%
sum(rate(container_cpu_usage_seconds_total{image!=""}[1m])) by (name,instance) / (sum(container_spec_cpu_period{image!=""} / 100000) by (name,instance)) * 100 > 80
# 容器内存使用超过80%,在监控内存前一定要给容器设置内存limit,为了得到使用的百分比,k8s也同样适用,docker热设置limit命令: docker update -m 1024M ${container_name}
sum(container_memory_rss{image!=""}) by(name, instance) / sum(container_spec_memory_limit_bytes{image!=""}) by(name, instance) * 100 != +inf > 80
# 容器文件使用量,阈值界定不好搞
sum(container_fs_usage_bytes{image!=""}) by(name, instance) / 1024^2
# 10分钟jvm加载的类数量
sum(rate(jvm_classes_loaded_total[10m])) by (instance)
# 死锁的线程数量,新建的线程:NEW,等待的线程:WAITING等都是一样的
sum(jvm_threads_state{state="BLOCKED"}) by (instance)
# 这个也是死锁的线程数量,gauages类型
max(jvm_threads_deadlocked) by (instance)
# 内存池Code Cache(代码缓存区)使用多少M,其他的也是一样的
sum(jvm_memory_pool_bytes_used{pool="Code Cache"}) by (instance, pool) / 1024^2
# 内存池Compressed Class Space(指针指向的空间)使用
sum(jvm_memory_pool_bytes_used{pool="Compressed Class Space"}) by (instance, pool) / 1024^2
# Metaspace,元空间
sum(jvm_memory_pool_bytes_used{pool="Metaspace"}) by (instance, pool) / 1024^2
# PS Eden Space(新生代,对象被创建的时候首先放到这个区域)
sum(jvm_memory_pool_bytes_used{pool="PS Eden Space"}) by (instance, pool) / 1024^2
# PS Old Gen(老年代,存放新生代中经过多次垃圾回收仍然存活的对象)
sum(jvm_memory_pool_bytes_used{pool="PS Old Gen"}) by (instance, pool) / 1024^2
# PS Survivor Space(幸存者区,不能被回收的对象存放的位置)
sum(jvm_memory_pool_bytes_used{pool="PS Survivor Space"}) by (instance, pool) / 1024^2
# 1m的GC消耗的时间
sum(rate(jvm_gc_collection_seconds_count{gc="PS Scavenge"}[1m])) by (instance, gc)
# 1m标记的时间
sum(rate(jvm_gc_collection_seconds_count{gc="PS MarkSweep"}[1m])) by (instance, gc)
# 给定的jvm内存,gauages类型,
jvm_memory_pool_bytes_max
# 上一次GC内存池的大小
jvm_memory_pool_collection_committed_bytes / 1024 ^ 2
# JVM内存池最后一次垃圾回收使用的字节数
jvm_memory_pool_collection_used_bytes / 1024 ^ 2
# 10分钟卸载的类数量
rate(jvm_classes_unloaded_total[10m])
docker run --restart=always \
-v /:/rootfs:ro -v /var/run:/var/run:rw \
-v /sys:/sys:ro \
-v /var/lib/docker/:/var/lib/docker:ro \
-v /dev/disk/:/dev/disk:ro \
-p 7890:8080 -d \
--name=cadvisor \
google/cadvisor:latest
# 创建并编写docker的rule
vim /data/prometheus/conf/docker-rule.yml
groups:
- name: docker
rules:
- alert: Container_CPU_High
expr: sum(rate(container_cpu_usage_seconds_total{image!=""}[1m])) by (name) / (sum(container_spec_cpu_period{image!=""} / 100000) by (name)) * 100 > 80
for: 5m
labels:
status: Critical
annotations:
summary: "Container {{ $labels.name }} In {{ $labels.instance }}: High CPU usage"
description: "Container {{ $labels.name }} In {{ $labels.instance }} of job {{ $labels.job }} CPU usage is {{ $value }}"
- alert: Container_Free_High
expr: sum(container_memory_rss{image!=""}) by(name) / sum(container_spec_memory_limit_bytes{image!=""}) by(name) * 100 != +inf > 80
for: 5m
labels:
status: Critical
annotations:
summary: "Container {{ $labels.name }} In {{ $labels.instance }}: High Free usage"
description: "Container {{ $labels.name }} In {{ $labels.instance }} of job {{ $labels.job }} Free usage is {{ $value }}"
指标 | 说明 | 单位 |
---|---|---|
container_memory_max_usage_bytes | 容器中最大使用的内存的记录 | bytes |
container_memory_usage_bytes | 容器中当前是用的内存 | bytes |
container_spec_cpu_period | cpu的配额,相当于cpu的limit | CPU个数 * 100000 = cpu配额 |
container_cpu_usage_seconds_total | 容器当前使用的cpu | bytes |
container_memory_rss | RSS内存,常驻内存集.分配给进程使用实际物理内存 | bytes |
container_spec_memory_limit_bytes | 设置的内存的limit | bytes |
pushgateway
来实现自定义监控
pushgateway
插件来# docker安装,pushgateway随便在哪里构建都可以,也可以做集群化
docker run --restart=always --name pushgateway -d -p 9091:9091 prom/pushgateway
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MkC3ZVbw-1633345453690)(images/image-20210816145335773.png)]
echo 'ech 404' | curl --data-binary @- http://124.71.81.11:9091/metrics/job/pushgateway/ip/192.168.0.212
--data-binary @-
: 意思为携带二进制数据发送POST请求,pushgateway只支持POSTpushgateway
的URL: http://124.71.81.11:9091/metrics/job
和ip
是自己设置,相当于给这条自定义的数据标签,方便PromQL查询到
job
对应是pushgateway
ip
对应的是192.168.0.212
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zve77Isf-1633345453691)(images/image-20210816151948529.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VvjQPwQz-1633345453692)(images/image-20210816151836388.png)]
curl
,过程略# shell脚本结合crontab定时执行给pushgateway数据即可
echo 'ech 404' | curl --data-binary @- http://124.71.81.11:9091/metrics/job/pushgateway/ip/192.168.0.212
pip3 install flask
pip3 install prometheus_client
pip3 install requests
import requests
import prometheus_client
from prometheus_client import Counter
from prometheus_client.core import CollectorRegistry
from flask import Response, Flask
blackbox exporter
利用端口探测是方式实现监控服务端口SSL
证书过期时间监测# 编写blackbox_exporter配置文件,固定格式,直接复制就可以
vim /data/blackbox_exporter/blackbox.yml
modules:
http_2xx:
prober: http
http_post_2xx:
prober: http
http:
method: POST
tcp_connect:
prober: tcp
pop3s_banner:
prober: tcp
tcp:
query_response:
- expect: "^+OK"
tls: true
tls_config:
insecure_skip_verify: false
ssh_banner:
prober: tcp
tcp:
query_response:
- expect: "^SSH-2.0-"
irc_banner:
prober: tcp
tcp:
query_response:
- send: "NICK prober"
- send: "USER prober prober prober :prober"
- expect: "PING :([^ ]+)"
send: "PONG ${1}"
- expect: "^:[^ ]+ 001"
icmp:
prober: icmp
blackbox_exporter
# 随便找台服务器启动都可以,只要网络是通的
docker run --restart=always -d -p 9115:9115 --name blackbox_exporter -v /data/blackbox_exporter/blackbox.yml:/config/blackbox.yml prom/blackbox-exporter --config.file=/config/blackbox.yml
# prometheus.yml增加监控port的job,监控业务端口是否正常
- job_name: 'port_status'
scrape_interval: 30s
metrics_path: /probe
params:
module: [tcp_connect]
file_sd_configs:
- files:
- prom/targets/port-target.yaml
refresh_interval: 2m
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 192.168.0.212:9115 # blackbox_exporter所在的位置
# 看192.168.0.212:3000的端口是否正常,我们curl一下,最后一行的probe_success显示为1就表示正常,0就与之相反,有些我看也有是0,个人觉得不准确
curl http://192.168.0.212:9115/probe?target=192.168.0.212:3000&module=tcp_connect&debug=true
blackbox_exporter
的Logs
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0ijfHjTS-1633345453692)(images/image-20210820135521485.png)]
# 监控端口
probe_success{job="port_status"} == 0
- job_name: 'ssl'
metrics_path: /probe
params:
module: [http_2xx]
file_sd_configs:
- files:
- prom/targets/ssl-target.yaml
refresh_interval: 2m
relabel_configs:
- source_labels: [__address__]
target_label: __param_target
- source_labels: [__param_target]
target_label: instance
- target_label: __address__
replacement: 192.168.0.212:9115
# 小于30天的证书告警
floor((probe_ssl_earliest_cert_expiry - time()) / 86400 < 30)
grafana
直接出图是不对的,显示会有问题,因为不管是端口列表或者域名列表,他们的标签都是一样的,没法区分,自己写promQL出图job_name
定义,如果节点发生变化,比如新增节点,那我们就不得不编辑prometheus.yml
配置文件, 适用静态的static_configs
去管理节点,并重载prometheus
配置才能完成,这些都需要手动去进行,很显然,会疲于奔命, 特别是容器环境中,根本就没法适用.Service Discovery
,其实就是prometheus的注册中心,简称**:SD**, 不需要用户静态的配置static_configs
Consu
l, Eureka
, Zookeepe
r,Serverset
或Airbnb Nerve
等,同时Prometheus也可以很好的集成到目前主流的Kubernetes容器编排平台上,通过其API Server动态发现各类被监控的对象,如Pod、Server、Endpoint、Ingress和Node对象,同时Prometheus基于DNS或者文件的动态发现机制# 先创建一个yaml,里面有2组列表
vim prom_port_sd.yaml
- targets:
- 192.168.0.31:6378
- 192.168.0.31:5672
- 192.168.0.31:15672
- 192.168.0.31:9093
- 192.168.0.31:9092
- 192.168.0.31:28017
- 192.168.0.31:9201
- 192.168.0.31:5602
- 192.168.0.31:2181
- 192.168.0.31:2182
labels:
app: prometheus
job: prometheus
- targets:
- node1.cce.com:9100
- node2.cce.com:9100
labels:
app: node-expoter
job: node
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- target:
rule_files:
- "prom/rules/*-rule.yml"
scrape_configs:
- job_name: 'prometheus'
file_sd_configs: # 服务发现动态感知target的关键字
- files:
- targets/prom*.yaml # 指定要加载的文件列表,支持通配符
refresh_interval: 2m # 每隔2分钟重新加载一次文件中定义的Target,默认为5m
prometheus
虽然不支持集群,但还是难不倒苦逼运维,上面所做的一切都是针对小微环境构建的,我们最终通过consul
做SD,高可用prometheus实现中大型企业级监控prometheus
采集的数据默认只保存15天,如果要对监控的数据做分析,需要持久化prometheus
集群架构图[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nmwee7D2-1633345453693)(images/image-20210820162605311.png)]
docker pull consul
docker run --restart=always --name consul -d -p 8500:8500 consul
# 然后浏览器访问${IP}:${PORT}
# 测试注册,修改为自己的IP和Port
curl -X PUT -d '{"id": "node-exporter","name": "node-exporter","address": "192.168.0.212","port": 9100,"tags": ["test"],"checks": [{"http": "http://192.168.0.212:9100/metrics", "interval": "5s"}]}' http://192.168.0.212:8500/v1/agent/service/register
# 删除已经注册的信息
curl -X PUT http://192.168.0.212:8500/v1/agent/service/deregister/node-exporter
- job_name: 'consul-prometheus'
consul_sd_configs:
- server: '192.168.0.212:8500'
services: []
relabel_configs
来解决一些标签等的问题exporter
注册到consul
上去Prometheus
主机监控同样的目标,然后有告警出现,也会发送同样的告警给Alertmanager
,然后使用Alertmanager
自身的去重告警功能,只发出一条告警出来,然后用keepalived
做双机热备
alertmanager
0.15.2以上才能实现集群, 多个Altermanager
组成gossip
集群# 启动altermanager加2个参数就可以配置集群,具体可以--help
# 你altermanager的ip和端口
--cluster.listen-address=""
# 集群中有哪些altermanager,自己的也要写上
--cluster.peer=CLUSTER.PEER
# 比如gossip集群的IP各自为192.168.0.2:9094,192.168.0.3:9094,192.168.0.4:9094,
# alter1 启动配置为--cluster.listen-address=192.168.0.2:9094 --cluster.peer=192.168.0.2:9094 --cluster.peer=192.168.0.3:9094 --cluster.peer=192.168.0.4:9094,alter2只需要改--cluster.listen-address
# 同时prometheus配置文件中需要都添加上
prometheus不支持集群的配置,但是支持Federation
也叫联邦,允许Prometheus服务器从另一个Prometheus服务器抓取选定的时间序列,联邦有不同的用例。通常,它用于实现可扩展的 Prometheus 监控设置或将相关指标从一个服务的 Prometheus 提取到另一个服务中
小集群用联邦是没问题的,如果集群过大,联邦就会造成Top Prometheus
的压力过大,因为所有的数据都汇集到Top Prometheus
中
Thanos
使用灭霸做prometheus的高可用,Thanos
is a CNCF Incubating project, Thanos是一系列组件
Thanos是一款开源的Prometheus 高可用解决方案,其支持从多个Prometheus中查询数据并进行汇总和去重,并支持将Prometheus本地数据传送到云上对象存储进行长期存储
去掉了top Prometheus
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-czTznKah-1633345453695)(images/
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CeFSYjWA-1633345453696)(images/image-20210909155728667.png)]
参考
wget https://repo1.maven.org/maven2/io/prometheus/jmx/jmx_prometheus_javaagent/0.16.1/jmx_prometheus_javaagent-0.16.1.jar
Name | Description |
---|---|
startDelaySeconds | 在服务请求之前开始延迟。延迟期内的任何请求都将导致指标集为空。 |
hostPort | 要通过远程 JMX 连接的主机和端口。如果既未指定 this 也未指定 jmxUrl,则将与本地 JVM 对话。 |
username | 用于远程 JMX 密码认证的用户名。 |
password | 用于远程 JMX 密码认证的密码。 |
jmxUrl | 要连接到的完整 JMX URL。如果是 hostPort,则不应指定 |
ssl | JMX 连接是否应该通过 SSL 完成。要配置证书,您必须设置以下系统属性:-Djavax.net.ssl.keyStore=/home/user/.keystore -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.trustStore=/home/user/.truststore -Djavax.net.ssl.trustStorePassword=changeit |
lowercaseOutputName | 小写输出指标名称。适用于默认格式和name . 默认为假。 |
lowercaseOutputLabelNames | 小写输出指标标签名称。适用于默认格式和labels . 默认为假。 |
whitelistObjectNames | 要查询的ObjectName列表。默认为所有 mBean。 |
blacklistObjectNames | 不查询的ObjectName列表。优先于whitelistObjectNames 。默认为无。 |
rules | 要按顺序应用的规则列表,处理在第一个匹配规则处停止。不收集不匹配的属性。如果未指定,则默认以默认格式收集所有内容。 |
pattern | 匹配每个 bean 属性的正则表达式模式。 该模式未锚定。 捕获组可用于其他选项。 默认匹配所有内容。 |
attrNameSnakeCase | 将属性名称转换为蛇形大小写。这可以从与模式和默认格式匹配的名称中看出。例如,anAttrName 到 an_attr_name。默认为假。 |
name | The metric name to set. Capture groups from the pattern can be used. If not specified, the default format will be used. If it evaluates to empty, processing of this attribute stops with no output. |
value | Value for the metric. Static values and capture groups from the pattern can be used. If not specified the scraped mBean value will be used. |
valueFactor | Optional number that value (or the scraped mBean value if value is not specified) is multiplied by, mainly used to convert mBean values from milliseconds to seconds. |
labels | A map of label name to label value pairs. Capture groups from pattern can be used in each. name must be set to use this. Empty names and values are ignored. If not specified and the default format is not being used, no labels are set. |
help | Help text for the metric. Capture groups from pattern can be used. name must be set to use this. Defaults to the mBean attribute description and the full name of the attribute. |
cache | Whether to cache bean name expressions to rule computation (match and mismatch). Not recommended for rules matching on bean value, as only the value from the first scrape will be cached and re-used. This can increase performance when collecting a lot of mbeans. Defaults to false . |
type | The type of the metric, can be GAUGE , COUNTER or UNTYPED . name must be set to use this. Defaults to UNTYPED . |
vim prometheus-jmx-config.yaml
---
lowercaseOutputLabelNames: true
lowercaseOutputName: true
whitelistObjectNames: ["java.lang:type=OperatingSystem"]
rules:
- pattern: 'java.lang<>((?!process_cpu_time)\w+):'
name: os_$1
type: GAUGE
attrNameSnakeCase: true
/data/prometheus/package
目录是放prometheus-jmx-config.yaml
和jmx_prometheus_javaagent-0.16.1.jar
的docker run -d \
--name tomcat-1 \
-v /data/prometheus/package:/jmx-exporter \
-e CATALINA_OPTS="-Xms64m -Xmx128m -javaagent:/jmx-exporter/jmx_prometheus_javaagent-0.16.1.jar=6060:/jmx-exporter/prometheus-jmx-config.yaml" \
-p 6060:6060 \
-p 8080:8080 \
tomcat:8.5-alpine
vim prometheus-jmx-config.yaml
---
lowercaseOutputLabelNames: true
lowercaseOutputName: true
whitelistObjectNames: ["java.lang:type=OperatingSystem"]
rules:
- pattern: 'java.lang<>((?!process_cpu_time)\w+):'
name: os_$1
type: GAUGE
attrNameSnakeCase: true
/data/prometheus/package
目录是放prometheus-jmx-config.yaml
和jmx_prometheus_javaagent-0.16.1.jar
的docker run -d \
--name tomcat-1 \
-v /data/prometheus/package:/jmx-exporter \
-e CATALINA_OPTS="-Xms64m -Xmx128m -javaagent:/jmx-exporter/jmx_prometheus_javaagent-0.16.1.jar=6060:/jmx-exporter/prometheus-jmx-config.yaml" \
-p 6060:6060 \
-p 8080:8080 \
tomcat:8.5-alpine