Prometheus Pushgateway 的存在是为了允许临时作业和批处理作业将其指标公开给 Prometheus。由于此类工作可能存在的时间不够长而无法被删除,因此他们可以将其指标推送到 Pushgateway。然后 Pushgateway 将这些指标公开给 Prometheus。
首先,Pushgateway无法将Prometheus变成基于推送的监控系统。有关 Pushgateway 用例的一般描述,请阅读何时使用 Pushgateway。
Pushgateway 显然不是聚合器或分布式计数器,而是指标缓存。它没有类似 statsd 的语义。推送的指标与您在永久运行的程序中进行抓取时呈现的指标完全相同。如果您需要分布式计数,您可以将实际的 statsd 与 Prometheus statsd 导出器结合使用,或者查看 prom-aggregation-gateway。随着经验的积累,Prometheus 项目有一天可能能够提供一种独立于 Pushgateway 的本地解决方案,甚至可能作为 Pushgateway 的一部分。
对于机器级指标,节点导出器的文本文件收集器通常更合适。 Pushgateway 旨在用于服务级别指标。
Pushgateway 不是事件存储。虽然您可以使用 Prometheus 作为 Grafana 注释的数据源,但必须使用某些事件日志框架来跟踪发布事件等内容。
不久前,我们决定不对推送的指标实现“超时”或 TTL,因为几乎所有提议的用例都被证明是我们强烈反对的反模式。您可以关注 prometheus-developers 邮件列表上的最新讨论。
从发布页面下载适合您平台的二进制版本并解压 tarball。
如果您想从源代码自行编译,则需要一个有效的 Go 设置。然后使用提供的 Makefile(类型make
)。
对于最基本的设置,只需启动二进制文件即可。要更改侦听地址,请使用--web.listen-address
标志(例如“0.0.0.0:9091”或“:9091”)。默认情况下,Pushgateway 不保留指标。但是, --persistence.file
标志允许您指定一个文件,其中推送的指标将被持久化(以便它们在 Pushgateway 重新启动后继续存在)。
您可以使用 prom/pushgateway Docker 映像部署 Pushgateway。
例如:
docker pull prom/pushgateway
docker run -d -p 9091:9091 prom/pushgateway
必须使用常用方法之一将 Pushgateway 配置为 Prometheus 抓取的目标。但是,您应该始终在 scrape 配置中设置honor_labels: true
(有关详细说明,请参阅下文)。
Prometheus 客户端库应该具有将注册的指标推送到 Pushgateway 的功能。通常,Prometheus 客户端被动地提供 Prometheus 服务器抓取的指标。支持推送的客户端库都有一个推送函数,需要由客户端代码调用。然后,它会使用下面描述的 API 主动将指标推送到 Pushgateway。
使用 Prometheus 文本协议,推送指标非常简单,无需提供单独的 CLI。只需使用命令行 HTTP 工具(如curl
即可。您最喜欢的脚本语言很可能具有一些内置的 HTTP 功能,您也可以在此处利用。
请注意,在文本协议中,每一行都必须以换行符(也称为“LF”或“n”)结尾。以其他方式结束一行,例如使用“CR”又名“r”、“CRLF”又名“rn”,或仅结束数据包,将导致协议错误。
推送的指标按组进行管理,由任意数量标签的分组键标识,其中第一个标签必须是job
标签。通过网络界面可以轻松检查这些组。
有关标签值中特殊字符的含义,请参阅下面的 URL 部分。
示例:
将单个样本推送到由{job="some_job"}
标识的组中:
echo "some_metric 3.14" | curl --data-binary @- http://pushgateway.example.org:9091/metrics/job/some_job
由于没有提供类型信息, some_metric
将是untyped
类型。
将更复杂的内容推入由{job="some_job",instance="some_instance"}
标识的组中:
cat <
请注意如何提供类型信息和帮助字符串。这些行是可选的,但强烈建议您使用更复杂的内容。
删除由{job="some_job",instance="some_instance"}
标识的组中的所有指标:
curl -X DELETE http://pushgateway.example.org:9091/metrics/job/some_job/instance/some_instance
删除由{job="some_job"}
标识的组中的所有指标(请注意,这不包括上例中{job="some_job",instance="some_instance"}
组中的指标,即使这些指标具有相同的工作标签):
curl -X DELETE http://pushgateway.example.org:9091/metrics/job/some_job
删除所有组中的所有指标(需要通过命令行标志--web.enable-admin-api
启用管理 API):
curl -X PUT http://pushgateway.example.org:9091/api/v1/admin/wipe
Prometheus 服务器将为每个抓取的指标附加一个job
标签和一个instance
标签。 job
标签的值来自抓取配置。当您将 Pushgateway 配置为 Prometheus 服务器的抓取目标时,您可能会选择一个作业名称,例如pushgateway
。 instance
标签的值会自动设置为抓取目标的主机和端口。因此,从 Pushgateway 抓取的所有指标都将以 Pushgateway 的主机和端口作为instance
标签以及job
标签(如pushgateway
。您可能已附加到推送到 Pushgateway 的指标的job
和instance
标签之间的冲突可以通过将这些标签重命名为exported_job
和exported_instance
来解决。
然而,在抓取 Pushgateway 时,这种行为通常是不受欢迎的。通常,您希望保留推送到 Pushgateway 的指标的job
和instance
标签。这就是为什么你必须在 Pushgateway 的 scrape 配置中设置honor_labels: true
。它可以实现所需的行为。有关详细信息,请参阅文档。
这给我们留下了推送到 Pushgateway 的指标不具有instance
标签的情况。这种情况很常见,因为推送的指标通常处于服务级别,因此与特定实例无关。即使使用honor_labels: true
,如果首先没有设置instance
标签,Prometheus 服务器也会附加instance
标签。因此,如果将指标推送到 Pushgateway 时没有实例标签(并且分组键中没有实例标签,请参见下文),Pushgateway 将使用空实例标签 ( {instance=""}
) 导出它,这相当于根本没有instance
标签,但阻止服务器附加实例标签。
Pushgateway 通过相同的/metrics
端点公开所有推送的指标及其自己的指标。 (详细信息请参见公开的指标部分。)因此,所有指标必须相互一致:同名的指标必须具有相同的类型,即使它们被推送到不同的组,并且不能有重复,即具有相同名称和完全相同标签对的指标。会导致不一致的推送将被拒绝,状态代码为 400。
不过,不一致的帮助字符串是可以容忍的。 Pushgateway 将选择一个获胜的帮助字符串并在信息级别记录它。
遗留说明:Pushgateway 自己的push_time_seconds
指标的帮助字符串在 v0.10.0 中已更改。通过使用持久化文件,推送到早期版本Pushgateway的指标可以使其成为v0.10.0或更高版本的Pushgateway。在这种情况下,将显示上述日志消息。一旦之前推送的每个组被删除或收到新的推送,日志消息就会消失。
推送期间执行的一致性检查与抓取期间执行的一致性检查相同。在常见的用例中,抓取比推送更常见。因此,推送时间检查的性能成本并不相关。然而,如果 Pushgateway 上的大量指标与频繁的推送相结合,推送时长可能会变得非常长。在这种情况下,您可以考虑使用命令行标志--push.disable-consistency-check
,这可以节省推送期间一致性检查的成本,但允许推送不一致的指标。检查仍然会在抓取过程中进行,因此只要 Pushgateway 上存储的指标不一致,所有抓取都会失败。因此,设置该标志会使您面临因一次不一致的推送而禁用 Pushgateway 的风险。
如果您在时间t 1推送指标,您可能会倾向于相信 Prometheus 会使用相同的时间戳t 1来抓取它们。相反,Prometheus 附加的时间戳是它抓取 Pushgateway 的时间。为什么会这样呢?
在Prometheus的世界观中,一个metric可以随时被抓取。无法抓取的指标基本上已经不复存在。 Prometheus 具有一定的容忍度,但如果它无法在 5 分钟内获取某个指标的任何样本,它将表现得好像该指标不再存在一样。防止这种情况实际上是使用 Pushgateway 的原因之一。 Pushgateway 将使您的临时工作的指标可以随时进行抓取。将推送时间附加为时间戳会破坏该目的,因为在最后一次推送后 5 分钟,您的指标对于 Prometheus 来说将显得过时,就好像它根本无法再被刮擦一样。 (普罗米修斯只知道每个样本一个时间戳,无法区分“推送时间”和“抓取时间”。)
由于没有任何用例可以附加不同的时间戳,并且许多用户试图错误地这样做(尽管没有客户端库支持此操作),因此 Pushgateway 拒绝任何带有时间戳的推送。
如果您认为需要推送时间戳,请参阅何时使用 Pushgateway。
为了更容易地对失败的推送器或最近未运行的推送器发出警报,Pushgateway 将在指标push_time_seconds
和push_failure_time_seconds
中添加最后一次成功和失败的POST
/ PUT
到每个组的 Unix 时间戳。这将覆盖任何使用该名称推送的指标。任一指标的值为零意味着该组从未见过成功或失败的POST
/ PUT
。
所有推送均通过 HTTP 完成。该界面有点像 REST。
Pushgateway 监听的默认端口是 9091。路径如下
/metrics/job/{//}
用作job
标签的值,后跟任意数量的其他标签对(可能包含也可能不包含instance
标签)。 URL路径定义的标签集用作分组键。任何已在请求正文中设置的标签(作为常规标签,例如name{job="foo"} 42
)都将被覆盖,以匹配 URL 路径定义的标签!
如果job
或任何标签名称以@base64
为后缀,则以下作业名称或标签值将根据 RFC 4648 使用 URL 和文件名安全字母表解释为 Base64 编码字符串。 (填充是可选的,但需要单个=
来编码空标签值。)这是处理以下情况的唯一方法:
/
作业名称或标签值,因为普通(甚至 URI 编码) /
否则会被解释为路径分隔符。//
或尾随/
将会消失。请注意,空job
名称无效。空标签值有效但很少有用。要使用 base64 对其进行编码,您必须至少使用一个=
填充字符以避免//
或尾随/
。对于其他特殊字符,通常的 URI 组件编码也可以工作,但 base64 可能更方便。
理想情况下,客户端库负责处理后缀和编码。
示例:
要使用分组键job="directory_cleaner",path="/var/tmp"
,以下路径将不起作用:
/metrics/job/directory_cleaner/path//var/tmp
相反,对标签值使用 base64 URL 安全编码,并通过在标签名称后添加@base64
来标记它:
/metrics/job/directory_cleaner/path@base64/L3Zhci90bXA
如果您没有使用为您处理编码的客户端库,则可以使用编码工具。例如,有一个命令行工具base64url
(Debian软件包basez
),您可以将其与curl
结合使用,通过以下方式从命令行推送:
echo 'some_metric{foo="bar"} 3.14' | curl --data-binary @- http://pushgateway.example.org:9091/metrics/job/directory_cleaner/path@base64/$(echo -n '/var/tmp' | base64url)
要使用包含空标签值的分组键,例如job="example",first_label="",second_label="foobar"
,以下路径将不起作用:
/metrics/job/example/first_label//second_label/foobar
相反,请使用以下包含=
填充字符的路径:
/metrics/job/example/first_label@base64/=/second_label/foobar
分组键job="titan",name="Προμηθεύς"
可以用 URI 编码“传统地”表示:
/metrics/job/titan/name/%CE%A0%CF%81%CE%BF%CE%BC%CE%B7%CE%B8%CE%B5%CF%8D%CF%82
或者您可以使用更紧凑的 base64 编码:
/metrics/job/titan/name@base64/zqDPgc6_zrzOt864zrXPjc-C
较新版本的 Prometheus 展示格式(文本和 protobuf)支持度量和标签名称中的完整 UTF-8 字符集。如果设置了命令行标志--push.enable-utf8-names
Pushgateway 仅接受名称中的特殊字符。为了允许作为 URL 路径一部分的标签名称中的特殊字符,该标志还启用特定的编码机制。这与上述标签值的 base64 编码类似,但由于技术和历史原因,其工作原理在细节上有所不同。和以前一样,客户端库通常应该处理编码。其工作原理如下:
U__
开头。_1F60A_
。__
。U__
开头,则这些字符也必须进行编码,结果为U___55_____
。 (即U__
+ _55_
(对于U
)+ __
+ __
)。U__
开头但包含无效序列(例如U__in_xxx_valid
)的标签名称保持不变。例如,标签"foo.bar"="baz"
将被编码为:
/metrics/job/example/U__foo_2e_bar/baz
此编码与标签值的 base64 编码兼容:
/metrics/job/example/U__foo_2e_bar@base64/YmF6
请注意,此方法有一个不太可能的边缘情况,未正确处理:不知道编码机制的推送者可能使用的标签名称也是另一个标签名称的有效编码版本。例如,如果推送器打算使用标签名称U__foo_2e_bar
,但不将其编码为U___55_____foo__2e__bar
,则 Pushgateway 会将U__foo_2e_bar
解码为foo.bar
。这是通过--push.enable-utf8-names
标志选择解码的主要原因。
PUT
方法PUT
用于推送一组指标。 URL 中指定的分组键的所有指标都将替换为使用PUT
推送的指标。
请求的正文包含要以分隔的二进制协议缓冲区或简单的纯文本格式推送的指标(均在版本 0.0.4 中,请参阅数据展示格式规范)。两种变体之间的区分是通过Content-Type
标头完成的。 (对协议缓冲区使用值application/vnd.google.protobuf; proto=io.prometheus.client.MetricFamily; encoding=delimited
,否则尝试使用文本格式作为后备。)
成功时的响应代码为 200、202 或 400。200 响应意味着推送成功,替换现有指标组或创建新指标。如果请求格式错误或者推送的指标与推送到其他组的指标不一致或与 Pushgateway 本身的指标冲突,则可能会发生 400 响应。响应正文中返回解释并记录错误级别。仅当设置了--push.disable-consistency-check
标志时才会出现 202。在这种情况下,推送的指标只是排队,不检查一致性。然而,如上所述,不一致将导致抓取失败。
在极少数情况下,Pushgateway 最终可能会推送一组不一致的指标。在这种情况下,即使罪魁祸首是之前推送的指标,新推送也会因不一致而被拒绝。删除有问题的指标以摆脱这种情况。
如果使用 protobuf 格式,请勿在一次推送中发送重复的 MetricFamily proto 消息(即多个同名消息),因为它们会相互覆盖。
请注意,Pushgateway 不提供任何强有力的保证将推送的指标持久保存到磁盘。 (服务器崩溃可能会导致数据丢失。或者 Pushgateway 配置为根本不持久保存到磁盘。)
具有空正文的PUT
请求实际上会删除具有指定分组键的所有指标。但是,与下面描述的DELETE
请求相反,它确实更新了push_time_seconds
指标。
POST
方式POST
工作方式与PUT
方法完全相同,但仅替换与新推送的指标同名的指标(在具有相同分组键的指标中)。
具有空正文的POST
请求仅更新push_time_seconds
指标,但不会更改任何先前推送的指标。
DELETE
方法DELETE
用于从 Pushgateway 中删除指标。请求不得包含任何内容。删除 URL 中指定的分组键的所有指标。
成功时的响应代码始终为 202。此时删除请求只是排队。无法保证请求将实际执行或结果将到达持久层(例如,在服务器崩溃的情况下)。但是, PUT
/ POST
和DELETE
请求的顺序是保证的,即如果您成功发送了DELETE
请求,然后发送了PUT
,则保证DELETE
将首先被处理(反之亦然)。
删除没有指标的分组键是无操作,不会导致错误。
POST 或 PUT 请求的正文可以是 gzip 或 snappy 压缩的。添加标头Content-Encoding: gzip
或Content-Encoding: snappy
来执行此操作。
示例:
echo " some_metric 3.14 " | gzip | curl -H ' Content-Encoding: gzip ' --data-binary @- http://pushgateway.example.org:9091/metrics/job/some_job
echo " some_metric 3.14 " | snzip | curl -H ' Content-Encoding: snappy ' --data-binary @- http://pushgateway.example.org:9091/metrics/job/some_job
管理 API 提供对 Pushgateway 的管理访问,并且必须通过设置--web.enable-admin-api
标志来显式启用。
Pushgateway 监听的默认端口是 9091。路径如下所示:
/api//admin/
HTTP_METHOD | API_版本 | 处理程序 | 描述 |
---|---|---|---|
放 | v1 | 擦拭 | 从 Pushgateway 安全删除所有指标。 |
例如,要擦除 Pushgateway 中的所有指标:
curl -X PUT http://pushgateway.example.org:9091/api/v1/admin/wipe
查询 API 允许访问推送的指标以及构建和运行时信息。
/api//
HTTP_METHOD | API_版本 | 处理程序 | 描述 |
---|---|---|---|
得到 | v1 | 地位 | 以 JSON 格式返回构建信息、命令行标志和开始时间。 |
得到 | v1 | 指标 | 以 JSON 格式返回推送的指标系列。 |
例如 :
curl -X GET http://pushgateway.example.org:9091/api/v1/status | jq
{
"status": "success",
"data": {
"build_information": {
"branch": "master",
"buildDate": "20200310-20:14:39",
"buildUser": "[email protected]",
"goVersion": "go1.13.6",
"revision": "eba0ec4100873d23666bcf4b8b1d44617d6430c4",
"version": "1.1.0"
},
"flags": {
"log.format": "logfmt",
"log.level": "info",
"persistence.file": "",
"persistence.interval": "5m0s",
"push.disable-consistency-check": "false",
"web.enable-admin-api": "false",
"web.enable-lifecycle": "false",
"web.external-url": "",
"web.listen-address": ":9091",
"web.route-prefix": "",
"web.telemetry-path": "/metrics"
},
"start_time": "2020-03-11T01:44:49.9189758+05:30"
}
}
curl -X GET http://pushgateway.example.org:9091/api/v1/metrics | jq
{
"status": "success",
"data": [
{
"labels": {
"job": "batch"
},
"last_push_successful": true,
"my_job_duration_seconds": {
"time_stamp": "2020-03-11T02:02:27.716605811+05:30",
"type": "GAUGE",
"help": "Duration of my batch job in seconds",
"metrics": [
{
"labels": {
"instance": "",
"job": "batch"
},
"value": "0.2721322309989773"
}
]
},
"push_failure_time_seconds": {
"time_stamp": "2020-03-11T02:02:27.716605811+05:30",
"type": "GAUGE",
"help": "Last Unix time when changing this group in the Pushgateway failed.",
"metrics": [
{
"labels": {
"instance": "",
"job": "batch"
},
"value": "0"
}
]
},
"push_time_seconds": {
"time_stamp": "2020-03-11T02:02:27.716605811+05:30",
"type": "GAUGE",
"help": "Last Unix time when changing this group in the Pushgateway succeeded.",
"metrics": [
{
"labels": {
"instance": "",
"job": "batch"
},
"value": "1.5838723477166057e+09"
}
]
}
}
]
}
Pushgateway 提供了一组管理 API 来简化自动化和集成。
HTTP_METHOD | 小路 | 描述 |
---|---|---|
得到 | /-/健康 | 当 Pushgateway 健康时返回 200。 |
得到 | /-/准备好 | 当 Pushgateway 准备好为流量提供服务时,返回 200。 |
--web.enable-lifecycle
标志启用。HTTP_METHOD | 小路 | 描述 |
---|---|---|
放 | /-/辞职 | 触发 Pushgateway 正常关闭。 |
或者,可以通过向 Pushgateway 进程发送SIGTERM
来触发正常关闭。
Pushgateway 通过配置的--web.telemetry-path
(默认值: /metrics
)公开以下指标:
push_time_seconds
和push_failure_time_seconds
,如上所述。process_...
go_...
promhttp_metric_handler_requests_...
# HELP pushgateway_build_info A metric with a constant '1' value labeled by version, revision, branch, and goversion from which pushgateway was built.
# TYPE pushgateway_build_info gauge
pushgateway_build_info{branch="master",goversion="go1.10.2",revision="8f88ccb0343fc3382f6b93a9d258797dcb15f770",version="0.5.2"} 1
# HELP pushgateway_http_push_duration_seconds HTTP request duration for pushes to the Pushgateway.
# TYPE pushgateway_http_push_duration_seconds summary
pushgateway_http_push_duration_seconds{method="post",quantile="0.1"} 0.000116755
pushgateway_http_push_duration_seconds{method="post",quantile="0.5"} 0.000192608
pushgateway_http_push_duration_seconds{method="post",quantile="0.9"} 0.000327593
pushgateway_http_push_duration_seconds_sum{method="post"} 0.001622878
pushgateway_http_push_duration_seconds_count{method="post"} 8
# HELP pushgateway_http_push_size_bytes HTTP request size for pushes to the Pushgateway.
# TYPE pushgateway_http_push_size_bytes summary
pushgateway_http_push_size_bytes{method="post",quantile="0.1"} 166
pushgateway_http_push_size_bytes{method="post",quantile="0.5"} 182
pushgateway_http_push_size_bytes{method="post",quantile="0.9"} 196
pushgateway_http_push_size_bytes_sum{method="post"} 1450
pushgateway_http_push_size_bytes_count{method="post"} 8
# HELP pushgateway_http_requests_total Total HTTP requests processed by the Pushgateway, excluding scrapes.
# TYPE pushgateway_http_requests_total counter
pushgateway_http_requests_total{code="200",handler="static",method="get"} 5
pushgateway_http_requests_total{code="200",handler="status",method="get"} 8
pushgateway_http_requests_total{code="202",handler="delete",method="delete"} 1
pushgateway_http_requests_total{code="202",handler="push",method="post"} 6
pushgateway_http_requests_total{code="400",handler="push",method="post"} 2
一般来说,最好对push_time_seconds
远远落后于预期的情况发出警报。这将捕获失败的推送以及完全关闭的推送器。
要更早地检测失败的推送,请在push_failure_time_seconds > push_time_seconds
上发出警报。
推送也可能会因为格式错误而失败。在这种情况下,它们永远不会到达任何指标组,因此不会设置任何push_failure_time_seconds
指标。这些推送仍计为pushgateway_http_requests_total{code="400",handler="push"}
。您可以对该指标的rate
发出警报,但您必须检查日志以识别有问题的推送程序。
Pushgateway 支持 TLS 和基本身份验证。这可以更好地控制各种 HTTP 端点。
要使用 TLS 和/或基本身份验证,您需要使用--web.config.file
参数传递配置文件。文件的格式在导出工具包存储库中进行了描述。
请注意,TLS 和基本身份验证设置会影响所有 HTTP 端点:用于抓取的 /metrics、通过 /metrics/... 推送指标的 API、通过 /api/... 的管理 API 以及 Web UI。
普通的二进制文件将 Web 文件嵌入到resources
目录中。出于开发目的,让正在运行的二进制文件直接使用这些文件会很方便(这样您就可以立即看到更改的效果)。要切换到直接使用,请将-tags dev
添加到.promu.yml
中的flags
条目,然后make build
。通过恢复对.promu.yml
更改并输入make assets
来切换回“正常”模式。
相关的风格指南是 Go 代码审查注释以及 Peter Bourgon 的《Go:生产环境最佳实践》的格式和风格部分。