CPU
、内存和磁盘,但不监控可以指示主机上应用程序是否正常运行的关键服务HTTP
200状态码可以监控Web
应用程序是否正常运行,它会告诉你应用程序正在响应请求,但并不会反映出是否返回了正确的数据CPU
使用率超过80%就发出警报。这种检查通常是不灵活的布尔逻辑或者一段时间内的静态阈值,它们通常会匹配特定的结果或范围,这种模式没有考虑到大多数复杂系统的动态性。阈值的匹配或许很重要,但它可能由异常事件触发,甚至可能是自然增长的结果checklist
)的所有事情都是监控的某种形式Prometheus
主要是一个基于拉取的系统,但它也支持接收推送到网关的事件Prometheus
改变了“指标作为补充”的观念,指标变成了监控工作流程中最重要的部分。Prometheus
颠覆了以故障检测为中心的模型,指标用来反映环境的状态、可用性以及性能observation
),观察点通常包括值、时间戳,有时也涵盖描述观察点的一系列属性(如源或标签)。观察的集合称为时间序列gauge
),这种类型是上下增减的数字,本质上是特定度量的快照counter
),这种类型是随着时间增加而不会减少的数字histogram
)是对观察点进行采样的指标类型,可以展现数据集的频率分布。将数据分组在一起并以这样的方式显示,这个被称为“分箱”(binning
)的过程可以直观地查看数值的相对大小sigma
符号表示,例如,1 sigma
表示与平均值有一个标准差sigma
法则(如图1-13所示)。法则指出,一个标准差或1到–1代表平均值两边68.27%的数据,两个标准差或2到–2代表95.45%,而三个标准差则代表99.73%Brendan Gregg
的USE
(Utilization
、Saturation
和Error
)方法[1],侧重于主机级监控resource: all physical server functional components (CPUs, disks, busses, ...
)utilization: the average time that the resource was busy servicing work
saturation: the degree to which the resource has extra work which it can
't service, often queued
errors: the count of error events
1.5.1 USE方法CPU
开始USE
是使用率(Utilization
)、饱和度(Saturation
)和错误(Error
)的缩写,该方法是由Netflix
的内核和性能工程师Brendan Gregg
开发的。USE
方法建议创建服务器分析清单,以便快速识别问题USE
方法可以概括为:针对每个资源,检查使用率、饱和度和错误。该方法对于监控那些受高使用率或饱和度的性能问题影响的资源来说是最有效的Google
的四个黄金指标,专注于应用程序级监控Gregg
对模型的定义中,它是一个传统意义上的物理服务器组件,如CPU
、磁盘等,但许多人也将软件资源包含在定义中CPU
使用率随时间的百分比CPU
饱和度,等待CPU
的进程数CPU
资源不太有影响swap
测量http://www.brendangregg.com/USEmethod/use-linux.html
1.5.2 Google的四个黄金指标
Weaveworks
团队开发了一个名为RED
(Rate
、Error
和Duration
)的相关框架,你可能也会对此感兴趣(https://rancher.com/red-method-for-prometheus-3-key-metrics-for-monitoring
/)Google
的四个黄金指标来自Google SRE
手册,它们采用与USE
类似的方法,指定要监控的一系列通用指标类型HTTP
请求数,或者数据库系统的事务HTTP
500错误等显式失败,要么是返回错误内容或无效内容等隐式失败,或者基于策略原因导致的失败——例如,强制要求响应时间超过30ms
的请求视为错误IO
。这还包括即将饱和的部分,例如正在快速填充的磁盘Prometheus
来实例化这些监控方法。在本书的最后,你应该可以搭建出一个高度可扩展的监控平台The Packer Book
》The Terraform Book
》The Art of Monitoring
》The Docker Book
》The Logstash Book
》The Art of Monitoring
》Pro Puppet
》Pulling Strings with Puppet
》Pro Linux System Administration
》Pro Nagios
2.0》Hardening Linux
》The Visual Display of Quantitative Information
》https://www.datadoghq.com/blog/timeseries-metric-graphs
-101/https://github.com/turnbullpress/prometheusbook-code
Prometheus
的灵感来自谷歌的Borgmon
。它最初由前谷歌SRE Matt T.Proud
开发,并转为一个研究项目。在Proud
加入SoundCloud
之后,他与另一位工程师Julius Volz
合作开发了Prometheus
。后来其他开发人员陆续加入了这个项目,并在SoundCloud
内部继续开发,最终于2015年1月将其发布Facebook
发现85%的查询是针对26小时内的数据Prometheus
通过抓取或拉取应用程序中暴露的时间序列数据来工作。时间序列数据通常由应用程序本身通过客户端库或称为exporter
(导出器)的代理来作为HTTP
端点暴露Prometheus
还有一个推送网关(push gateway
)[3],可用于接收少量数据——例如,来自无法拉取的目标数据(如临时作业或者防火墙后面的目标)Prometheus
架构(图)https://github.com/Lusitaniae/apache_exporter
https://github.com/prometheus/mysqld_exporter
https://github.com/prometheus/pushgateway
2.2.1 指标收集
2.2.2 服务发现
2.2.3 聚合和警报
2.2.4 查询数据
2.2.5 自治
2.2.6 冗余和高可用性
2.2.7 可视化
2.3 Prometheus数据模型 2.3.1 指标名称 2.3.2 标签 2.3.3 采样数据 2.3.4 符号表示 2.3.5 保留时间
2.4 安全模型
2.5 Prometheus生态系统 链接
2.6 参考链接
https://prometheus.io
/https://prometheus.io/docs
/GitHub
主页:https://github.com/prometheus
GitHub
源码:https://github.com/prometheus/prometheus
Prometheus
和时间序列设计(https://www.youtube.com/watch?v=gNmWzkGViAY
)Grafana
官网:https://grafana.com
https://prometheus.io/docs/instrumenting/exporters
/https://prometheus.io/docs/instrumenting/clientlibs
/。(Prometheus
客户端库)Prometheus
服务器,此外还有Alertmanager
,它为Prometheus
提供警报引擎并进行管理Prometheus
项目还包括一系列exporter<sup>[1]</sup>
,用于监控应用程序和服务,并在端点上公开相关指标以进行抓取。核心exporter
支持常见工具,如Web
服务器、数据库等。许多其他exporter
都是开源的,你可以从Prometheus
社区查看Prometheus
2.0开始,默认情况下某些HTTP API
的管理功能被禁用Prometheus
可以通过多种方式进行配置和部署,关于安全有以下两个假设Prometheus
专为短期监控和警报需求而设计。默认情况下,它在其数据库中保留15天的时间序列数据。如果要保留更长时间的数据,则建议将所需数据发送到远程的第三方平台notation
)instance
标签(标识源主机或应用程序)以及一个job
标签(包含抓取特定时间序列的作业名称)sample
)的结果__name
__的标签)Prometheus
内部使用Prometheus
数据模型提供了维度website_visits_total
为网站访问的总数Prometheus
收集时间序列数据。为了处理这些数据,它使用一个多维时间序列数据模型。这个时间序列数据模型结合了时间序列名称和称为标签(label
)的键/值对,这些标签提供了维度。每个时间序列由时间序列名称和标签的组合唯一标识Grafana
集成。此外,Prometheus
也支持其他仪表板Prometheus
团队建议将Prometheus
服务器部署到特定环境和团队,而不是仅部署一个单体Prometheus
服务器Prometheus
冗余架构(图)Prometheus
服务器都设计为尽可能自治,旨在支持扩展到数千台主机的数百万个时间序列的规模。数据存储格式被设计为尽可能降低磁盘的使用率,并在查询和聚合期间快速检索时间序列Prometheus
服务器还提供了一套内置查询语言PromQL
、一个表达式浏览器(如图2-2所示)以及一个用于浏览服务器上数据的图形界面Prometheus
表达式浏览器(图)Prometheus
还可以定义警报规则。这些是为系统配置的在满足条件时触发警报的标准,例如,资源时间序列开始显示异常的CPU
使用率。Prometheus
服务器没有内置警报工具,而是将警报从Prometheus
服务器推送到名为Alertmanager
(警报管理器)[1]的单独服务器。Alertmanager
可以管理、整合和分发各种警报到不同目的地https://prometheus.io/docs/alerting/alertmanager
/Prometheus
称其可以抓取的指标来源为端点(endpoint
)。端点通常对应单个进程、主机、服务或应用程序。为了抓取端点数据,Prometheus
定义了名为目标(target
)的配置Prometheus
服务器的HTTP API
,从而访问数据库中的所有数据Prometheus
命令行、配置文件、规则文件和运行时配置float
64类型的数值instrumentation label
):插桩标签来自被监控的资源——例如,对于与HTTP
相关的时间序列,标签可能会显示所使用的特定HTTP
动词。这些标签在由诸如客户端或exporter
抓取之前会被添加到时间序列中target label
):目标标签更多地与架构相关——它们可能会识别时间序列所在的数据中心。目标标签由Prometheus
在抓取期间和之后添加Prometheus
中可以自动更新的资源列表Consul
等数据存储,在Amazon
或Google
中运行实例,或使用DNS SRV
记录来生成资源列表Prometheus
部署到生产环境或进行扩展,则应该始终选择配置管理工具作为安装方法https://prometheus.io/download
/$ brew install prometheus
Docker Compose
安装Prometheus
、Node Exporter
和Grafana<sup>[1]</sup>
Docker Compose
单节点安装Prometheus
、Alertmanager
、Node Exporter
和Grafana<sup>[2]</sup>
https://github.com/vegasbrianc/prometheus
https://github.com/danguita/prometheus-monitoring-stack
3.1.6 通过配置管理工具安装PrometheusPrometheus
打包成服务:https://github.com/kayrus/prometheus-kubernetes
CoreOS
的Prometheus Operator
:https://github.com/coreos/prometheus-operator
3.2 配置Prometheus
YAML
配置非常复杂,可能让人很痛苦,建议你通过YAML Lint
(http://www.yamllint.com
/)在线方式或者在命令行使用yamllint
(https://github.com/adrienverge/yamllint
)来验证YAML
配置文件YAML
块Puppet
的Prometheus
模块:https://forge.puppet.com/puppet/prometheus
Chef
的Prometheus cookbook
:https://supermarket.chef.io/cookbooks/prometheus-platform
Ansible
的Prometheus role
:https://github.com/cloudalchemy/ansible-prometheus
SaltStack
的Prometheus formula
:https://github.com/arnisoph/saltstack-prometheus-formula
3.1.7 通过Kubernetes安装Prometheusglobal
alerting
rule_files
scrape_configs
3.2.1 global
3.2.2 alerting
3.2.3 rule_files
3.2.4 scrape_configs
prometheus.yml
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']promtool
来验证配置文件,这是Prometheus
附带的一个代码校验工具--storage.tsdb.path
选项:它的默认数据目录位于运行Prometheus
的目录中,用于控制时间序列数据库位置--storage.tsdb.retention
选项:控制时间序列的保留期。默认值为15d
,代表15天SSD
作为时间序列数据库的磁盘。对于每秒10万个样本的示例,我们知道按时间序列收集的每个样本在磁盘上占用大约1到2个字节。假设每个样本有2个字节,那么保留15天的时间序列意味着需要大约259 GB
的磁盘Prometheus
磁盘使用情况的更多信息,请参见存储文档(https://prometheus.io/docs/prometheus/latest/storage
/)process_resident_memory_bytes
指标来查看Prometheus
进程的内存使用情况sum
聚合来计算所有匹配的指标的计数和,使用=~运算符和.+的正则表达式来匹配所有指标GB
的内存Prometheus
在内存中做了很多工作。每个收集的时间序列、查询和记录规则都会消耗进程内存。但一个有用的、粗略的经验法则是将每秒采集的样本数乘以样本的大小。我们可以使用以下查询语句来查看样本收集率Prometheus
的性能很难估计,因为它在很大程度上取决于你的配置、所收集的时间序列的数量以及服务器上规则的复杂性。一般容量规划关注两个问题:内存和磁盘PromQL
查询方面需要帮助,则可以使用查询编辑器Promeditor
,它可以在Prometheus
本地运行(https://github.com//davkal/promeditor
)promhttp_metric_handler_requests_total
指标来看sum()
运算符累加,但没有按作业分类,子句by
它允许按特定维度聚合rate()
函数用来计算一定范围内时间序列的每秒平均增长率,只能与计数器一起使用,最适合用于增长较慢的计数器或用于警报的场景range vector
)是第二个PromQL
数据类型,它包含一组时间序列,其中每个时间序列都包含一系列数据点。范围向量允许我们显示该时间段的时间序列,持续时间被包含在中括号[ ]中,内容是一个整数值后跟一个单位缩写,其中单位缩写prometheus_build_info
,它包含有关Prometheus
服务器的构建信息Prometheus
服务器的常见模式,它使用恒定值为1的指标,并且添加了你可能希望通过标签附加的相关信息http://localhost:9090/graph
来获得go_gc_duration_seconds
,里面有一个标签quantile
="0.5",表示这衡量的是第50百分位数,后面的数字是这个指标的值http://localhost:9090/metrics
内容s
:秒m
:分钟h
:小时d
:天w
:周exporter
,然后配置节点和Docker
指标让Prometheus
来抓取。基本主机资源监控CPU
Grafana
,并对收集的数据进行基本的可视化USE
:Utilization
)Saturation
)Error
)USE
方法可以概括为:针对每个资源,检查使用率、饱和度和错误。该方法对于监控那些受高使用率或饱和度的性能问题影响的资源来说是最有效的CPU
、磁盘等,但许多人也将软件资源包含在定义中Prometheus
使用exporter
工具来暴露主机和应用程序上的指标,目前有很多可用于各种目的的exporter
(https://prometheus.io/docs/instrumenting/exporters
/)exporter
:Node Exporter
(https://github.com/prometheus/node_exporter
),它还有一个textfile
收集器,允许你导出静态指标Linux
主机,然后下载并安装Node Exporter
。我们将选择一个Docker
守护进程主机exporter
,那么还有很多支持Prometheus
的主机监控客户端。例如,collectd
也可以收集Prometheus
指标(https://collectd.org/wiki/index.php/Plugin:Write_Prometheus
)exporter
的最佳方式。这种方式可以轻松地管理配置,并提供自动化和服务管理node_exporter
在端口9100上运行,并在路径/metrics
上暴露指标。你可以通过--web.listen-address
和--web.telemetry-path
参数来设置端口和路径no
-前缀来修改状态。(https://github.com/prometheus/node_exporter
的Enabled by default
和Disabled by default
),如textfile
收集器,textfile
收集器非常有用,因为它允许我们暴露自定义指标。这些自定义指标可能是批处理或cron
作业 等无法抓取的,可能是没有exporter
的源,甚至可能是为主机提供上下文的表态指标Prometheus
指标的字符串,然后暴露它们以便抓取.prom
结尾的文件内定义,并且使用Prometheus
特定文本格式metadata
)和两个标签。一个标签role
定义节点的角色。在示例中,标签的植 为docker_server
。另一个标签datacenter
定义主机的地理位置。最后,指标的值 为1,因为它不是计数型、测量型或计时型的指标,而是提供上下文textfile
收集器,我们不需要配置参数,它默认就会被加载。但我们需要指定textfile_exporter
目录,以便Node Exporter
知道在哪里可以找到自定义指标。为此,我们需要指定--collector.textfile.directory
参数--collector.systemd.unit-whitelist
参数配置,它会匹配systemd
正则表达式Node Exporter
导出的数据。查看当前prometheus.yml
文件和抓取配置文件的scrape_configs
部分,Node Exporter
默认抓取路径是/metrics
,重启Prometheus
服务器Prometheus
假设Node Exporter
具有默认路径/metrics
,并且抓取的目标形式如下:SIGHUP
或重新启动Prometheus
服务器,那么我们的配置将被重新加载,并且服务器也会开始抓取。我们很快就会看到时间序列数据开始流入Prometheus
服务器Prometheus
还提供了一种方式来限制收集器从服务器端实际抓取的数据,尤其是在你无法控制正抓取的主机的配置很有用params
块中collect
[]列表指定,然后将它们作为URL
参数传递给抓取请求。你可以使用Node Exporter
实例上的curl
命令来对此进行测试(只收集cpu
指标,其它指标忽略)Google
的cAdvisor
工具。在Docker
守护进程上,cAdvisor
作为Docker
容器运行,单个cAdvisor
容器返回针对Docker
守护进程和所有正在运行的容器的指标。Prometheus
支持通过它导出指标,并将数据传输到其他各种存储系统,如InfluxDB
、Elasticsearch
和Kafka
4.2.1 运行cAdvisor
docker run --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:rw \ --volume=/sys:/sys:ro \ --volume=/var/lib/docker:/var/lib/docker:ro \ --volume=/dev/disk:/dev/disk:ro \ --publish=8080:8080 \ --detach=true \ --name=cadvisor \ google/cadvisor:latest
4.2.2 抓取cAdvisor scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'node' static_configs: - targets: ['138.197.26.39:9100', '138.197.30.147:9100', '138.197.30.163:9100'] - job_name: 'docker' static_configs: - targets: ['138.197.26.39:8080']
4.3 抓取的生命周期 scrape_configs: - job_name: 'node' scheme: https metrics_path: /moremetrics static_configs: - targets: ['138.197.26.39:9100', '138.197.30.147:9100', '138.197.30.163:9100']
4.4 标签 更改或添加标签会创建新的时间序列 4.4.1 标签分类 4.4.2 重新标记 - job_name: 'docker' static_configs: - targets: ['138.197.26.39:8080', '138.197.30.147:8080', '138.197.30.163:8080'] metric_relabel_configs: - source_labels: [__name__] regex: '(container_tasks_state|container_memory_failures_total)' action: drop 删除指标 - job_name: 'docker' static_configs: - targets: ['138.197.26.39:8080', '138.197.30.147:8080', '138.197.30.163:8080'] metric_relabel_configs: - source_labels: [__name__] separator: ',' regex: '(container_tasks_state|container_memory_failures_total)' action: drop regex1;regex2;regex3 替换标签值 id="/docker/6f823kdj39892jd8j3jid983ujj8edjie99djc883mnbnc8833nccllddklsoow838ckkc8" metric_relabel_configs: - source_labels: [id] regex: '/docker/([a-z0-9]+)' replacement: '$1' target_label: container_id 删除标签 metric_relabel_configs: - regex: '/docker/([a-z0-9]+)' action: labeldrop 文档
http://localhost:9090/targets
查看抓取目标列表以及每个目标的状态node_cpu_seconds_total
的指标是主机上CPU
使用率CPU
使用百分比,但要实现这一点,需要稍微处理下指标,可以通过一系列PromQL
计算来实现这一结果CPU
模式的每秒使用率。PromQL
有一个名为irate
的函数,用于计算范围向量中时间序列增加的每秒即时速率。让我们对node_cpu_seconds_total
指标使用irate
函数,在查询框中输入(表示为5分钟范围内的每秒速率)avg
或average
去处符介绍的by
子句idle
的值 ,并且宽没有表示成百分比形式。我们将查询每个实例的idle
使用率,它已经是一个比率,将它乘以100转换为百分比CPU
使用率的百分比CPU
考虑在内的一段时间内的平均运行队列长度。平均负载少于CPU
的数量通常是正常的,长时间内超过该数字的平均值 则表示CPU
已饱和CPU
数量,可使用count
聚合实现idle
的mode
计算node_cpu_seconds_total
时间序列出现次数,然后使用by
子句从结果向量中删除instance
之外的所有标签,可以看到3个节点各有2个CPU
node_load
1指标结合起来,如下所示CPU
数量的两倍的结果https://prometheus.io/docs/prometheus/latest/querying/operators/#aggregation-operators
Node Exporter
内存指标按内存的类型和使用率进行细分。可以在以node_memory
为前缀的指标列表中找到它们node_memory
指标的一个子集以获取使用率/proc/vmstat
收集的两个Node Exporter
指标KB
为单位node_vmstat_pswpin
:系统每秒从磁盘读到内存的字节数node_vmstat_pswpout
:系统每秒从内存写到磁盘的字节数node_filesystem_size_bytes
显示被监控的每个文件系统挂载大小。我们可以使用与内存指标类似的查询来生成在主机上使用的磁盘空间的百分比mountpoint
标签文件系统"/"挂载,返回该文件系统的磁盘使用指标Prometheus
提供了一种机制,通过一个名为predict_linear
的函数,可以构造一个查询来回答这个问题h
],并将此时间序列快照放在predict_linear
函数中。该函数使用简单的线性回归,根据以前的增长情况来确定文件系统何时会耗尽空间。该函数参数包括一个范围向量,即一小时窗口,以及未来需要预测的时间点node_systemd_unit_state
指标中暴露出来。对于收集的每个服务和服务状态都有一个指标node_systemd_unit_state
state
标签来进一步缩小搜索范围,仅返回active
状态的数据name
标签为docker.service
的所有指标https://prometheus.io/docs/prometheus/latest/querying/operators/#comparison-binary-operators
up
指标Prometheus
还会填充其他一些监控指标,包括scrape_duration_seconds
(抓取的持续时间)和scrape_duration_scraped
(目标暴露的样本数)up
指标exporter
都有特定的指标,旨在确定最后一次成功的数据抓取。例如,cAdvisor
指标container_last_seen
,它提供容器列表以及它们最近一次活动的时间。MySQL Exporter
返回一个指标mysql_up
up
指标,因为它们是在重新标记阶段之后生成的docker_server
,主机的位置datacenter
。尽管这些数据本身很有用,但为什么又要创建一个单独的指标而不是仅将作为标签添加到主机的指标中呢?我们已经知道标签提供了时间序列的维度,并且与指标名称相结合,它们构成了时间序列的标识。同时,我们也已经被警告过:NJ
)的数据中心metadata
指标来进行向量匹配(vector match
)。向量匹配可以使用任何PromQL
二元运算符。向量匹配尝试针对左侧向量中的每个元素在右侧向量中查找对应的匹配元素one-to-one
)和多对一(many-to-one
,或一对多(one-to-many
))ignoring
修饰符忽略掉特定标签,或者使用on
修饰符来减少显示的标签列表node_system_unit_state
指标中name
标签为docker.service
并且值为1的指标。然后,我们使用on
修饰符将返回的标签列表减少到metadata
指标的instance
和job
标签,并且datacenter
标签的值 为SF
group_left
或group_right
修饰符显式指定,其中left
或right
是为了确定哪个向量具有更高的基数。Prometheus
文档包含了一些这种匹配的例子,但它们通常不会被使用。大多数情况下,一对一匹配就足够了https://prometheus.io/docs/prometheus/latest/querying/operators/#vector-matching
元数据风格的指标
4.6 查询持久性
4.6.1 记录规则
4.6.2 配置记录规则
global: scrape_interval: 15s evaluation_interval: 15s
mkdir -p rules cd rules touch node_rules.yml
rule_files: - "rules/node_rules.yml"CPU
、内存和磁盘计算转换为记录规则。我们有很多要监控的主机,所以我们要对所有节点预先计算这三个指标的查询,这样就可以将这些计算作为指标,然后可以设置警报或者通过Grafana
等仪表板进行可视化node_rules
。规则组名称在服务器中必须是唯一的。规则组内的规则以固定间隔顺序执行。默认情况下,这是通过全局evaluate_interval
来控制的,但你可以使用interval
子句在规则组中覆盖rules
的YAML
块,它包含该组的记录规则。每条规则都包含一条记录,告诉Prometheus
将新的时间序列命名为什么。你应该仔细命名规则,以便快速识别它们代表的内容。一般推荐的格式是:level
表示聚合级别,以及规则输出的标签。metric
是指标名称,除了使用rate()
或irate()
函数剥离_total
计数器之外,应该保持不变。这样的命名可以帮助你更轻松地找到新指标。最后,operations
是应用于指标的操作列表,一般最新的操作放在前面。CPU
查询将命名为expr
字段来保存生成新时间序列的查询labels
块以向新时间序列添加新标签SIGHUP
信号发送到Prometheus
进程,可以在运行时重新加载规则文件。重新加载仅在规则文件格式良好时才有效。Prometheuus
服务器附带一个名为promtool
的实用程序,可以帮助检测规则文件instance:node_cpu:avg_rate5m
,则应该可以看到如下内容web
界面的/rules
路径中查看当前服务器上定义的规则Prometheus
通常不用于长期数据保留,默认保存15天的时间序列数据。这意味着Prometheus
更专注于监控问题,而不是其他可视化和仪表板系统Grafana
并将Prometheus
连接到上面Red Hat
上获取PackageCloud
公钥grafana.repo
文件内的/etc/yum.repos.d
/目录中yum
或者dnf
命令来安装Grafana
sudo yum install grafana
在Mac OS X上安装Grafana
brew install grafana
Docker镜像Linux
上启动Grafana
sudo service grafana-server startGrafana
是一个基于Go
的Web
应用服务,默认在端口3000上运行。一旦运行,你就可以通过浏览器访问——例如,如果它在本地主机上运行,则可直接访问http://localhost
:3000admin
和admin
,你可以通过更新Grafana
配置文件的[security
]部分来控制Grafana
与我们的Prometheus
数据关联起来,单击入门教程中的"Add data source"
Prometheus
。接下来,选中Default
复选框,告诉Grafana
默认搜索该数据源的数据。我们还需要确保将数据源类型设置为Prometheus
HTTP
设置,这是我们要查询的Prometheus
服务器的URL
。我们假设Grafana
与Prometheus
在同一台主机上运行,因此这里使用本地服务器的http://localhost
:9090Access
选项设置为proxy
(代理),但是这并没有为我们的连接配置HTTP
代理,不过它告诉Grafana
使用自己的Web
服务来代理与Prometheus
的连接。另一个选项direct
,是从Web
浏览器直接连接。proxy
设置更加实用一些,因为连接部分交由Grafana
服务负责Add"
按钮就可以完成新数据源的添加。在界面上,现在可以看到我们的数据源显示。如果保存后有横幅弹出提示"Datasource is working"
,则表明它正在工作!Grafana
图标,然后单击"Dashboards->Home"
返回主控制台视图Grafana
入门:https://grafana.com/docs/guides/getting_started
/Grafana
教程和录像:https://grafana.com/docs/tutorials/screencasts
/Prometheus
文档中的Grafana
部分:https://prometheus.io/docs/visualization/grafana
/Grafana
预建仪表板:https://grafana.com/grafana/dashboards
Grafana
仪表板,以满足特定的需求,如Mysql
(https://github.com/percona/grafana-dashboards
)或Redis
(https://grafana.com/grafana/dashboards
/763)JSON
文件(https://github.com/turnbullpress/prometheusbook-code/blob/master/4/dashboard.json
)The Docker Book
》https://dockerbook.com
/OS X
启动时启动Grafana
brew services start grafana
4.7.3 配置Grafana Web界面
4.7.4 第一个仪表板
有大量资源和示例可供参考
书
https://hub.docker.com/search?q=grafana&type=image
4.7.2 启动和配置GrafanaPrometheus
使用2.0格式:https://www.robustperception.io/converting-rules-to-the-prometheus-2-0-format
4.6.3 添加记录规则
group: - name: node_rules rules: - record: instance:node_cpu:avg_rate5m expr: 100 - avg(irate(node_cpu_seconds_total{job="node",mode="idle"}[5m])) by (instance) * 100
level:metric:operations
instance:node_cpu:avg_rate5m
在Prometheus
文档中有一些全名的最佳实践:https://prometheus.io/docs/practices/naming
/
group: - name: node_rules rules: - record: instance:node_cpu:avg_rate5m expr: 100 - avg(irate(node_cpu_seconds_total{job="node",mode="idle"}[5m])) by (instance) * 100 labels: metric_type: aggregation
group: - name: node_rules rules: - record: instance:node_cpu:avg_rate5m expr: 100 - avg(irate(node_cpu_seconds_total{job="node",mode="idle"}[5m])) by (instance) * 100 - record: instance:node_memory_usage:percentage expr: (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes)) / node_memory_MemTotal_bytes * 100 - record: instance:root:node_filesystem_usage:percentage expr: (node_filesystem_size_bytes{mountpoint="/"} - node_filesystem_free_bytes{mountpoint="/"}) / node_filesystem_size_bytes{mountpoint="/"} * 100
4.7 可视化 4.7.1 安装Grafana sudo rpm --import https://packagecloud.io/gpg.key [grafana] name=grafana baseurl=https://packagecloud.io/grafana/stable/el/7/$basearch repo_gpgcheck=1 enabled=1 gpgcheck=1 gpgkey=https://packagecloud.io/gpg.key https://grafanarel.s3.amazonaws.com/RPM-GPG-KEY-grafana sslverify=1 sslcacert=/etc/pki/tls/certs/ca-bundle.crt
Prometheus
配置文件prometheus.yml
的rule_files
块中添加这个文件prometheus.yml
配置文件的global
块中的evaluation_interval
参数控制evaluation_interval
参数exporter
使用这种"元数据"模式来提供额外状态的信息,例如cAdvisor
的cadvisor_version
指标relabel_configs
:https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config
RE
2正则表达式语法:https://github.com/google/re2/wiki/Syntax
http://www.regexplanet.com/advanced/golang/index.html
4.5 Node Exporter和cAdvisor指标 4.5.1 USE方法 CPU使用率
node_cpu_seconds_total{cpu="cpu0",instance="138.197.26.39.9100",job="node",mode="user"} irate(node_cpu_seconds_total{job="node"}[5m]) avg(irate(node_cpu_seconds_total{job="node"}[5m])) by (instance) avg(irate(node_cpu_seconds_total{job="node",mode="idle"}[5m])) by (instance) * 100 100 - avg(irate(node_cpu_seconds_total{job="node",mode="idle"}[5m])) by (instance) * 100
CPU饱和度 count by (instance)(node_cpu_seconds_total{mode="idle"}) node_load1 > on (instance) 2 * count by (instance)(node_cpu_seconds_total{mode="idle"}) 内存使用率 (总内存-(可用内存+缓冲缓存中的内存+页面缓存中的内存))÷总内存×100 (node_memory_MemTotal_bytes - (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes)) / node_memory_MemTotal_bytes * 100
内存饱和度 1024 * sum by (instance) ( (rate(node_vmstat_pgpgin[1m]) + rate(node_vmstat_pgpgout[1m])) ) 磁盘使用率 (node_filesystem_size_bytes{mountpoint="/"}) - node_filesystem_free_bytes{mountpoint="/") / node_filesystem_size_bytes{mountpoint="/"} * 100 predict_linear(node_filesystem_free_bytes{mountpoint="/"}[1h], 4*3600) < 0 4.5.2 服务状态 node_systemd_unit_state{name="docker.service",state="active"} 4.5.3 可用性和up指标 up{job="<job-name>", instance="<instance-id>"} 4.5.4 metadata指标 metadata{role="docker_server",datacenter="NJ"} 1 更改标签或添加新标签都会创建新的时间序列 metadata{datacenter!="NJ"} 向量匹配 一对一匹配 node_system_unit_state{name="docker.service"} == 1 and on (instance, job) metadata{datacenter="SF"} node_system_unit_state{instance="138.197.30.147:9100", job="node", name="docker.service", state="active"} 多对一和一对多匹配
container_id
中,通过重新标记我们可以这样做cAdvisor
指标都有一个id
标签,其中包含正在运行的进程的名称。如果进程是一个容器,会看到如下信息source_labels
参数选择要操作的指标,并且还需要一组标签名称。在示例中我们使用____name
标签,____name
标签是表示指标名称的预留标签relabel_configs
),这对于将来自服务发现的元数据标签中的信息应用于指标上的标签来说非常有用。这是在作业内的relabel_configs
块中完成的metric_relabel_configs
)且指标被保存于存储系统之前。这样,我们就可以确定哪些指标需要保存、哪些需要丢弃以及这些指标的样式。这是在我们作业 内的metric_relabel_configs
块中完成的job
和instance
schematic label
)是url
、error_code
或user
之类的东西,它们允许你将拓扑中同一级别的时间序列匹配在一起,例如创建数据间的比率Prometheus
提供了可以重新标记目标的机会,并可能使用你的服务发现所添加的一些元数据。你还可以过滤目标,以删除或保留特定条目API
等__meta
_为前缀。每个服务发现机制都有不同的元数据____scheme
_、______address
和____metrics_path
_。这些标签包含目标的模式(http
或https
)、目标的地址以及指标的具体路径______metrics_path
__默认为/metrics
,____scheme
默认为值http
。此外,如果路径中存在任何URL
参数,则它们的前缀会设置为________param
___*。instance
标签的默认内容是____address
标签的内容Web UI
上显示Prometheus
,其中一些标签可以在配置中被覆盖 ,例如,通过metrics_path
参数设置的指标路径以及通过scheme
参数指定的模式Prometheus cAdvisor
是在Docker
守护进程上运行的。为此,我们将在配置中添加第三个作业web ui
(http://11.11.11.112:8080/containers
)Docker
1主机上运行一个cAdvisor
容器cAdvisor
容器docker.service
:Docker
守护进程ssh.service
:SSH
守护进程rsyslog.service
:RSyslog
守护进程Prometheus
服务器自己的指标Node Exporter
指标cAdvisor
指标node_memory_MemTotal_bytes
:主机上的总内存node_memory_MemFree_bytes
:主机上的可用内存node_memory_Buffers_bytes
:缓冲缓存中的内存node_memory_Cached_bytes
:页面缓存中的内存https://prometheus.io/docs/prometheus/latest/configuration/recording_rules
/https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules
/Grafana
等仪表板可视化查询cAdvisor
将从中收集数据,例如/sys
目录--volume=/sys:/sys:ro
Docker
套接字的挂载,通常位于/var/run
目录中API
(例如Amazon AWS API
)以获取目标列表DNS
记录以返回目标列表static_configs
块中定义的scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
static_configs:
- targets: ['11.11.11.111:9100', '11.11.11.112:9100', '11.11.11.113:9100']
DNS
的方式- job_name: node
file_sd_configs:
- files:
- targets/nodes/*.json
refresh_interval: 5m
- job_name: docker
file_sd_configs:
- files:
- targets/docker/*.json
refresh_interval: 5m
file_sd_configs
块替换prometheus.yml
文件中的static_configs
块。在这些块中,已经指定了文件列表,并包含在files
列表中。我们在父目录targets
下为每个作业指定了对应的文件,并为每个作业创建了一个子目录。你可以创建适合你的任何文件结构Prometheus
都会重新加载文件的内容。以防万一,我们还指定了refresh_interval
选项,该选项将在每个间隔结束时加载文件列表中的目标——对这个示例来说是5分钟prometheus_sd_file_mtime_seconds
的指标将告诉你文件的上次更新时间。你可以监控这个指标以识别数据过期问题cd /etc/prometheus
mkdir -p targets/{nodes,docker}
Docker
守护进程列表移动到新的JSON
文件,创建两个文件来保存这些目标JSON
文件touch targets/nodes/nodes.json
touch targets/docker/daemons.json
node.json
文件node.json
文件[{
"targets": ["138.197.26.39:9100", "138.197.30.147:9100", "138.197.30.163:9100"]
}]
daemons.json
文件daemons.json
文件[{
"targets": ["138.197.26.39:8080", "138.197.30.147:8080", "138.197.30.163:8080"]
}]
yaml
格式实现和使用JSON
的目标列表是一样的- targets:
- "138.197.26.39:8080"
- "138.197.30.147:8080"
- "138.197.30.163:8080"
[{
"targets": ["138.197.26.39:8080", "138.197.30.147:8080", "138.197.30.163:8080"],
"labels": {"datacenter": "nj"}
}]
__meta_filepath
,它包括配置目标的文件路径和文件名https://localhost:9090/service-discovery
,通过web
界面查看服务发现目标的完整列表及其元数据标签API
密钥或密码等信息,应该依靠密钥保管库或环境变量(https://www.12factor.net
/)Prometheus
文档中还有一个基于文件的服务发现集成列表(https://prometheus.io/docs/operating/integrations/#file-service-discovery
)Amazon EC
2Azure
Consul
Google Compute Cloud
Kubernetes
(https://prometheus.io/docs/prometheus/latest/configuration/configuration/#kubernetes_sd_config
)DNS
服务发现允许你指定DNS
条目列表,然后查询这些条目中的记录以发现目标列表。它依赖于A
、AAAA
或SRV DNS
记录查询DNS
记录将由Prometheus
服务器上本地定义的DNS
服务器解析。例如,Linux
上的/etc/resolv.conf
DNS
服务发现作业- job_name: webapp
dns_sd_configs:
- names: ['_prometheus._tcp.example.com']
webapp
的新作业 ,并指定了一个dns_sd_configs
块。在该块中,我们指定了names
参数,其中包含要查询的DNS
条目列表Prometheus
的DNS
服务发现假定你会查询SRV
或服务发现。服务记录是一种在DNS
配置中定义服务的方法,服务通常由运行服务的一个或多个目标主机和端口组合组成。DNS SRV
条目的格式如下所示SRV
记录_service._proto.name. TTL IN SRV priority weight port target.
_service
是要查询的服务名称,__proto
是服务的协议,通常是TCP
或UDP
。我们指定条目的名称,后面以"."结尾,然后是记录的TTL
(Time To Live
)时间。IN
是标准的DNS
类(通常都会用IN
)。我们指定目标主机的优先级(priority
):较低的值 具有较高的优先级SRV
记录_prometheus._tcp.example.com 300 IN SRV 10 1 9100 webapp1.
_prometheus._tcp.example.com 300 IN SRV 10 1 9100 webapp2.
_prometheus._tcp.example.com 300 IN SRV 10 1 9100 webapp3.
Prometheus
查询目标时,它会通过DNS
服务器查找example.com
域。然后,它将在该域中搜索名为_prometheus._tcp.example.com
的SRV
记录,并返回该条目中的服务记录。在该条目中有三条记录,因此我们会看到返回了三个目标SRV
的DNS
目标webapp1.example.com
webapp2.example.com
webapp3.example.com
DNS
服务发现来查询单个A
或AAAA
记录。为此,我们需要为抓取明确指定查询类型的端口。之所以需要指定端口,是因为A
或AAAA
记录只返回主机,而不是像SRV
记录那样返回主机和端口组合DNS A
记录服务发现作业- job_name: webapp
dns_sd_configs:
- names: ['example.com']
type: A
port: 9100
example.com
域根目录下的所有A
记录DNS
子域A
记录服务发现作业- job_name: webapp
dns_sd_configs:
- names: ['web.example.com']
type: A
port: 9100
web.example.com
的A
记录解析,并在后面加上9100端口后缀DNS
服务发现中只有一个元数据标签__meta_dns_name
,它被设置为生成目标的特定DNS
记录Prometheus
是一个按功能划分的平台,指标的收集和存储与警报是分开的。警报管理功能由名为Alertmanager
的工具提供,该工具是监控体系中的独立组件。我们需要在Prometheus
服务器上定义警报规则,这些规则可以触发事件,然后传播到Altermanager
。接下来,Alertmanager
会决定如何处理相应的警报,进而解决去重等问题,还会确定在发送警报时使用的机制:实时消息、电子邮件或通过PagerDuty
和VictorOps
等工具symptom
)进行警报。症状是应用程序停止工作的迹象,它们可能是由许多原因导致的各种问题的表现。API
或网站的高延迟是一种症状,这种症状可能由许多问题导致:高数据库使用率、内存问题、磁盘性能等。对症状发送警报可以识别真正的问题。仅对原因(例如高数据库使用率)发出警报也可能识别出问题(但通常很可能不会)。对于这个应用程序,高数据库使用率可能是完全正常的,并且可能不会对最终用户或应用程序造成性能问题。作为一个内部状态,发送警报是没有意义的。这种警报可能会导致工程师错过更重要的问题,因为他们已经对大量不可操作且基于原因的警报变得麻木。你应该关注基于症状的警报,并依赖你的指标或其他诊断数据来确定原因Nagios
警报GB
分区上9%的可用磁盘空间与1TB
磁盘上9%的可用磁盘空间完全不同。我们可以忽略或静音这类通知吗?还是需要立即采取行动?Google SRE
手册中有一个很棒的关于警报的章节Alertmanager
处理从客户端发来的警报(https://prometheus.io/docs/alerting/alertmanager
/),客户端通常是Prometheus
服务器。Alertmanager
对警报进行去重、分组,然后路由到不同的接收器,如电子邮件、短信或SaaS
服务(PagerDuty
等)Alertmanager
架构https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules
/)将使用收集的指标并在指定的阈值或标准上触发警报。我们还将看到如何为警报添加一些上下文。当指标达到阈值或标准时,会生成一个警报并将其推送到Alertmanager
。警报在Alertmanager
上的HTTP
端点上接收。一个或多个Prometheus
服务器可以将警报定向到单个Alertmanager
,或者你可以创建一个高可用的Alertmanager
集群Alertmanager
二进制:https://github.com/prometheus/alertmanager
Prometheus.io
下载页面:https://prometheus.io/download/#alertmanager
GitHub Releases
页面:https://github.com/prometheus/alertmanager/releases
amtool
二进制文件用于帮助管理Alertmanager
amtool
二进制文件sudo cp alertmanager /usr/local/bin
sudo cp amtool /usr/local/bin
sudo chmod -R 777 /usr/local/bin/{alertmanager,amtool}
Docker Compose
安装Prometheus
、Node Exporter
和Grafana
(https://github.com/vegasbrianc/prometheus
)Docker Compose
单节点安装Prometheus
、Alertmanager
、Node Exporter
和Grafana
(https://github.com/danguita/prometheus-monitoring-stack
)Docker Swarm
安装Prometheus
(https://github.com/stefanprodan/swarmprom
)Alertmanager
配置也是基于YAML
的配置文件(https://prometheus.io/docs/alerting/configuration
/)alertmanager.yml
配置文件global:
smtp_smarthost: 'localhost:25'
smtp_from: 'alertmanager@example.com'
smtp_require_tls: false
template:
- '/etc/alertmanager/template/*.tmpl'
route:
receiver: email
receivers:
- name: 'email'
email_configs:
- to: 'alerts@example.com'
template
块包含保存警报模板的目录列表(https://prometheus.io/docs/alerting/notifications
/)。由于Alertmanager
可以发送到各种目的地,因此你通常需要能够自定义警报的外观及其包含的数据。现在让我们创建这个目录sudo mkdir -p /etc/alertmanager/template
route
块会告诉Alertmanager
如何处理特定的传入警报。警报根据规则进行匹配然后采取相应的操作。你可以把路由想象成有树枝的树,每个警报都从树的根(基本路由或基本节点)进入。除了基本节点之外,每个路由都有匹配的标准,这些标准应该匹配所有警报。然后,你可以定义子路由或子节点,它们是树的分支,对某些特定的警报感兴趣,或者会采取某些特定的操作Alertmanager
路由email_configs
块来指定电子邮件选项,例如接收警报的地址。我们还可以指定SMTP
设置(将覆盖 全局设置),并添加其他条目(例如邮件标头)Webhook
接收器的内置接收器,你可以使用它将警报发送到Alertmanager
中没有特定接收器的其他目的地(https://prometheus.io/docs/alerting/configuration/#webhook_config
)Alertmanager
作为一个Web
服务运行,默认端口为9093。启动Alertmanager
代码清单:启动Alertmanager
alerting:
alertmanagers:
- static_configs:
- targets:
- alertmanager: 9093
Alertmanager
alerting: alertmanagers: - dns_sd_configs: - names: ['_alertmanager._tcp.example.com']
6.6.2 监控Alertmanager
- job_name: 'alertmanager' static_configs: - targets: ['localhost:9093']
6.7 添加警报规则 cd rules touch node_alerts.yml rule_files: - "rules/*_rules.yml" - "rules/*_alerts.yml" 6.7.1 添加第一条警报规则 groups: - name: node_alerts rules: - alert: HighNodeCPU expr: instance:node_cpu:avg_rate5m > 80 for: 60m labels: severity: warning annotations: summary: High Node CPU of {{ humanize $value}}% for 1 hour console: You might want to check the Node Dashboard at http://grafana.example.com/dashboard/db/node-dashboard instance:node_cpu:avg_rate5m > 80 6.7.2 警报触发 警报未激活
Alertmanager API
在/api/v1/alerts
路径接收警报ALERT
时间序列HighNodeCPU
警报被触发了,我们将能在Alertmanager Web
控制台http://alertmanager:9093/#/alerts
上看到该警报HighNodeCPU
警报邮件Prometheus
服务器也可能出问题。让我们添加一些规则来识别问题并对它们发出警告PrometheusConfigReloadFailed
,它让我们知道Prometheus
配置重新加载是否失败。如果上次重新加载失败,则使用指标prometheus_config_last_reload_successful
,且指标的值 为0Node Exporter
收集的systemd
指标。如果我们在节点上监控的服务不再活动,则会生成一个警报active
标签的node_systemd_unit_state
指标值为0,则会触发此警报,表示服务故障至少60秒severity
标签中添加了一个新值 critical
,并添加了一个模板注解,以帮助指示哪个实例和作业失败up
指标的平均值然后按job
聚合,并在该值低于50%时触发。如果作业中50%的实例无法完成抓取,则会触发警报job
对up
指标求和,然后将其除以计数,如果结果大于或等于0.8,或者特定作业中20%的实例未启动,则触发警报up
指标缺失警报Alertmanager
的行为。如果引发了新警报,那么Alertmanager
将等待下一个选项group_wait
中指定的时间段,以便在触发警报之前查看是否收到该组中的其他警报。你可以将其视为警报缓冲repeat_interval
。这个暂停并不适用于我们的警报组,而是适用于单个警报,并且是等待重新发送相同警报的时间段,我们指定为3个小时continue
选项来覆盖此行为,该选项控制警报是否先遍历路由,然后再返回以遍历路由树continue
选项默认为false
,但如果设置为true
,则警报将在此路由中触发(如果匹配),并继续执行下一个相邻路由。有时这对于向两个地方发送警报很有用,但更好的解决方法是在接收器中指定多个端点send_resolved
选项设置为true
,可以使用Alertmanager
发送它们。通常不建议发送这些已解决的警报,因为其可能导致“错误警报”的循环,进而导致警报疲劳,所以在启用之前要仔细考虑Slack
接收器,它会消息发送到Slack
实例(https://prometheus.io/docs/alerting/configuration/#slack_config
)Alertmanager
发送给Slack
的一般警报消息非常简单。你可以在其源代码中看到Alertmanager
使用的默认模板,该模板包含电子邮件和其他接收器的默认值 ,但是我们可以为许多接收器覆盖这些值 。例如,可以在Slack
警报中添加文本行Alertmanager
自定义通知使用Go
模板语法。警报中包含的数据也通过变量暴露。我们使用CommonAnnotations
变量,该变量包含一组警报通用的注解集Go template
函数来引用外部模板,从而避免在配置文件中嵌入较长且复杂的字符串,目录位于/etc/alertmanager/templates
Web
界面silence
Unsee
的Alertmanager
控制台(https://github.com/cloudflare/unsee
)amtool
命令行。amtool
二进制文件随Alertmanager
安装tar
包附带query
子命令来查询当前silence
列表Instance
开头的alertname
。我们还使用了--comment
参数来添加有关警报的信息--author
参数覆盖了silence
的创建者,并将持续时间指定为两个小时,而不是默认的一小时silence
的创建,在创建silence
时,你还可以使用正则表达式作为标签值YAML
配置文件,而不必每次都指定--alertmanager.url
参数。amtool
查找的默认配置文件路径是$HOME/.config/amtool/config.yml
或/etc/amtool/config.yml
silence
过期amtool
创建的silence
被设置为一小时后自动过期,可以使用--expires
和--expire-on
参数来指定更长的时间或窗口Prometheus
称这种警报静音为silence
。silence
可以设定为特定时期,例如一小时,或者是一个时间窗口(如直到今天午夜)。这是silence
的到期时间或到期日期。如果需要,我们也可以提前手动让silence
过期(如果我们的维护比计划提前完成)Alertmanager
文档中还有一些其他的通知模板示例(https://prometheus.io/docs/alerting/notification_examples
/)Slack
接收器Prometheus
以一个固定时间间隔来评估所有规则,这个时间由evaluate_interval
定义,我们将其设置为15秒。在每个评估周期,Prometheus
运行每个警报规则中定义的天工并更新警报状态for
,控制在触发警报之前测试天工必须为true
的时间长度。在示例中,指标instance:node_cpu:avg_rate5m
需要在触发警报之前的60分钟内大于80%。这限制了警报误报或是暂时状态的可能性Prometheus
后,你将能够在Prometheus Web
界面http://localhost:9090/alerts
中看到新的警报node_alerts
,该组中的规则包含在rules
块中。在每个警报组中,警报名称都必须是唯一的CPU
警报规则(https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules
/)。我们将创建一个警报,如果我们创建的CPU
查询(5分钟内的节点平均CPU
使用率)在至少60分钟内超过80%,则会触发警报prometheus.yml
配置文件中的rule_files
块,可以使用globbing
通配符加载该目录中以_rules.yml
或__alerts.yml
结尾的所有文件Alertmanager
已经配置完成,让我们添加第一条警报规则。根据使用的节点查询来创建警报,并使用up
指标来创建一些基本的可用性警报Prometheus
一样,Alertmanager
暴露了自身的相关指标Prometheus
将查询_alertmanager.__tcp.example.com SRV
记录以获得Alertmanager
的主机名alerting
块包含允许Prometheus
识别一个或多个Alertmanager
的配置。为此,Prometheus
使用与查找抓取目标时相同的发现机制,在默认配置中是static_configs
。与监控作业一样,它指定目标列表,此处是主机名alertmanager
加端口9093(Alertmanager
默认端口)的形式。该列表假定你的Prometheus
服务器可以解析alertmanager
主机名为IP
地址,并且Alertmanager
在该主机的端口9093上运行prometheus.yml
配置文件中使用了默认的Alertmanager
配置,它包含在alerting
块中。让我们先来看看默认配置Alertmanager
提供了一个Web
界面:http://localhost
:9093Alertmanager
一起附带的还有一个命令行工具amtool
,允许你查询警报、管理silence
和使用Alertmanager
服务器等https://prometheus.io/docs/prometheus/latest/configuration/template_reference
/Alertmanager Web
控制台CPU
不断变化,每隔一段由scrape_interval
定义的时间被Prometheus
抓取一次,对我们来说是15秒true
时(对于我们来说是CPU
超过80%),会创建一个警报并转换到Pending
状态,执行for
子句Prometheus
架构认为,实现集群所需的投入以及维护集群节点之间数据一致性的成本要高于数据本身的价值Prometheus
推荐的容错解决方案是并行运行两个配置相同的Prometheus
服务器,并且这两个服务器同时处于活动状态。该配置生成的重复警报可以交由上游Alertmanager
使用其分组(及抑制)功能进行处理。一个推荐的方法是尽可能使上游Alertmanager
高度容错,而不是关注Prometheus
服务器的容错能力Alertmanager
集群来实现的。所有Prometheus
服务器会向所有的Alertmanager
发送警报。Alertmanager
负责去除重复数据并通过集群共享警报状态Prometheus
服务器都会收集指标,以加倍该集合可能产生的工作负载。其次,如果某个Prometheus
服务器出现故障或中断,那么另一台服务器就会存在数据缺失,在查询该服务器上的数据时会发现这一差距PromQL
中对上述问题进行修补。例如,当请求来自两个源的同一指标值 时,你可以通过max by
获取两个指标的最大值。或者,当单个工作分片可能存在差距的警报发生时,你可以增加for
子句以确保有多个值Prometheus
服务器的细节,使用配置管理工具可以相对容易实现这一点Alertmanager
包含由HashiCorp Memberlist
库(https://github.com/hashicorp/memberlist
)提供的集群功能。Memberlist
是一个Go
语言库,使用基于gossip
的协议来管理集群成员和成员故障检测,其也是SWIM
协议的扩展(http://arvix.org/abs
/1707.00788)Alertmanager
,将使用am
1主机来启动集群Alertmanager
集群alertmanager
二进制文件来指定一个配置文件,以及一个集群监听地址和端口。你需要在集群中的每个节点上使用相同的配置,这样可以确保对警报的处理是相同的,并且确保集群的一致性Alertmanager
应使用相同的配置!如果不相同,那么集群实际上并不是高可用的am
1主机的IP
地址172.19.0.10和8001端口。Alertmanager
集群中的其他节点将使用这个地址和羊肉串连接到集群,因此该端口需要在Alertmanager
集群节点之间的网络上保持可访问状态Alertmanager
,监听它们的本地IP
地址,并引用刚刚创建的集群节点的IP
地址和端口Alertmanager
集群的其他节点Alertmanager
主机(am
2和am
3)上同样运行alertmanager
二进制文件,并使用各自的IP
地址和8001端口来为每台主机指定一个集群监听地址。还使用集群cluster.peer
参数来指定am
1节点的IP
地址和端口作为peer
,以便它们可以加入集群Alertmanager
的控制台状态页面/status
上进行确认。我们来看看主机am
1上显示的集群状态https://172.19.0.10:9093/status
7.1.3 为Prometheus配置Alertmanager集群 alerting: alertmanagers: - static_configs: - targets: - am1:9003 - am2:9003 - am3:9003
alerting: alertmanager: - dns_sd_configs: - names: ['_alertmanager._tcp.example.com']
7.2 可扩展性 7.2.1 功能扩展
7.2.2 水平分片 scrape_configs: - job_name: 'federate' scrape_interval: 15s honor_labels: true metrics_path: '/federate' params: 'match[]': - '{job="prometheus"}' - '{__name__=~"job:.*"}' static_configs: - targets: - 'source-prometheus-1:9090' - 'source-prometheus-2:9090' - 'source-prometheus-3:9090'
Grafana
等工具暴露指标或者作为可视化的默认数据源worker
),每个节点都抓取一部分目标。然后,我们在工作节点上汇总感兴趣的特定时间序列。例如,若我们正在监控主机指标,则可能会汇总这些指标的子集。然后,主节点(primary
)使用Prometheus federation API
来抓取每个工作节点的聚合指标(https://prometheus.io/docs/prometheus/latest/federation
/)federation
)将时间序列撮到集中的Prometheus
服务器。Grafana
支持从多个Prometheus
服务器撮数据来构建图形,允许在可视化级别联合来自多个服务器的数据,前提是收集的时间序列具有一定的一致性(https://grafana.com/docs/grafana/latest/features/datasources/mixed/#mixed-data-source
)Prometheus
服务器上。例如,可以通过地理位置或者逻辑域来拆分服务器Prometheus
环境扩展通常有两种形式:功能扩展或水平扩展Prometheus
将查询alertmanager.example.com SRV
记录以返回Alertmanager
列表。我们可以使用其他服务发现机制,让Prometheus
识别集群中的所有Alertmanager
Prometheus
,那么我们可以在Prometheus
服务器的状态页面中看到所有连接的Alertmanager
Alertmanager
。Alertmanager
接收警报、处理数据去重并共享 状态Prometheus
连接的Alertmanager
集群SRV
记录的形式指定了名为_alertmanager
的TCP
服务。我们的记录返回三个主机名am
1、am
2和am
3,以及端口号9093(Prometheus
可以在这里找到一个正在运行的Alertmanager
)。让我们配置Prometheus
服务器来发现它们Alertmanager
服务发现Alertmanager
添加DNS SRV
记录Alertmanager SRV
记录Alertmanager
集群本身负责与集群的其他活动成员共享所有收到的警报,并处理数据去重(如果需要)。因此,你不应该为Alertmanager
设置负载平衡,因为Prometheus
会帮你处理Alertmanager
静态定义Alertmanager
上设置silence
并查看配置是否复制到其他Alertmanager
节点,以此来测试集群是否正常工作。为此,请单击am
1上的New Silence
按钮并设置silence
,然后检查am
2和am
3上的/silences
路径,应该可以看到所有主机上都复制了相同的silence
配置API
端点。如果你正在监控现有应用程序,那么可以创建一个特定网页或端点的优先级列表,并按重要性顺序对其进行监控API
的调用次数和时间,例如,如果你的应用程序使用数据库、缓存或搜索服务,或者使用第三方服务(如支付网关)cron
作业)的数量和时间Prometheus
会倾向于关注可即刻获取的指标。对于长期业务指标,在许多情况下,你可能会使用基于事件的系统USE
和RED
方法,以及Google
黄金指标metrics-utility
类,它不需要实例化,只包含静态方法https://prometheus.io/docs/instrumenting/clientlibs
/)。实用程序库将暴露一个允许 我们创建和增加指标的API
Ruby
风格的代码来演示,假设已经创建了一个名为Metric
的实用程序库include Metric
def pay_user(user, amount)
pay(user.account, amount)
Metric.increment 'payment'
Metric.increment "payment-amount, #{amount.to_i}"
send_payment_notification(user.email)
end
def send_payment_notification(email)
send_email(payment, email)
Metric.increment 'email-payment'
end
payment
指标:在每次付款时都会增加指标的值payment-amount
指标:该指标按金额记录每笔付款send_payment_notification
来发送一封电子邮件,其中增加了第三个指标email-payment
的值。email-payment
指标用于计算发送的付款电子邮件的数量mwp-rails
应用程序例子:https://github.com/turnbullpress/mwp-rails
Ruby
的客户端添加对Prometheus
的支持(https://github.com/prometheus/client_ruby
)mwp-rails Gemfile
source 'https://rubygems.org' ruby '2.4.2' gem 'rails', '5.1.5' ... gem 'prometheus-client' ...
prometheus = Prometheus::Client.registry
test_counter = prometheus.count(:test_count, 'A test counter')
test_counter.increment
test_counter.get 1.0
test_counter = prometheus.counter(:test_counter, 'A test counter') test_gauge = prometheus.gauge(:test_gauge, 'A test gauge') test_histogram = prometheus.histogram(:test_histogram, 'A test histogram') test_summary = prometheus.summary(:test_summary, 'A test summary')
将监控添加到Rails
touch lib/metrics.rb
module Metrics def self.counter(name, docstring, base_labels = {}) provide_metric(name) || registry.counter(name, docstring, base_labels) end def self.summary(name, docstring, base_labels = {}) provide_metric(name) || registry.summary(name, docstring, base_labels) end def self.gauge(name, docstring, base_labels = {}) provide_metric(name) || registry.summary(name, docstring, base_labels) end def self.histogram(name, docstring, base_labels = {}, buckets = ::Prometheus::Clien::Histogram::DEFAULT_BUCKETS) provide_metric(name) || registry.histogram(name, docstring, base_labels, buckets) end private def self.provide_metrics(name) registry.get(name) end def. self.registry @registry || ::Prometheus::Client.registry end end
touch config/initializers/lib.rbincrement
方法添加标签或者指定增量,如下所示User
模型Rack
中间件来自动创建一些有关HTTP
请求的有用指标。在示例中,我们通过以config.ru
文件内添加exporter
(和中间件收集器)来启用指标端点Prometheus
添加到config.ru
文件中exporter
会创建一个路径/metrics
,其中包含由应用程序定义的Prometheus
注册表中指定的所有指标。惧器将一些HTTP
服务器指标添加到通过Rack
中间件收集的端点Rails
的/metrics
端点Prometheus
中使用它们。让我们创建一个作业来抓取/metrics
端点,然后把Rails
服务器添加到基于文件的服务发现中,按主机名添加3个Rails
服务器Rails
服务器的服务发现prometheus.yml
配置文件创建新的作业Rails
服务器目标metrics
库的依赖/config/initializers/lib.rb
require 'metrics'
def destroy user = User.find(params[:id]) user.destroy Metrics.counter(:users_deletes_counter, "Deletes users counter").increment redirect_to users_path, :notice => "User deleted." end
.increment({service: 'foo'}, 2)
class User < ActiveRecord::Base enum role: [:user, :vip, :admin] after_initialize :set_default, :if => :new_record? after_create do Metrics.counter(:user_created_counter, "Users created counter").increment end end
require 'prometheus/middleware/collector' require 'prometheus/middleware/exporter' use Prometheus::Middleware::Collector use Prometheus::Middleware::Exporter
使用指标
- job_name: rails file_sd_configs: - files: - targets/rails/*.json refresh_interval: 5m
Rails
以加载metrics
库,有几种方法可以做到这一点,但我最喜欢使用添加初始化程序的方式metrics
库创建初始化程序Metrics
模块Metrics
模块Prometheus client_ruby
指标increment
方法来增加指标的值Prometheus
应用程序监控的核心,你创建的每个指标都需要先注册。我们已创建了一个名为prometheus
的注册表,现在可以在此注册表中创建指标Prometheus
指标bundle
命令安装新的gem
bundle
命令安装prometheus-client
Rails
控制台来测试客户端,现在通过rails c
命令启动一个客户端Rails
控制台测试Prometheus
客户端Prometheus
注册表(registry
)Prometheus
注册表Process exporter
查看/proc
子系统的内容(https://github.com/ncabatoff/process-exporter
)docker run -d --rm -p 9256:9256 --privileged -v /proc:/host/proc -v `pwd`:/config ncabatoff/process-exporter --procfs /host/proc -config.path /config/filename.yml
Grok Exporter
(https://github.com/fstab/grok_exporter
)和名为mtail
的Google
实用程序(https://github.com/google/mtail
)。我们选择mtail
,因为它更轻巧,也更受欢迎Logstash
或者ELK
?目前它们无法直接输出到Prometheus
,但你可以使用Logstash
的指标过滤器来创建指标并将其直接输出到Alertmanager
(https://github.com/wtliuNA/logstash-output-prometheus
)mtail
日志处理器是由Google
的SRE
人员编写的,其采用Apache
2.0许可证,并且使用Go
语言。mtail
日志处理器专门用于从应用程序日志中提取要导出到时间序列数据库中的指标mtail
日志处理器通过运行“程序”(program
)来工作,它定义了日志匹配模式,并且指定了匹配后要创建和操作的指标。它与Prometheus
配合得很好,可以暴露任何要抓取的指标,也可以配置为将指标发送到collectd
、StatsD
或Graphite
等工具mtail
二进制文件wget https://github.com/google/mtail/releases/download/v3.0.0-rc33/mtail_v3.0.0-rc33_linux_amd64 -0 mtail
chmod 0755 mtail
sudo cp mtail /usr/local/bin
mtail
二进制文件mtail --version
mtail
程序mtail
程序目录sudo mkdir /etc/mtail
line_count.mtail
程序sudo touch /etc/mtail/line_count.mtail
line_count.mtail
程序counter line_count
/$/ {
line_count++
}
line_count
的计数器。计数器名称以counter
为前缀(自然地,测量型以gauge
为前缀)。这让计数和测量通过mtail
导出到你定义的任何目的地mtail
程序的内容:匹配的条件和采取的操作;首先指定条件,然后执行以下操作,包含在{}中else
子句的形式扩展(https://github.com/google/mtail/blob/master/docs/Language.md
)/foo/ {
ACTION1
} else {
ACTION2
}
/metrics
路径Apache combined
指标HTTP
响应代码维度。我们还可以执行更复杂的操作,例如构建直方图rails
程序(https://github.com/google/mtail/blob/master/examples/rails.mtail
)Rails mtail
指标输出mtail
程序,可以通过多种方式部署它们。我们建议为每个应用程序运行一个mtail
实例,并作为依赖项通过配置管理部署在应用程序周围。这种模式通常被称为边车(sidecar
)模式,非常适合容器化应用mtail
实例中运行多个程序,但有一点需要注意,mtail
会在传递给它的每个日志文件上运行每个程序,这可能会对主机产生性能影响Prometheus
作业抓取它们mtail
作业Web
服务器和一个Rails
服务器,两个目标都在端口3903上被抓取apache_http_requests_total
,将一些前缀为$的捕获添加到计数器中作为维度。每个维度都包含在[]方括号中mtail
,这次加载一些Apache
(或其他使用combined
日志格式的Web
服务器),那么会看到这些新生成的指标named capture group
)。在示例中,我们捕获request_status
的命名值,然后可以在操作中使用这些捕获combined
访问日志操作named capture group
)。在示例中,我们捕获request_status
的命名值 ,然后可以在操作中使用这些捕获by
运算符指定要添加到指标的其他维度。在第一个计数器apache_http_requests_total
中,我们添加了request_method
、http_version
、request_status
的附加维度,这些维度将作为标签添加到结果计数器中mtail
还允许你通过将正则天工定义为常量来重用它们https://github.com/google/mtail/tree/master/examples
mtail
从Apache
访问日志中撮一些指标,特别是使用combined
日志格式的指标apache_combined
程序--emit_prog_label
参数设置为false
来省略此标签mtail
的用户需要针对正在解析的日志文件的权限,否则mtail
将无法读取文件。当无法读取文件时,你将在使用--logtostderr
参数获得的mtail
日志输出中看到读取错误Web
服务器(可以使用--address
和--port
参数来设置IP
地址和端口)。浏览一下这个Web
服务器,根路径下会显示一些诊断信息StatsD
和Graphite
等工具mtail
的/metrics
路径--progs
告诉mtail
在哪里找到我们的程序,第二个参数--logs
告诉mtail
在哪里找到要解析的日志文件。我们使用glob
模式(https://godoc.org/path/filepath#Match
)来匹配/var/log
目录中的所有日志文件。你可以指定以逗号分隔的文件列表,也可以多次指定--logs
参数