# Prometheus 知识学习手册 · 第 3 篇:配置与运维 > 基于 [prometheus.io 官方文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) 整理 > 文档版本:Prometheus v3.15.0(最新稳定版,2026-10 发布)| 抓取日期:2026-10-08 > 数据来源:prometheus/prometheus@v3.15.0、prometheus/alertmanager、prometheus/docs 官方仓库源文件(与官网 latest 内容一致) > > **全册结构(共 4 篇)** > - 第 1 篇:入门与架构 > - 第 2 篇:PromQL 与查询 > - **第 3 篇:配置与运维** ← 本篇 > - 第 4 篇:Alertmanager 与生态(告警、插桩、可视化、规范) --- ## 目录 - [第 1 章 配置全解](#第-1-章-配置全解) - [1.1 配置文件总览与加载方式](#11-配置文件总览与加载方式) - [1.2 通用占位符(Placeholders)](#12-通用占位符placeholders) - [1.3 顶层结构与 `global` 配置](#13-顶层结构与-global-配置) - [1.4 `runtime`:运行时参数](#14-runtime运行时参数) - [1.5 `otlp`:OTLP 接收端配置](#15-otlpotlp-接收端配置) - [1.6 ``:抓取配置全字段](#16-scrape_config抓取配置全字段) - [1.7 relabel 机制详解](#17-relabel-机制详解) - [1.8 ``:HTTP 客户端通用块](#18-http_confighttp-客户端通用块) - [1.9 `` 与 ``](#19-tls_config-与-oauth2) - [1.10 `` 与 ``](#110-remote_write-与-remote_read) - [1.11 `alertmanager_config` 与告警顶层块](#111-alertmanager_config-与告警顶层块) - [1.12 `storage`、`` 与 ``](#112-storagetsdb-与-exemplars) - [1.13 `` 与 `rule_files` / `scrape_configs` 组织](#113-tracing_config-与-rule_files--scrape_configs-组织) - [第 2 章 服务发现](#第-2-章-服务发现) - [第 3 章 规则与模板](#第-3-章-规则与模板) - [第 4 章 CLI 与工具](#第-4-章-cli-与工具) - [第 5 章 安全加固](#第-5-章-安全加固) - [第 6 章 存储](#第-6-章-存储) - [第 7 章 联邦与远程读写](#第-7-章-联邦与远程读写) - [第 8 章 特性开关与迁移](#第-8-章-特性开关与迁移) - [第 9 章 最佳实践](#第-9-章-最佳实践) - [第 10 章 实战教程](#第-10-章-实战教程) - [附录:本篇覆盖清单(URL → 章节对照)](#附录本篇覆盖清单url--章节对照) --- ## 第 1 章 配置全解 Prometheus 的配置分为两部分:**命令行 flag**(不可变参数,例如存储位置、保留量、端口)与**配置文件**(scrape jobs / instances、rule files 等)。配置文件是 YAML 格式,通过 `--config.file` 指定。要查看全部命令行 flag,运行 `./prometheus -h`。 理解配置文件的一个关键心理模型是:**它是「声明式」的抓取与规则蓝图**,Prometheus 会把它编译成内部的 target 列表、relabel 流水线与规则组,并在每次 `reload` 时整体重编译。因此配置的「副作用」都集中在两个时机——进程启动与配置重载。 > 💡 补充:把「不可变 flag」理解为「进程身份」、把「可变配置文件」理解为「工作内容」,能帮助你判断哪些变更需要重启(如 `--storage.tsdb.path`),哪些只需 reload(如 scrape job、规则文件、`global` 大部分字段、`storage.tsdb.retention`)。 ### 1.1 配置文件总览与加载方式 Prometheus 配置**可在运行时重载**,有两种触发方式: | 触发方式 | 说明 | | --- | --- | | 发送 `SIGHUP` | 向 Prometheus 进程发送 `SIGHUP` 信号(Windows 上不支持)。 | | HTTP `POST /-/reload` | 需启用 `--web.enable-lifecycle`;等价于管理 API 的 Reload 端点。 | 重载的关键规则: - 如果新配置**不合法**,则变更**不生效**,进程继续用旧配置运行(这是一道重要的安全阀)。 - 重载配置会**同时重载 rule files**(`rule_files` 中 glob 匹配到的规则文件)。 - 配置文件使用 YAML;schema 说明中的方括号 `[]` 表示可选参数;对非列表参数,若未设置则取指定默认值。 > 💡 补充:生产环境推荐用「CI 先 `promtool check config` 校验 → 再 `POST /-/reload`」的两步流程,避免把不合法配置推到线上。`--config.auto-reload`(默认 `false`)可开启文件变更自动重载,配合 `--config.auto-reload-interval`(默认 `30s`)使用,适合本地开发或配置由工具频繁生成的场景。 ### 1.2 通用占位符(Placeholders) 配置参考用一套占位符描述「值的类型」,理解它们能准确读懂每个字段: | 占位符 | 含义 | | --- | --- | | `` | `true` 或 `false` | | `` | 时长,正则 `((([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?|0)`,如 `1d`、`1h30m`、`5m`、`10s` | | `` | 当前工作目录中的有效路径 | | `` | 浮点数 | | `` | hostname/IP,可带可选端口 | | `` | 整数 | | `` | 匹配 `[a-zA-Z_][a-zA-Z0-9_]*`;不支持字符会转为下划线(如 `app.kubernetes.io/name` → `app_kubernetes_io_name`) | | `` | Unicode 字符串 | | `` | 有效 URL 路径 | | `` | `http` 或 `https` | | `` | 普通字符串(密码等敏感值) | | `` | 普通字符串 | | `` | 字节大小,**单位必需**,支持 `B`、`KB`、`MB`、`GB`、`TB`、`PB`、`EB`(如 `512MB`) | | `` | 使用前会做模板展开的字符串 | > 💡 补充:v3 起指标名与标签名全面支持 UTF-8,`` 的 legacy 字符集限制只在 `metric_name_validation_scheme: legacy` 时生效;默认 `utf8` 下任意 UTF-8 字符串都是合法名称(详见第 5 章 UTF-8 与第 8 章迁移)。 ### 1.3 顶层结构与 `global` 配置 配置文件顶层键如下: ```yaml global: # 全局默认值(同时作为其他配置块的默认) runtime: # 运行时参数 rule_files: # glob 列表:规则文件 scrape_config_files: # glob 列表:追加到 scrape_configs scrape_configs: # 抓取配置列表 alerting: # alert_relabel_configs + alertmanagers remote_write: # 远程写列表 otlp: # OTLP 接收端 remote_read: # 远程读列表 storage: # tsdb + exemplars tracing: # 分布式追踪 ``` #### `global` 字段全表 `global` 中的字段同时充当其他配置块(尤其是 `scrape_config`)的默认值: | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `scrape_interval` | ` \| default = 1m` | 默认抓取间隔 | | `scrape_timeout` | ` \| default = 10s` | 默认抓取超时,**不得大于 scrape interval** | | `scrape_protocols` | `[, ...]` | 抓取协议协商顺序,**大小写敏感**:`PrometheusProto`、`OpenMetricsText0.0.1`、`OpenMetricsText1.0.0`、`PrometheusText0.0.4`、`PrometheusText1.0.0` | | `evaluation_interval` | ` \| default = 1m` | 规则求值间隔 | | `rule_query_offset` | ` \| default = 0s` | 规则求值时间戳回拨量 | | `external_labels` | `{ : ... }` | 对外系统使用的标签;支持环境变量引用 `${var}`/`$var`,未定义变量替换为空串,`$$` 转义 `$` | | `query_log_file` | `` | 查询日志文件路径;重载会重新打开文件 | | `scrape_failure_log_file` | `` | 抓取失败日志文件 | | `body_size_limit` | ` \| default = 0` | 响应体大小上限,`0` 表示无限制(实验特性) | | `sample_limit` | ` \| default = 0` | 每目标每次抓取的样本数上限,`0` 无限制 | | `label_limit` | ` \| default = 0` | 每样本标签数上限 | | `label_name_length_limit` | ` \| default = 0` | 标签名长度上限(UTF-8,字符最多 4 字节) | | `label_value_length_limit` | ` \| default = 0` | 标签值长度上限 | | `target_limit` | ` \| default = 0` | 单 job 目标数上限(实验特性) | | `keep_dropped_targets` | ` \| default = 0` | 保留被丢弃 target 的数量(用于调试 relabel) | | `metric_name_validation_scheme` | ` \| default "utf8"` | 留空或 `utf8` 支持全部 UTF-8;`legacy` 仅允许字母数字冒号下划线 | | `scrape_native_histograms` | ` \| default = false` | 是否摄入原生直方图 | | `convert_classic_histograms_to_nhcb` | ` \| default = false` | 把 classic 直方图转为 NHCB(自定义桶边界的原生直方图) | | `always_scrape_classic_histograms` | ` \| default = false` | 是否总是同时摄入 classic 直方图 | | `extra_scrape_metrics` | ` \| default = false` | 额外存储 `scrape_timeout_seconds`、`scrape_sample_limit`、`scrape_body_size_bytes`,可被单 job 覆盖 | `scrape_protocols` 的默认值取决于 `scrape_native_histograms`: - 当 `scrape_native_histograms = false` 时,默认协商顺序为 `[OpenMetricsText1.0.0, OpenMetricsText0.0.1, PrometheusText1.0.0, PrometheusText0.0.4]`; - 当其为 `true` 时,首位加入 `PrometheusProto`。 **原生直方图三开关的组合语义**(构成一张真值表): | 场景 | `scrape_native_histograms=false` | `scrape_native_histograms=true` | | --- | --- | --- | | CASE 1:端点只暴露 classic 直方图 | 摄入 classic 直方图;原生开关无效果 | 摄入 classic 直方图(或因 `convert_classic_histograms_to_nhcb` 转为 NHCB) | | CASE 2:端点只暴露 native 直方图 | 原生部分被忽略,不摄入 | 按原生直方图摄入 | | CASE 3:端点同时暴露 native + classic | 视同 CASE 1 处理,native 部分被忽略 | 摄入为原生直方图;不生成 NHCB(会冲突);仅当 `always_scrape_classic_histograms=true` 时才**另外**保留 classic 直方图 | > 💡 补充:`external_labels` 支持环境变量展开曾是 feature flag `expand-external-labels`,v3 起已成为默认行为。这一特性常用于让同一份配置在 HA 对的两台 Prometheus 上产生不同标识。 > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.4 `runtime`:运行时参数 | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `log_level` | ` \| default = info` | 进程日志最低级别,**可重载生效** | | `gogc` | ` \| default = 75` | Go GC 的 `GOGC` 参数;**调低会增加 CPU 使用率** | `runtime.log_level` 是替代已废弃命令行 flag `--log.level` 的推荐做法。 > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.5 `otlp`:OTLP 接收端配置 `otlp` 决定 Prometheus 的 OTLP 接收端如何把 OpenTelemetry 的 resource attributes、scope metadata、直方图等翻译成 Prometheus 语义。 | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `promote_resource_attributes` | `[, ...] \| default = []` | 把指定的 resource attributes 提升为标签;**不能**与 `promote_all_resource_attributes: true` 同时配置 | | `promote_all_resource_attributes` | ` \| default = false` | 提升所有 resource attributes(除 `ignore_resource_attributes` 中列出的);属性变化可能导致序列 churn 与高内存 | | `ignore_resource_attributes` | `[, ...] \| default = []` | 忽略哪些 resource attributes,**仅当上项为 `true` 时可用** | | `translation_strategy` | ` \| default = "UnderscoreEscapingWithSuffixes"` | 名称翻译策略,取值见下 | | `keep_identifying_resource_attributes` | ` \| default = false` | 在把 `service.name` 等转为 `instance`/`job` 的同时,额外写入 `target_info` 指标 | | `convert_histograms_to_nhcb` | ` \| default = false` | 把 OTLP 显式桶直方图转为 NHCB | | `promote_scope_metadata` | ` \| default = false` | 把 OTel scope metadata(name、version、schema URL、attributes)提升为指标标签 | | `label_name_underscore_sanitization` | ` \| default = true` | 对以 `_` 开头的标签名前缀 `key_`;保留标签(`__` 开头)不修改 | | `label_name_preserve_multiple_underscores` | ` \| default = true` | 在 underscore escaping 下保留连续下划线 | `translation_strategy` 的取值: | 取值 | 语义 | | --- | --- | | `UnderscoreEscapingWithSuffixes` | OpenTelemetry 社区通用规范化(下划线替换 + 追加单位/`_total` 后缀) | | `NoUTF8EscapingWithSuffixes` | 依赖 Prometheus UTF-8 支持,保留点等特殊字符,但仍追加单位/`_total` 后缀 | | `UnderscoreEscapingWithoutSuffixes` | 非法字符转下划线,但**不**追加任何后缀 | | `NoTranslation`(实验) | 依赖 UTF-8 支持,保留特殊字符且不追加单位/类型后缀;有已知风险(PromQL 可读性下降、序列冲突) | > 💡 补充:`NoTranslation` 的风险在于「同名不同单位」的指标会冲突(例如 `foo.bar` 秒 与 `foo.bar` 毫秒),这是它被标为实验且需要谨慎的原因。 > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.6 ``:抓取配置全字段 `job_name` 在**所有 scrape config 中必须唯一**。下面按「基础设置 → 服务发现 → relabel → 限额」的顺序给出全字段表。 #### 基础与请求设置 | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `job_name` | `` | **必填**;该 job 的唯一名称,同时作为 `job` 标签 | | `scrape_interval` | ` \| default = ` | 抓取间隔 | | `scrape_timeout` | ` \| default = ` | 抓取超时,不得大于 scrape interval | | `scrape_protocols` | `[, ...] \| default = ` | 协议协商顺序,默认由 `scrape_native_histograms` 决定 | | `fallback_scrape_protocol` | `` | 当目标返回的 `Content-Type` 非法时的回退协议 | | `metrics_path` | ` \| default = /metrics` | 抓取路径 | | `honor_labels` | ` \| default = false` | `true` 保留抓取数据中的标签;`false` 时冲突标签改名 `exported_` | | `honor_timestamps` | ` \| default = true` | 是否采用目标暴露的时间戳 | | `track_timestamps_staleness` | ` \| default = false` | 是否按目标时间戳跟踪 staleness | | `scheme` | ` \| default = http` | 协议 | | `params` | `{ : [, ...] }` | 请求参数(如 federation 的 `match[]`) | | `enable_compression` | ` \| default = true` | 是否对响应启用压缩 | | `scrape_failure_log_file` | `` | 抓取失败日志文件 | | `[ ]` | HTTP 客户端块 | 见 1.8 节 | #### 服务发现块(均为列表 `[ - ... ]`) `aws_sd_configs`、`azure_sd_configs`、`consul_sd_configs`、`digitalocean_sd_configs`、`docker_sd_configs`、`dockerswarm_sd_configs`、`dns_sd_configs`、`ec2_sd_configs`、`eureka_sd_configs`、`file_sd_configs`、`gce_sd_configs`、`hetzner_sd_configs`、`http_sd_configs`、`ionos_sd_configs`、`kubernetes_sd_configs`、`kuma_sd_configs`、`lightsail_sd_configs`、`linode_sd_configs`、`marathon_sd_configs`、`nerve_sd_configs`、`nomad_sd_configs`、`oci_sd_configs`、`openstack_sd_configs`、`outscale_sd_configs`、`ovhcloud_sd_configs`、`puppetdb_sd_configs`、`scaleway_sd_configs`、`serverset_sd_configs`、`stackit_sd_configs`、`triton_sd_configs`、`uyuni_sd_configs`、`vultr_sd_configs`。 各 SD 的字段与 meta 标签详见 **第 2 章**。 #### 静态目标与 relabel | 字段 | 类型 | 说明 | | --- | --- | --- | | `static_configs` | `[ - ... ]` | 静态目标列表 | | `relabel_configs` | `[ - ... ]` | **target** relabel,作用于服务发现结果、决定抓取与目标标签 | | `metric_relabel_configs` | `[ - ... ]` | **metric** relabel,作用于入库前的样本 | #### 限额与高级设置 | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `body_size_limit` | ` \| default = 0` | 响应体上限,`0` 无限制 | | `sample_limit` | ` \| default = 0` | 样本数上限(经 metric relabel 后仍未超过才入库) | | `label_limit` | ` \| default = 0` | 每样本标签数上限 | | `label_name_length_limit` | ` \| default = 0` | 标签名长度上限 | | `label_value_length_limit` | ` \| default = 0` | 标签值长度上限 | | `target_limit` | ` \| default = 0` | 目标数上限 | | `keep_dropped_targets` | ` \| default = 0` | 保留被丢弃 target 数量 | | `metric_name_validation_scheme` | ` \| default "utf8"` | 名称校验方案 | | `metric_name_escaping_scheme` | ` \| default "allow-utf-8"` | 转义方案:`allow-utf-8` / `underscores` / `dots` / `values`;留空时按 validation scheme 推断 | | `native_histogram_bucket_limit` | ` \| default = 0` | 原生直方图桶数上限 | | `native_histogram_min_bucket_factor` | ` \| default = 0` | 原生直方图最小桶增长因子 | | `scrape_native_histograms` | ` \| default = ` | 覆盖全局原生直方图开关 | | `convert_classic_histograms_to_nhcb` | ` \| default = ` | 覆盖全局 NHCB 转换开关 | | `always_scrape_classic_histograms` | ` \| default = ` | 覆盖全局 classic 直方图开关 | | `extra_scrape_metrics` | ` \| default = ` | 覆盖全局额外抓取指标开关 | **`native_histogram_min_bucket_factor` 与 schema 的对照表**(增长因子 ↔ 分辨率 schema): | 增长因子(growth factor) | schema | | --- | --- | | 65536 | -4 | | 256 | -3 | | 16 | -2 | | 4 | -1 | | 2 | 0 | | 1.4 | 1 | | 1.1 | 2 | | 1.09 | 3 | | 1.04 | 4 | | 1.02 | 5 | | 1.01 | 6 | | 1.005 | 7 | | 1.002 | 8 | > 💡 补充:`metric_name_escaping_scheme` 的 `dots` / `values` 是为「与 legacy Prometheus 之间往返 UTF-8 名称」设计的;`dots` 允许含点的简单指标名往返,`values` 允许完整往返。 **``**: ```yaml targets: [ - '' ] labels: { : ... } ``` `static_config` 中可用特殊标签(如 `__scheme__`、`__metrics_path__`)覆盖 scrape config 中的对应设置。 > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.7 relabel 机制详解 relabel 是 Prometheus 配置中最强大也最容易被误解的机制。它是一条**按出现顺序**依次执行的规则流水线,每条规则从标签集里取值、用正则匹配、再决定「改写、保留、丢弃」。 **执行时机与标签空间**: - 初始时 `job` 标签会被设为 `job_name`。 - relabel 期间可用的特殊标签:`__address__`、`__scheme__`、`__metrics_path__`、`__scrape_interval__`、`__scrape_timeout__`、`__convert_classic_histograms_to_nhcb__`、`__always_scrape_classic_histograms__`、`__scrape_native_histograms__`、`__unix_socket__`、`__param_`。 - `__address__` 为 `:`;relabel 完成后 `instance` 标签默认取 `__address__`。 - `__meta_*` 标签由服务发现机制提供;以 `__` 开头的标签在 target relabel 完成后**被移除**。 - 临时值用 `__tmp` 前缀(Prometheus 保证自己绝不使用该前缀)。 **`` 字段**: ```yaml # 从序列中取哪些标签;不存在的标签取空串 ""。 # 其内容用 separator 拼接,再与 regex 匹配(适用于 replace/keep/drop)。 [ source_labels: '[' [, ...] ']' ] # 拼接 source label 值之间使用的分隔符。 [ separator: | default = ; ] # replace 动作中结果写入的标签名(replace 动作必需)。支持正则捕获组。 [ target_label: ] # 用于匹配提取值的正则表达式。 [ regex: | default = (.*) ] # 对 source label 值哈希后取模的模数。 [ modulus: ] # 正则匹配时执行的替换值,支持捕获组。 [ replacement: | default = $1 ] # 基于正则匹配要执行的动作。 [ action: | default = replace ] ``` `` 是任意合法的 **RE2** 正则;对 `replace`、`keep`、`drop`、`labelmap`、`labeldrop`、`labelkeep` 动作**必需**。正则**两端自动锚定**;要取消锚定,写成 `.*.*`。 **`` 全部取值**: | 动作 | 语义 | | --- | --- | | `replace` | 用 `regex` 匹配拼接后的 `source_labels`;若匹配,把 `target_label` 设为 `replacement`(`${1}`、`${2}`… 被捕获组替换)。不匹配则不做替换 | | `lowercase` | 把拼接后的 `source_labels` 映射为小写 | | `uppercase` | 把拼接后的 `source_labels` 映射为大写 | | `keep` | 丢弃「`regex` 不匹配拼接后 `source_labels`」的目标 | | `drop` | 丢弃「`regex` 匹配拼接后 `source_labels`」的目标 | | `keepequal` | 丢弃「拼接后 `source_labels` 与 `target_label` 不相等」的目标 | | `dropequal` | 丢弃「拼接后 `source_labels` 与 `target_label` 相等」的目标 | | `hashmod` | 把 `target_label` 设为拼接后 `source_labels` 哈希的 `modulus` 取模值(常用于分片) | | `labelmap` | 用 `regex` 匹配**所有标签名**(不限于 `source_labels`),把匹配标签的值复制到 `replacement` 指定的新标签名 | | `labeldrop` | 用 `regex` 匹配所有标签名,**删除**匹配的标签 | | `labelkeep` | 用 `regex` 匹配所有标签名,**删除不匹配**的标签 | > 💡 补充/注意事项:使用 `labeldrop` 与 `labelkeep` 时务必确保删除标签后指标仍**唯一标识**——否则不同序列会撞成同一标签集,引发重复样本错误。调试 relabel 时,把 `keep_dropped_targets` 设为正数可在 UI 中看到被丢弃的目标及其原因。 **`` 与 ``**: - 两者格式与动作与 target relabel 完全相同。 - **metric relabel** 在样本**入库前的最后一步**应用,因此**不作用于** `up` 等自动生成的序列;典型用途是丢弃过于昂贵的序列。 - **alert relabel** 在告警发往 Alertmanager **之前**应用,且在 `external_labels` **之后**;典型用途是让带不同 external labels 的 HA 对发出完全一致的告警。 > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.8 ``:HTTP 客户端通用块 `` 是抓取目标、remote write/read、Alertmanager 连接等所有「Prometheus 主动发起 HTTP 请求」场景的通用配置块。 | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `basic_auth` | 块 | HTTP Basic 认证:`username` / `username_file`(互斥)、`password` / `password_file`(互斥) | | `authorization` | 块 | `type: \| default: Bearer`、`credentials` 与 `credentials_file`(互斥) | | `oauth2` | `[ ]` | OAuth 2.0 认证;**不能**与 `basic_auth` 或 `authorization` 同时使用 | | `follow_redirects` | ` \| default = true` | 是否跟随重定向 | | `enable_http2` | ` \| default: true` | 是否启用 HTTP/2 | | `tls_config` | `[ ]` | TLS 配置 | | `proxy_url` | `` | 代理 URL | | `no_proxy` | `` | 逗号分隔、不走代理的 IP/CIDR/域名,可带端口 | | `proxy_from_environment` | ` \| default: false` | 读取 `HTTP_PROXY`/`HTTPS_PROXY`/`NO_PROXY`(及小写) | | `proxy_connect_header` | `{ : [, ...] }` | CONNECT 请求头 | | `http_headers` | `: { values: [...], secrets: [...], files: [...] }` | 注入到每个请求的头部;Prometheus 自身设置的 header **不可覆盖** | > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.9 `` 与 `` #### ``(客户端侧) | 字段 | 说明 | | --- | --- | | `ca` / `ca_file` | 用于校验服务端证书的 CA(最多设置一个) | | `cert` / `cert_file` | 客户端证书(最多一个) | | `key` / `key_file` | 客户端私钥(最多一个) | | `server_name` | ``,ServerName 扩展 | | `insecure_skip_verify` | ``,跳过服务端证书校验 | | `min_version` | ``,`TLS10`/`TLS11`/`TLS12`/`TLS13`;未设置时用 Go 默认最低版本 TLS 1.2 | | `max_version` | ``,取值同上;未设置时用 Go 默认最高版本 TLS 1.3 | #### `` | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `client_id` | `` | 客户端 ID | | `grant_type` | `` | `client_credentials` 或 `urn:ietf:params:oauth:grant-type:jwt-bearer`(RFC 7523);默认 `client_credentials` | | `client_secret` / `client_secret_file` | 互斥 | 客户端密钥 | | `client_certificate_key` / `client_certificate_key_file` | 互斥 | 客户端证书密钥 | | `client_certificate_key_id` | `` | 证书密钥 ID | | `signature_algorithm` | `` | 默认 `RS256`;可选 `RS256`/`RS384`/`RS512` | | `iss` | `` | 默认等于 `client_id` | | `audience` | `` | 为空时使用 `TokenURL` | | `claims` | `{ : ... }` | 自定义 claims | | `scopes` | `[ - ... ]` | 申请的 scope | | `token_url` | `` | 获取 token 的 URL | | `endpoint_params` | `{ : ... }` | 追加到 token URL 的参数(可用 `grant_type`/`username`/`password` 启用 password 模式) | | `tls_config` | 块 | 令牌请求的 TLS 设置 | | `proxy_url` / `no_proxy` / `proxy_from_environment` / `proxy_connect_header` | 见 1.8 节 | 代理相关 | > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.10 `` 与 `` #### `` | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `url` | `` | **必填**,远端写入地址 | | `protobuf_message` | ` \| default = prometheus.WriteRequest` | 消息类型 | | `remote_timeout` | ` \| default = 30s` | 请求超时 | | `headers` | `{ : ... }` | 附加请求头 | | `write_relabel_configs` | `[ - ... ]` | 写前 relabel,在 external labels 之后应用 | | `name` | `` | 唯一名称(用于区分多个 remote write 队列) | | `send_exemplars` | ` \| default = false` | 是否发送 exemplars | | `send_native_histograms` | ` \| default = false` | 是否发送原生直方图;v2 消息下恒为 `true` | | `round_robin_dns` | ` \| default = false` | 对 DNS 结果轮询(实验) | | `sigv4` | 块 | AWS 签名;与 `basic_auth`/`authorization`/`oauth2`/`azuread` 互斥(详见下方) | | `azuread` | 块 | Azure AD 认证 | | `google_iam` | 块 | Google Cloud IAM;**警告**:Google Cloud 不支持 remote write,保留供将来使用 | | `queue_config` | 块 | 发送队列参数(见下表) | | `metadata_config` | 块 | metadata 发送参数(见下表) | | `` | 块 | 注意:在 remote write 下 `enable_http2` **默认 `false`** | **`sigv4`**:`region`、`access_key`、`secret_key`、`profile`、`role_arn`、`external_id`、`session_name`(≥3.15.0,pattern `^[\w+=,.@-]{2,64}$`)、`tags`(≥3.15.0)、`service_name`、`use_fips_sts_endpoint: | default = false`(≥2.54.0);与 `basic_auth`/`authorization`/`oauth2`/`azuread`/`google_iam` 互斥;使用默认凭据写 `sigv4: {}`。 **`azuread`**:`cloud: AzurePublic|AzureChina|AzureGovernment`(默认 `AzurePublic`);`managed_identity.client_id`;`workload_identity`(`client_id`/`tenant_id`/`token_file_path` 默认 `/var/run/secrets/azure/tokens/azure-identity-token`);`oauth`;`certificate`(`client_id`/`tenant_id`/`certificate_path`/`certificate_key_path`/`certificate_password`/`send_certificate_chain: false`);`sdk.tenant_id`;`scope`。 **`queue_config`**: | 字段 | 默认值 | 说明 | | --- | --- | --- | | `capacity` | `10000` | 每 shard 内存队列容量 | | `max_shards` | `50` | 最大 shard 数(并行度) | | `min_shards` | `1` | 最小 shard 数 | | `max_samples_per_send` | `2000` | 单次发送的最大样本数 | | `batch_send_deadline` | `5s` | 两次发送之间的最大等待时长 | | `min_backoff` | `30ms` | 重试最小退避 | | `max_backoff` | `5s` | 重试最大退避 | | `retry_on_http_429` | `false` | 是否对 HTTP 429 重试 | | `sample_age_limit` | `0s` | 样本新旧上限,超龄样本丢弃 | **`metadata_config`**:`send: true`、`send_interval: 1m`、`max_samples_per_send: 2000`。 #### `` | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `url` | `` | **必填** | | `name` | `` | 唯一名称 | | `required_matchers` | `{ : ... }` | 仅在查询匹配这些标签时才发往远端 | | `remote_timeout` | ` \| default = 1m` | 请求超时 | | `headers` | `{ : ... }` | 附加请求头 | | `read_recent` | ` \| default = false` | 是否也读取本地最近数据之外的部分 | | `filter_external_labels` | ` \| default = true` | 远端读取时是否过滤 external labels | | `` | 块 | HTTP 客户端块 | > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.11 `alertmanager_config` 与告警顶层块 告警相关配置位于顶层 `alerting` 下: ```yaml alerting: alert_relabel_configs: [ - ... ] alertmanagers: [ - ... ] ``` **`` 字段**: | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `timeout` | ` \| default = 10s` | 推送告警的每目标超时 | | `api_version` | ` \| default = v2` | Alertmanager API 版本(v3 不再支持 v1) | | `path_prefix` | ` \| default = /` | 推送告警的 HTTP 路径前缀 | | `scheme` | ` \| default = http` | 协议 | | `sigv4` | 块 | AWS 签名(字段同 remote_write 的 `sigv4`) | | `` | 块 | HTTP 客户端块 | | 各 `*_sd_configs` | 列表 | 服务发现(含 `vultr_sd_configs` 等) | | `static_configs` | 列表 | 静态 Alertmanager 目标 | | `relabel_configs` | 列表 | target relabel | | `alert_relabel_configs` | 列表 | 告警 relabel | 可用 `__alerts_path__` 标签改写告警推送的 API 路径。 > 💡 补充:Alertmanager 的连接配置同样支持通过 SD 自动发现实例,这样在 Alertmanager 集群扩缩容时无需手改 Prometheus 配置。 > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.12 `storage`、`` 与 `` `storage` 块可运行时重载: ```yaml storage: [ tsdb: ] [ exemplars: ] ``` **`` 字段**: | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `out_of_order_time_window` | ` \| default = 0s` | 乱序样本可接受的时间窗;`>0` 时错误合并为 `too-old` | | `stale_series_compaction_threshold` | ` \| default = 0` | 内存中 stale 序列占比阈值(0~1);`0` 禁用;实验特性 | | `chunk_encoding` | `{ floats: }` | float chunk 编码:`xor` 或 `xor2`;缺省在开启 `xor2-encoding`/`st-storage` 时为 `xor2`,否则 `xor`;**运行时可变** | | `retention.time` | `` | 保留时长;未设置且无 size 时默认 `15d`;取值优先于已废弃 flag `--storage.tsdb.retention.time`;设 `0` 禁用 | | `retention.size` | ` \| default = 0` | 保留的最大字节数;需单位;优先于已废弃 flag `--storage.tsdb.retention.size`;`0` 禁用 | | `retention.percentage` | ` \| default = 0` | 保留的最大磁盘百分比(实验);Prometheus 启动时若无法查询总容量会失败;`0` 禁用 | > 💡 补充:保留策略在运行时变更会**立即更新设置**,但基于新策略的 block 删除发生在**下一次 block reload 周期**(1 分钟内或某次 compaction 完成时,取先到者)。同时设置 `time` 与 `size` 时,**谁先触发就用谁**。 **``**:需 `--enable-feature=exemplar-storage` 才生效。 | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `max_exemplars` | ` \| default = 100000` | 环形缓冲区中为所有序列存储的 exemplar 上限;**运行时可变** | > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 1.13 `` 与 `rule_files` / `scrape_configs` 组织 **`tracing_config`**(实验特性,把 Prometheus 的 trace 通过 OTLP 协议导出到追踪后端): | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `client_type` | ` \| default = grpc` | `http` 或 `grpc` | | `endpoint` | `` | 目标地址,格式 `:` | | `sampling_fraction` | ` \| default = 0` | 采样概率,取值 0~1 | | `insecure` | ` \| default = false` | 为 `false` 时使用安全连接 | | `headers` | `{ : ... }` | 附加到 gRPC/HTTP 请求的头部 | | `compression` | `` | 支持的压缩类型:`gzip` | | `timeout` | ` \| default = 10s` | 每批导出的最大等待时长 | | `tls_config` | 块 | TLS 配置 | 若同时开启 query log 与 tracing,会向 query log 注入 `traceID` 与 `spanID`,便于日志/追踪关联。 **`rule_files` 与 `scrape_configs` 的组织**: ```yaml # 规则文件:glob 列表,所有匹配文件中的 rules 都会被读取。 rule_files: [ - ... ] # 抓取配置文件:glob 列表,匹配文件中的 scrape configs 会追加到 scrape_configs。 scrape_config_files: [ - ... ] # 抓取配置列表。 scrape_configs: [ - ... ] ``` > 💡 补充:`scrape_config_files` 允许把各个团队的抓取配置拆成独立文件、由不同流程生成,再通过 glob 汇总,这对多团队协作的大型部署非常实用——它与 `rule_files` 使用相同的 glob 合并语义。 > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) --- ## 第 2 章 服务发现 服务发现(Service Discovery,SD)解决的是「**目标从哪里来**」的问题。静态配置(`static_configs`)只适合目标固定的场景;一旦基础设施是动态的(容器编排、云主机、注册中心),就需要 SD 自动产出 target 列表。Prometheus 的 SD 机制统一遵循一个模型:**发现 → 产出带 `__meta_*` 标签的目标 → 经 `relabel_configs` 塑形 → 变成真正被抓取的 `__address__`**。 ### 2.1 SD 总览表(全部 `*_sd_config` 类型一览) 所有 SD 块都写在对应 `` 的 `*_sd_configs` 字段下,均为列表形式 `[ - ... ]`。 | SD 块 | 目标系统 | 关键必填字段 | meta 标签前缀 | | --- | --- | --- | --- | | `aws_sd_config` | AWS 统一 SD(`role` 决定子角色) | `role` | 依 role 而定(`__meta_ec2_*`、`__meta_lightsail_*`、`__meta_ecs_*`、`__meta_msk_*`、`__meta_elasticache_*`、`__meta_rds_*`) | | `azure_sd_config` | Microsoft Azure | `subscription_id` | `__meta_azure_*` | | `consul_sd_config` | HashiCorp Consul | — | `__meta_consul_*` | | `digitalocean_sd_config` | DigitalOcean | — | `__meta_digitalocean_*` | | `docker_sd_config` | Docker Engine | `host` | `__meta_docker_*` | | `dockerswarm_sd_config` | Docker Swarm | `host`、`role` | `__meta_dockerswarm_*` | | `dns_sd_config` | DNS(SRV/A/AAAA/MX/NS) | `names` | `__meta_dns_*` | | `ec2_sd_config` | AWS EC2(独立) | — | `__meta_ec2_*` | | `eureka_sd_config` | Netflix Eureka | `server` | `__meta_eureka_*` | | `file_sd_config` | 本地 JSON/YAML 文件 | `files` | `__meta_filepath` | | `gce_sd_config` | Google Compute Engine | `project`、`zone` | `__meta_gce_*` | | `hetzner_sd_config` | Hetzner | `role` | `__meta_hetzner_*` | | `http_sd_config` | 任意 HTTP 端点 | `url` | `__meta_url` | | `ionos_sd_config` | IONOS Cloud | `datacenter_id` | `__meta_ionos_*` | | `kubernetes_sd_config` | Kubernetes | `role` | `__meta_kubernetes_*` | | `kuma_sd_config` | Kuma | `server` | `__meta_kuma_*` | | `lightsail_sd_config` | AWS Lightsail | — | `__meta_lightsail_*` | | `linode_sd_config` | Linode | — | `__meta_linode_*` | | `marathon_sd_config` | Mesos Marathon | `servers` | `__meta_marathon_*` | | `nerve_sd_config` | Airbnb Nerve | `servers`、`paths` | `__meta_nerve_*` | | `nomad_sd_config` | HashiCorp Nomad | — | `__meta_nomad_*` | | `oci_sd_config` | Oracle Cloud | `region` | `__meta_oci_*` | | `openstack_sd_config` | OpenStack | `role`、`region` | `__meta_openstack_*` | | `outscale_sd_config` | Outscale | `access_key` | `__meta_outscale_*` | | `ovhcloud_sd_config` | OVHcloud | — | `__meta_ovhcloud_*` | | `puppetdb_sd_config` | PuppetDB | `url`、`query` | `__meta_puppetdb_*` | | `scaleway_sd_config` | Scaleway | `access_key`、`project_id`、`role` | `__meta_scaleway_*` | | `serverset_sd_config` | Airbnb Serverset | `servers`、`paths` | `__meta_serverset_*` | | `stackit_sd_config` | STACKIT | `project` | `__meta_stackit_*` | | `triton_sd_config` | Triton | `account`、`dns_suffix`、`endpoint` | `__meta_triton_*` | | `uyuni_sd_config` | Uyuni | `server` | `__meta_uyuni_*` | | `vultr_sd_config` | Vultr | — | `__meta_vultr_*` | > 💡 补充:SD 集成在 Prometheus 3.x 的稳定性保证中属于**不稳定**特性——除 `static_configs`、`file_sd_configs` 和 `http_sd_config` 外,其它 SD 集成可能随版本变更。选型时应优先考虑 `file_sd` 与 `http_sd` 这类更稳定的通用接口。 > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) ### 2.2 file_sd:基于文件的服务发现 `` 从本地文件读取目标,是「Prometheus 原生不支持某套 SD 系统」时的通用兜底方案。 | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `files` | `[ - ... ]` | 文件路径模式列表 | | `refresh_interval` | ` \| default = 5m` | 刷新间隔 | 文件格式要求: - 模式需以 `.json`、`.yml` 或 `.yaml` 结尾;**最后一段路径**可包含单个 `*` 通配符。 - 支持 JSON 与 YAML 两种格式。 - 每个 target 会带上 `__meta_filepath` 标签,指向其来源文件。 **`file_sd` 目标文件结构示例**: ```json [ { "labels": { "job": "node" }, "targets": [ "localhost:9100" ] } ] ``` #### 实践指南:用 file-based SD 发现抓取目标 官方指南流程如下:本地运行 Node Exporter(监听 9100 端口,用 `curl http://localhost:9100/metrics` 验证),然后让 Prometheus 通过 `targets.json` 发现它。 Prometheus 配置(替换解压目录中的 `prometheus.yml`): ```yaml scrape_configs: - job_name: 'node' file_sd_configs: - files: - 'targets.json' ``` 创建 `targets.json`(内容即上面示例)。启动 `./prometheus` 后,在 expression browser 中用 `up{job="node"}` 可确认 Node Exporter 被正确发现。 **动态修改 targets 列表**:file-based SD 下 Prometheus 会监听文件变化并**自动更新** scrape target 列表,**无需重启实例**。例如再启动一个监听 9200 端口的 Node Exporter: ```bash ./node_exporter --web.listen-address=":9200" ``` 向 `targets.json` 增加第二个条目后保存,`up{job="node"}` 应显示两个实例,`instance` 标签分别为 `localhost:9100` 与 `localhost:9200`。 > 💡 补充:官方提示本指南为简洁起见手动编辑 JSON;**生产环境应使用某种 JSON 生成流程或工具**(如由 CMDB、Ansible、配置管理客户端定期渲染该文件),直接把 `file_sd` 当作「工具产出接口」使用。 > 引自:[Use file-based service discovery to discover scrape targets](https://prometheus.io/docs/guides/file-sd/) ### 2.3 http_sd:基于 HTTP 的服务发现 HTTP SD 通过 HTTP 端点发现 targets,是对既有 SD 机制的补充,也是 **File-based SD 的替代方案**。它最适合「已有服务能通过 HTTP 动态提供目标列表」的场景。 #### file_sd 与 http_sd 对比 | 维度 | File SD | HTTP SD | | --- | --- | --- | | 事件驱动(Event Based) | 是,通过 inotify | 否 | | 更新频率 | 即时(得益于 inotify) | 跟随 `refresh_interval` | | 格式 | YAML 或 JSON | JSON | | 传输方式 | 本地文件 | HTTP/HTTPS | | 安全 | 依赖文件系统权限 | TLS、Basic auth、Authorization header、OAuth2 | #### 端点协议要求 - 响应按原样消费,不做修改。 - 每个 refresh interval(默认 1 分钟)Prometheus 对 SD 端点执行一次 GET 请求。 - GET 请求会带 HTTP 头 `X-Prometheus-Refresh-Interval-Seconds`,值为 refresh interval。 - 端点**必须**返回 HTTP 200,且 `Content-Type: application/json`;响应必须为 UTF-8。 - 若无 targets 要发送,也必须返回 HTTP 200 与空列表 `[]`;target 列表**无序**。 - Prometheus 会缓存 target 列表;刷新出错时继续使用当前列表;列表**不跨重启保存**。 - 指标 `prometheus_sd_refresh_failures_total` 计数刷新失败次数;`prometheus_sd_refresh_duration_seconds` 用于跟踪 HTTP SD 刷新尝试或性能;配置重载后底层 scrape job 消失时这些指标被移除。 - 每次请求必须返回**完整** target 列表,**不支持增量更新**。 - Prometheus 实例**不发送 hostname**,SD 端点无法得知请求是否为重启后的首次请求。 - HTTP SD 的 URL **不视为 secret**;认证与 API key 应通过适当机制传递——Prometheus 支持 TLS authentication、basic authentication、OAuth2 与 authorization headers。 #### HTTP SD 格式 ```json [ { "targets": [ "", ... ], "labels": { "": "", ... } }, ... ] ``` 示例: ```json [ { "targets": ["10.0.10.2:9100", "10.0.10.3:9100", "10.0.10.4:9100", "10.0.10.5:9100"], "labels": { "__meta_datacenter": "london", "__meta_prometheus_job": "node" } } ] ``` > 💡 补充:`http_sd_config` 的字段为 `url`(必填)、`refresh_interval`(默认 `60s`)与 ``;每个 target 会带 `__meta_url` 标签,指向其来源端点。由于「不发送 hostname」「不支持增量」这两点,若你的 SD 服务需要在重启后重建状态,应让其**无状态**或自行持久化。 > 引自:[Writing HTTP service discovery](https://prometheus.io/docs/prometheus/latest/http_sd/) ### 2.4 docker_sd 与 dockerswarm #### `` | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `host` | `` | **必填**,Docker daemon 地址(如 `unix:///var/run/docker.sock`) | | `port` | ` \| default = 80` | 目标端口 | | `host_networking_host` | ` \| default = "localhost"` | host 网络模式下的主机名 | | `match_first_network` | ` \| default = true` | 匹配第一个网络 | | `filters` | `[ - name, values ]` | Docker 过滤器 | | `refresh_interval` | ` \| default = 60s` | 刷新间隔 | | `` | 块 | HTTP 客户端块 | meta 标签前缀为 `__meta_docker_*`。 #### `` 自 v2.20.0 起,Prometheus 可在 Docker Swarm 集群中发现 targets。 | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `host` | `` | **必填**,Docker daemon 地址 | | `role` | `` | **必填**,`services` / `tasks` / `nodes` | | `port` | ` \| default = 80` | 目标端口 | | `filters` | `[ - name, values ]` | Docker 过滤器 | | `refresh_interval` | ` \| default = 60s` | 刷新间隔 | | `` | 块 | HTTP 客户端块 | meta 标签前缀为 `__meta_dockerswarm_*`。 #### 指南:Docker Swarm 三种角色 Docker Swarm 服务发现含 3 种角色: - **nodes**:Swarm 中的主机,可用于自动监控 Docker daemons 或 Swarm 主机上的 Node Exporter。 - **tasks**:Swarm 中部署的单个容器,每个 task 带其关联的 service labels;一个 service 可由一个或多个 task 支撑。 - **services**:发现部署的 services 及其暴露端口;**通常应改用 tasks 角色**。 Prometheus **只发现暴露端口的** tasks 与 services。 **监控 Docker daemons(nodes 角色)**。先编辑 `/etc/docker/daemon.json` 并重启 daemon: ```json { "metrics-addr" : "0.0.0.0:9323", "experimental" : true } ``` (也可用节点 IP 替代 `0.0.0.0`。)然后配置: ```yaml scrape_configs: # Make Prometheus scrape itself for metrics. - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] # Create a job for Docker daemons. - job_name: 'docker' dockerswarm_sd_configs: - host: unix:///var/run/docker.sock role: nodes relabel_configs: # Fetch metrics on port 9323. - source_labels: [__meta_dockerswarm_node_address] target_label: __address__ replacement: $1:9323 # Set hostname as instance label - source_labels: [__meta_dockerswarm_node_hostname] target_label: instance ``` 对 nodes 角色也可用 `dockerswarm_sd_configs` 的 `port` 参数;但**推荐用 `relabel_configs`**,因为可在相同 Docker Swarm 配置间复用相同 API 调用。 **监控容器(tasks 角色)**。部署 cadvisor: ```shell docker service create --name cadvisor -l prometheus-job=cadvisor \ --mode=global --publish target=8080,mode=host \ --mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock,ro \ --mount type=bind,src=/,dst=/rootfs,ro \ --mount type=bind,src=/var/run,dst=/var/run \ --mount type=bind,src=/sys,dst=/sys,ro \ --mount type=bind,src=/var/lib/docker,dst=/var/lib/docker,ro \ google/cadvisor -docker_only ``` Prometheus 配置与逐段解释: ```yaml scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'dockerswarm' dockerswarm_sd_configs: - host: unix:///var/run/docker.sock role: tasks relabel_configs: # Only keep containers that should be running. - source_labels: [__meta_dockerswarm_task_desired_state] regex: running action: keep # Only keep containers that have a `prometheus-job` label. - source_labels: [__meta_dockerswarm_service_label_prometheus_job] regex: .+ action: keep # Use the prometheus-job Swarm label as Prometheus job label. - source_labels: [__meta_dockerswarm_service_label_prometheus_job] target_label: job ``` - `__meta_dockerswarm_task_desired_state` + `regex: running` + `action: keep`:只保留应运行的 targets(避免监控应关闭的 tasks)。 - `__meta_dockerswarm_service_label_prometheus_job` + `regex: .+` + `keep`:只保留带 `prometheus-job` 标签的 targets。 - 最后一条把 task 的 `prometheus-job` 标签转成 target label,**覆盖**来自 scrape config 的默认 `dockerswarm` job 标签。 其他有用的 relabel: | 目标 | relabel 条件 | | --- | --- | | 仅通过某网络抓取 | `__meta_dockerswarm_network_name` + `regex: ingress` + `keep` | | 仅抓取 global tasks | `__meta_dockerswarm_service_mode` + `regex: global` + `keep`,配合 `__meta_dockerswarm_task_port_publish_mode` + `regex: host` + `keep` | | 加 `docker_node` 标签 | `__meta_dockerswarm_node_hostname` → `target_label: docker_node` | 连接方式:`host: unix:///var/run/docker.sock` 用 Docker socket;Prometheus 也提供 HTTP、HTTPS 的额外配置选项连接 Swarm。 > 💡 补充:tasks 有 **25 个以上**标签可用;可在 Prometheus「Status」菜单下的「Service Discovery」页查看所有发现标签。服务发现不对 Swarm stack 做任何假设,配置正确即可插拔到任意现有 stack。 > 引自:[Docker Swarm](https://prometheus.io/docs/guides/dockerswarm/) ### 2.5 其他主要 SD 要点 以下集中列出配置参考中各 SD 块的字段与 meta 标签,完整覆盖「字段名、默认值、meta 前缀」。 #### `aws_sd_config`(统一 AWS SD,`role` 决定子角色) | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `role` | `` | `ec2` / `lightsail` / `ecs` / `msk` / `elasticache` / `rds` | | `region` | `` | 区域 | | `endpoint` | `` | 自定义端点 | | `access_key` / `secret_key` | `` | 静态凭据 | | `profile` | `` | AWS profile | | `role_arn` / `external_id` | `` | 跨账号 AssumeRole | | `refresh_interval` | ` \| default = 60s` | 刷新间隔 | | `port` | ` \| default = 80` | 目标端口 | | `filters` | `[ - name, values ]` | 过滤器,**仅 ec2 与 rds 支持** | | `clusters` | `[, ...]` | 集群列表,用于 `ecs`/`elasticache`/`msk`/`rds` | | `` | 块 | HTTP 客户端块 | 各 role 的 meta 标签: | role | meta 标签 | | --- | --- | | `ec2` | `__meta_ec2_*`:ami、architecture、availability_zone、availability_zone_id、instance_id、instance_lifecycle、instance_state、instance_type、ipv6_addresses、owner_id、platform、default_ipv6_address、primary_ipv6_addresses、primary_subnet_id、private_dns_name、private_ip、public_dns_name、public_ip、region、subnet_id、tag_、vpc_id | | `lightsail` | `__meta_lightsail_*`:availability_zone、blueprint_id、bundle_id、instance_name、instance_state、instance_support_code、ipv6_addresses、private_ip、public_ip、region、tag_ | | `ecs` | `__meta_ecs_*`:cluster、cluster_arn、service、service_arn、service_status、task_group、task_arn、task_definition、ip_address、launch_type、desired_status、last_status、health_status、platform_family、platform_version、subnet_id、availability_zone、region、public_ip、network_mode、container_instance_arn、`ec2_*` 系列、tag_cluster_/tag_service_/tag_task_/tag_ec2_ | | `msk` | `__meta_msk_*`:cluster_name/arn/state/type/version/kafka_version/jmx_exporter_enabled/configuration_arn/configuration_revision/tag_;node_type/arn/added_time/instance_type/attached_eni;broker_id/endpoint_index/client_subnet/client_vpc_ip/node_exporter_enabled;controller_endpoint_index | | `elasticache` | `__meta_elasticache_*`:deployment_option;serverless_cache_* 与 cache_cluster_* 两大系列,含 node_* 节点级标签 | | `rds` | `__meta_rds_cluster_*` 与 `__meta_rds_instance_*` 两大系列 | #### `azure_sd_config` | 字段 | 类型 / 默认值 | | --- | --- | | `environment` | ` \| default = AzurePublicCloud` | | `authentication_method` | ` \| default = OAuth`(`OAuth`/`ManagedIdentity`/`SDK`/`WorkloadIdentity`) | | `subscription_id` | ``(**必填**) | | `tenant_id` / `client_id` / `client_secret` / `resource_group` | `` | | `refresh_interval` | ` \| default = 300s` | | `port` | ` \| default = 80` | | `` | 块 | meta:`__meta_azure_machine_*`、`__meta_azure_subscription_id`、`__meta_azure_tenant_id`。 #### `consul_sd_config` | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `server` | ` \| default = "localhost:8500"` | Consul 地址 | | `path_prefix` | `` | 路径前缀 | | `token` | `` | ACL token | | `datacenter` | `` | 数据中心 | | `namespace` | `` | 企业版命名空间 | | `partition` | `` | 企业版分区 | | `scheme` | ` \| default = "http"` | 协议 | | `username` / `password` | `` | 已弃用,改用 `basic_auth` | | `services` | `[ - ]` | 要发现的服务 | | `filter` | `` | Catalog API 过滤表达式 | | `health_filter` | `` | Health API 过滤表达式 | | `tags` | — | 已弃用 | | `node_meta` | — | 已弃用 | | `tag_separator` | ` \| default = ,` | 标签分隔符 | | `allow_stale` | ` \| default = true` | 是否允许陈旧读取 | | `refresh_interval` | ` \| default = 30s` | 刷新间隔 | | `` | 块 | HTTP 客户端块 | meta:`__meta_consul_*`。 #### `dns_sd_config` | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `names` | `[ - ]` | 要查询的 DNS 名 | | `type` | ` \| default = 'SRV'` | `SRV`/`A`/`AAAA`/`MX`/`NS` | | `port` | `` | 端口 | | `refresh_interval` | ` \| default = 30s` | 刷新间隔 | meta:`__meta_dns_name`、`__meta_dns_srv_record_target`/`_port`、`__meta_dns_mx_record_target`、`__meta_dns_ns_record_target`。 #### `kubernetes_sd_config` | 字段 | 类型 / 默认值 | 说明 | | --- | --- | --- | | `api_server` | `` | API server 地址(与 `kubeconfig_file` 互斥) | | `role` | `` | **必填**:`endpoints` / `endpointslice` / `service` / `pod` / `node` / `ingress` | | `kubeconfig_file` | `` | 与 `api_server` 互斥 | | `namespaces` | 块 | `own_namespace: `、`names: [ - ]` | | `selectors` | `[ - role, label, field ]` | 资源选择器 | | `attach_metadata` | 块 | `node`/`namespace`/`deployment`/`job`/`cronjob`,默认均为 `false` | | `` | 块 | HTTP 客户端块 | roles:`node`/`service`/`pod`/`endpoints`/`endpointslice`/`ingress`;meta 前缀 `__meta_kubernetes_*`。 > 💡 补充:`endpoints` API 在 K8s v1.33+ 已弃用,建议改用 `endpointslice`;`endpointslice` 需 `discovery.k8s.io/v1`(K8s v1.21+);`ingress` 需 `networking.k8s.io/v1`(K8s v1.19+)。 #### 其余 SD 块的字段速览 | SD 块 | 字段(类型 / 默认值) | | --- | --- | | `digitalocean_sd_config` | `role: \| default = droplets`(droplets/databases)、`port: 80`、`refresh_interval: 60s`、`` | | `ec2_sd_config`(独立 EC2 SD) | `region`、`endpoint`、`access_key`、`secret_key`、`profile`、`role_arn`、`external_id`、`refresh_interval: 60s`、`port: 80`、`filters`、`` | | `gce_sd_config` | `project`(必填)、`zone`(必填)、`filter`、`refresh_interval: 60s`、`port: 80`、`tag_separator \| default = ,` | | `hetzner_sd_config` | `role`(robot/hcloud,必填)、`port: 80`、`refresh_interval: 60s`、`label_selector`(仅 hcloud)、`` | | `ionos_sd_config` | `datacenter_id`(必填)、`port: 80`、`refresh_interval: 60s`、`` | | `kuma_sd_config` | `server`(必填)、`client_id`、`refresh_interval: 30s`、`fetch_timeout: 2m`、`` | | `lightsail_sd_config` | `region`、`endpoint`、`access_key`、`secret_key`、`profile`、`role_arn`、`external_id`、`refresh_interval: 60s`、`port: 80`、`` | | `linode_sd_config` | `region`、`port: 80`、`tag_separator \| default = ,`、`refresh_interval: 60s`、`` | | `marathon_sd_config` | `servers`(至少一个)、`refresh_interval: 30s`、`auth_token`(与 `auth_token_file` 互斥)、`auth_token_file`、`` | | `nerve_sd_config` | `servers`(必填)、`paths`(必填)、`timeout \| default = 10s` | | `nomad_sd_config` | `allow_stale: true`、`namespace \| default = default`、`refresh_interval: 60s`、`region \| default = global`、`server`、`tag_separator \| default = ,`、`` | | `oci_sd_config` | `auth \| default = "api_key"`(api_key/instance_principal)、`tenancy`、`user`、`fingerprint`、`key_file`、`key_passphrase`(与 `key_passphrase_file` 互斥)、`key_passphrase_file`、`region`(必填)、`compartments`、`basic_auth`/`authorization`/`oauth2`(OCI 当前不支持)、`proxy_url`、`no_proxy`、`proxy_from_environment: false`、`proxy_connect_header`、`follow_redirects: true`、`enable_http2: true`、`tls_config`、`port: 80`、`refresh_interval: 60s` | | `openstack_sd_config` | `role`(hypervisor/instance/loadbalancer,必填)、`region`(必填)、`identity_endpoint`、`username`/`userid`、`password`、`domain_name`/`domain_id`、`project_name`/`project_id`、`application_credential_name`/`_id`/`_secret`、`all_tenants: false`、`refresh_interval: 60s`、`port: 80`、`availability \| default = "public"`(public/admin/internal)、`tls_config` | | `outscale_sd_config` | `region \| default = "eu-west-2"`、`access_key`(必填)、`secret_key`(与 `secret_key_file` 二选一)、`secret_key_file`、`endpoint`(空则 `https://api..outscale.com/api/v1`)、`port: 80`、`refresh_interval: 60s`、`` | | `ovhcloud_sd_config` | `application_key`、`application_secret`、`consumer_key`、`service`(vps 或 dedicated_server)、`endpoint \| default = "ovh-eu"`、`refresh_interval: 60s` | | `puppetdb_sd_config` | `url`(必填)、`query`(PQL,必填,仅资源)、`include_parameters: false`、`refresh_interval: 60s`、`port: 80`、`` | | `scaleway_sd_config` | `access_key`(必填)、`secret_key`(与 `secret_key_file` 互斥)、`secret_key_file`、`project_id`(必填)、`role`(instance/baremetal,必填)、`port: 80`、`api_url \| default = "https://api.scaleway.com"`、`zone \| default = fr-par-1`、`name_filter`、`tags_filter`、`refresh_interval: 60s`、`` | | `serverset_sd_config` | `servers`(必填)、`paths`(必填)、`timeout \| default = 10s`;仅支持 JSON 格式(不支持 Thrift) | | `stackit_sd_config` | `project`(必填)、`region \| default = "eu01"`、`endpoint`、`port: 80`、`private_key`、`private_key_path`、`service_account_key`、`service_account_key_path`、`credentials_file_path`、`refresh_interval: 60s`、`` | | `triton_sd_config` | `account`(必填)、`role \| default = "container"`(container/cn)、`dns_suffix`(必填)、`endpoint`(必填)、`groups`(仅 container)、`port \| default = 9163`、`refresh_interval: 60s`、`version \| default = 1`、`tls_config` | | `eureka_sd_config` | `server`(必填)、`refresh_interval: 30s`、`` | | `uyuni_sd_config` | `server`(必填)、`username`、`password`(必填)、`entitlement \| default = monitoring_entitled`、`separator \| default = ,`、`refresh_interval: 60s`、`` | | `vultr_sd_config` | `port: 80`、`refresh_interval: 60s`、``;meta `__meta_vultr_instance_*` | > 💡 补充:`gce_sd_config` 的凭据获取顺序为:`GOOGLE_APPLICATION_CREDENTIALS` → `$HOME/.config/gcloud/application_default_credentials.json` → GCE metadata server。`oci_sd_config` 的 meta 标签名中非 `[a-zA-Z0-9_]` 字符会转为下划线(保留大小写),并含 `defined_tag__`、`tag_`。 > 引自:[Configuration](https://prometheus.io/docs/prometheus/latest/configuration/configuration/) --- ## 第 3 章 规则与模板 Prometheus 支持两类可按固定间隔配置并求值的规则:**recording rules(记录规则)** 与 **alerting rules(告警规则)**。要纳入规则,需创建含规则语句的文件,并通过配置中的 `rule_files` 字段让 Prometheus 加载。规则文件使用 YAML。 规则文件可在运行时通过向 Prometheus 进程发送 `SIGHUP` **重新加载**。**只有当所有规则文件格式都正确时,变更才会被应用**。语法检查可用 `promtool`,无需启动 Prometheus 服务器: ```bash promtool check rules /path/to/example.rules.yml ``` `promtool` 二进制包含在项目下载页提供的 `prometheus` archive 中。文件语法合法时,检查器把解析出的规则文本表示打印到 stdout,并以状态码 `0` 退出;若有语法错误或无效输入参数,则向 stderr 打印错误信息并以 `1` 退出。 > 💡 补充:规则文件与主配置共用一套「全有或全无」的安全语义——一处出错,整批变更都不生效。这正是应在 CI 中对每个规则文件跑 `promtool check rules` 的原因。 ### 3.1 记录规则(Recording rules) **是什么 / 为什么**:记录规则把**频繁需要或计算昂贵**的表达式预先计算,结果保存为一组新的时间序列。查询预计算结果通常比每次执行原表达式快得多——对需要每次刷新都重复查询同一表达式的 dashboard 尤其有用。 **原理**:recording 与 alerting 规则都存在于 **rule group** 中。组内规则按固定间隔、以**同一求值时间**顺序执行。因此同一 group 内的规则可以「后面的规则引用前面规则的输出」,但不会看到更晚的规则。 命名约束:**recording rule 的名称必须是合法 metric name**;**alerting rule 的名称必须是合法 label value**。 **规则文件语法**: ```yaml groups: [ - ] ``` **简单示例**: ```yaml groups: - name: example rules: - record: code:prometheus_http_requests_total:sum expr: sum by (code) (prometheus_http_requests_total) ``` **`` 语法**: ```yaml # The name of the group. Must be unique within a file. name: # How often rules in the group are evaluated. [ interval: | default = global.evaluation_interval ] # Limit the number of alerts an alerting rule and series a recording # rule can produce. 0 is no limit. [ limit: | default = 0 ] # Offset the rule evaluation timestamp of this particular group by the specified duration into the past. [ query_offset: | default = global.rule_query_offset ] # Labels to add or overwrite before storing the result for its rules. # Labels defined in will override the key if it has a collision. labels: [ : ] rules: [ - ... ] ``` > 💡 补充:group 级 `labels` 与 rule 级 `labels` 发生键冲突时,**rule 级优先**(覆盖 group 级)。 **``(recording)语法**: ```yaml # The name of the time series to output to. Must be a valid metric name. record: # The PromQL expression to evaluate. Every evaluation cycle this is # evaluated at the current time, and the result recorded as a new set of # time series with the metric name as given by 'record'. expr: # Labels to add or overwrite before storing the result. labels: [ : ] ``` #### 命名约定 `level:metric:operations` 一致的命名方案让人一眼看懂规则含义,并让错误或无意义的计算暴露出来。记录规则应采用通用形式 **`level:metric:operations`**: - **`level`**:规则输出的聚合层级与 label。 - **`metric`**:指标名,应保持不变,仅在用 `rate()`/`irate()` 时**去掉 counter 的 `_total`**。 - **`operations`**:施加到指标上的操作列表,**最新操作在前**。 保持指标名不变,便于知道指标是什么、便于在代码库中查找指标。为保持操作名干净: - 若已有其他操作,则**省略 `_sum`**(保留 `sum()` 会冗余); - 可结合(associative)的操作可合并(如 `min_min` 等同 `min`); - 若没有明显的操作可用,就用 `sum`; - 做除法求比率时,用 `_per_` 分隔两指标,并把操作命名为 `ratio`。 > 💡 补充:`level` 与 `operations` 的组合使指标名本身成为「可读的查询说明」——例如 `job:request_failures_per_requests:ratio_rate5m` 一目了然地表达「job 层级、请求失败率、5 分钟速率的比值」。 > 引自:[Defining recording rules](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) ### 3.2 告警规则(Alerting rules) **是什么 / 为什么**:告警规则基于 PromQL 表达式定义告警条件。当表达式在某一时刻产生一个或多个向量元素时,该告警对这些元素的 label set 视为 **active**。告警规则的配置方式与 recording rules 相同。 **完整示例(含 group 级 `labels`)**: ```yaml groups: - name: example labels: team: myteam rules: - alert: HighRequestLatency expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5 for: 10m keep_firing_for: 5m labels: severity: page annotations: summary: High request latency ``` **``(alerting)语法**: ```yaml # The name of the alert. Must be a valid label value. alert: # The PromQL expression to evaluate. Every evaluation cycle this is # evaluated at the current time, and all resultant time series become # pending/firing alerts. expr: # Alerts are considered firing once they have been returned for this long. # Alerts which have not yet fired for long enough are considered pending. [ for: | default = 0s ] # How long an alert will continue firing after the condition that triggered it # has cleared. [ keep_firing_for: | default = 0s ] # Labels to add or overwrite for each alert. labels: [ : ] # Annotations to add to each alert. annotations: [ : ] ``` #### `for` 与 `keep_firing_for` - **`for`**(可选):从首次出现新的表达式输出向量元素,到该元素被计为 firing 之间等待的时长。例中 Prometheus 会检查该告警在 10 分钟内每次求值都持续 active 才触发。active 但尚未 firing 的元素处于 **pending** 状态。**没有 `for` 子句的告警规则在第一次求值时即变为 active(并立即 firing)。** - **`keep_firing_for`**(可选):告诉 Prometheus 在最后一次满足 firing 条件之后,继续让该告警保持 firing 指定时长。用于**防止 flapping alerts**、因数据丢失导致的误报 resolved 等。没有该子句的规则会在条件不满足的第一次求值时失效(前提是已完成上面的可选 `for` 时长)。 #### `labels` 与 `annotations` - **`labels` 子句**:为告警附加一组额外 label;任何已存在的**冲突 label 会被覆盖**。label 值可模板化。 - **`annotations` 子句**:一组信息性 label,用于存放更长的附加信息(如告警描述、runbook 链接)。annotation 值可模板化。 #### 模板变量 `$labels` / `$value` label 与 annotation 值可用 console templates 模板化: - `$labels` 变量持有告警实例的 label 键值对; - 配置的 external labels 通过 `$externalLabels` 访问; - `$value` 变量持有告警实例的求值结果。 ```gotemplate # To insert a firing element's label values: {{ $labels. }} # To insert the numeric expression value of the firing element: {{ $value }} ``` #### 完整示例(两个告警) ```yaml groups: - name: example rules: # Alert for any instance that is unreachable for >5 minutes. - alert: InstanceDown expr: up == 0 for: 5m labels: severity: page annotations: summary: "Instance {{ $labels.instance }} down" description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes." # Alert for any instance that has a median request latency >1s. - alert: APIHighRequestLatency expr: api_http_request_latencies_second{quantile="0.5"} > 1 for: 10m annotations: summary: "High request latency on {{ $labels.instance }}" description: "{{ $labels.instance }} has a median request latency above 1s (current value: {{ $value }}s)" ``` #### 运行时查看告警与 `ALERTS` 序列 - 进入 Prometheus 实例的 **"Alerts"** tab,可看到每个已定义告警当前 active 的确切 label set。 - 对 pending 和 firing 的告警,Prometheus 会存储**合成时间序列** `ALERTS{alertname="", alertstate="", }`。只要告警处于该 active(pending 或 firing)状态,样本值即为 `1`;不再如此时该序列被标记为 stale。 #### 发送告警通知 Prometheus 的告警规则擅长判断「当前」哪里出问题,但**不是完整的通知方案**。还需要一层来做摘要、通知限流、静默与告警依赖。生态中由 **Alertmanager** 承担该角色:Prometheus 可被配置为定期把告警状态信息发给 Alertmanager 实例,由其负责派发正确的通知。Prometheus 也可被配置为通过其服务发现集成**自动发现**可用的 Alertmanager 实例。 > 引自:[Alerting rules](https://prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) ### 3.3 模板参考(Template reference) Prometheus 支持在告警的 annotations 与 labels、以及提供的 console 页面中模板化。模板可对本地数据库运行查询、遍历数据、使用条件、格式化数据等。模板语言基于 **Go templating** 系统。 #### 数据结构 处理时间序列数据的主要数据结构是 sample,定义为: ```go type sample struct { Labels map[string]string Value interface{} } ``` 样本的 metric name 编码在 `Labels` map 中的特殊 `__name__` label 里。`[]sample` 表示样本列表。Go 中的 `interface{}` 类似 C 的 void pointer。 #### 函数总则 除 Go templating 提供的默认函数外,Prometheus 提供便于处理查询结果的模板函数。**若函数用于 pipeline,pipeline 的值作为最后一个参数传入。** #### Queries 表 | Name | Arguments | Returns | Notes | | --- | --- | --- | --- | | `query` | query string | `[]sample` | 查询数据库,**不支持**返回 range vector | | `first` | `[]sample` | `sample` | 等价于 `index a 0` | | `label` | label, sample | string | 等价于 `index sample.Labels label` | | `value` | sample | `interface{}` | 等价于 `sample.Value` | | `sortByLabel` | label, `[]sample` | `[]sample` | 按给定 label 排序样本;排序稳定(stable) | `first`、`label`、`value` 旨在让查询结果易于用在 pipeline 中。 #### Numbers 表 | Name | Arguments | Returns | Notes | | --- | --- | --- | --- | | `humanize` | number 或 string | string | 用 metric 前缀把数字转为更可读的格式(1000 进制) | | `humanize1024` | number 或 string | string | 类似 `humanize`,但以 **1024** 为基数 | | `humanizeDuration` | number 或 string | string | 把以秒为单位的时长转为更可读格式 | | `humanizePercentage` | number 或 string | string | 把比率值转为百分比 | | `humanizeTimestamp` | number 或 string | string | 把 Unix 时间戳(秒)转为更可读格式 | | `toTime` | number 或 string | `*time.Time` | 把 Unix 时间戳(秒)转为 `time.Time` | | `toDuration` | number 或 string | `*time.Duration` | 把以秒为单位的时长转为 `time.Duration` | | `now` | 无 | float64 | 返回模板求值时刻的 Unix 时间戳(秒) | > 💡 补充:humanizing 类函数面向人类可读输出,**不保证在 Prometheus 各版本间返回相同结果**——因此**不要**用它们的输出做逻辑判断或阈值比较。 #### Strings 表 | Name | Arguments | Returns | Notes | | --- | --- | --- | --- | | `title` | string | string | `cases.Title`,把每个单词首字母大写 | | `toUpper` | string | string | `strings.ToUpper`,全部转大写 | | `toLower` | string | string | `strings.ToLower`,全部转小写 | | `stripPort` | string | string | `net.SplitHostPort`,去掉端口只返回 host | | `match` | pattern, text | boolean | `regexp.MatchString`,测试**非锚定**正则匹配 | | `reReplaceAll` | pattern, replacement, text | string | `Regexp.ReplaceAllString`,**非锚定**正则替换 | | `graphLink` | expr | string | 返回该表达式在 expression browser 中 graph 视图的路径 | | `tableLink` | expr | string | 返回该表达式在 expression browser 中 Table 视图的路径 | | `parseDuration` | string | float | 解析如 `"1h"` 的时长字符串为秒数 | | `stripDomain` | string | string | 去掉 FQDN 的域名部分,**保留端口不变** | | `urlQueryEscape` | string | string | `url.QueryEscape`,转义字符串以便安全放入 URL query | #### Others 表 | Name | Arguments | Returns | Notes | | --- | --- | --- | --- | | `args` | `[]interface{}` | `map[string]interface{}` | 把对象列表转成键为 `arg0`、`arg1`… 的 map,用于向模板传多个参数 | | `tmpl` | string, `[]interface{}` | nothing | 类似内置 `template`,但允许非字面量作为模板名;结果被视为安全、不自动转义。**仅 console 可用** | | `safeHtml` | string | string | 标记字符串为 HTML、无需自动转义 | | `externalURL` | 无 | string | Prometheus 对外可达的 external URL | | `pathPrefix` | 无 | string | console 模板使用的外部 URL path | #### 模板类型差异 各类模板提供不同信息用于参数化模板,并有其他若干差异。 **Alert field templates**:`.Value`、`.Labels`、`.ExternalLabels`、`.ExternalURL` 分别包含告警值、告警 labels、全局配置的 external labels、external URL(由 `--web.external-url` 配置)。为方便起见,它们也以 `$value`、`$labels`、`$externalLabels`、`$externalURL` 变量暴露。 **Console templates**:consoles 暴露在 `/consoles/`,来源目录由 `-web.console.templates` flag 指定。console 模板用 `html/template` 渲染,提供**自动转义**;要绕过自动转义需用 `safe*` 函数。 - URL 参数以 map 形式在 `.Params` 中可用;要按同名访问多个 URL 参数,`.RawParams` 是各参数取值列表的 map。 - URL path 在 `.Path` 中可用(不含 `/consoles/` 前缀)。 - 全局配置的 external labels 在 `.ExternalLabels` 中可用。 - 四者都有便捷变量:`$rawParams`、`$params`、`$path`、`$externalLabels`。 - Consoles 还可访问由 `-web.console.libraries` flag 指定目录中 `*.lib` 文件里通过 `{{define "templateName"}}...{{end}}` 定义的所有模板。因是**共享命名空间**,需注意避免与其他用户冲突。以 `prom`、`_prom`、`__` 开头的模板名,以及上面列出的函数,均为 Prometheus 保留。 > 引自:[Template reference](https://prometheus.io/docs/prometheus/latest/configuration/template_reference/) ### 3.4 模板示例(Template examples) 模板可对本地数据库运行查询、遍历数据、使用条件、格式化数据等。以下为官方示例逐一说明。 **简单告警字段模板**: ```yaml alert: InstanceDown expr: up == 0 for: 5m labels: severity: page annotations: summary: "Instance {{$labels.instance}} down" description: "{{$labels.instance}} of job {{$labels.job}} has been down for more than 5 minutes." ``` > 💡 补充:告警字段模板会在**每次规则迭代中、对每个 firing 的告警执行**,因此查询和模板要保持轻量。如需更复杂的告警模板,建议改为链到 console。 **Simple iteration**(列出实例及其 up 状态): ```gotemplate {{ range query "up" }} {{ .Labels.instance }} {{ .Value }} {{ end }} ``` 特殊变量 `.` 持有每次循环迭代中当前样本的值。 **Display one value**: ```gotemplate {{ with query "some_metric{instance='someinstance'}" }} {{ . | first | value | humanize }} {{ end }} ``` Go 与 Go 模板语言都是**强类型**的,因此必须检查是否返回了样本以避免执行错误;例如抓取或规则求值尚未运行、或主机下线时会发生。内置的 `prom_query_drilldown` 模板会处理该情况,允许对结果格式化,并链接到 expression browser。 **使用 console URL 参数**: ```gotemplate {{ with printf "node_memory_MemTotal{job='node',instance='%s'}" .Params.instance | query }} {{ . | first | value | humanize1024 }}B {{ end }} ``` 若以 `console.html?instance=hostname` 访问,`.Params.instance` 求值为 `hostname`。 **Advanced iteration**(遍历所有网络设备并展示各设备网络流量): ```html {{ range printf "node_network_receive_bytes{job='node',instance='%s',device!='lo'}" .Params.instance | query | sortByLabel "device"}} {{ end }}
{{ .Labels.device }}
Received {{ with printf "rate(node_network_receive_bytes{job='node',instance='%s',device='%s'}[5m])" .Labels.instance .Labels.device | query }}{{ . | first | value | humanize }}B/s{{end}}
Transmitted {{ with printf "rate(node_network_transmit_bytes{job='node',instance='%s',device='%s'}[5m])" .Labels.instance .Labels.device | query }}{{ . | first | value | humanize }}B/s{{end}}
``` 因 `range` action **未指定变量**,循环内部 `.` 变为循环变量,故 `.Params.instance` 在循环内不可用——这是写模板时最常踩的坑之一。 **定义可复用模板**。Prometheus 支持定义可复用模板,与 console library 支持结合时尤其强大,可在多个 console 间共享模板: ```gotemplate {{/* Define the template */}} {{define "myTemplate"}} do something {{end}} {{/* Use the template */}} {{template "myTemplate"}} ``` 模板只限**一个参数**。`args` 函数可用于包裹多个参数: ```gotemplate {{define "myMultiArgTemplate"}} First argument: {{.arg0}} Second argument: {{.arg1}} {{end}} {{template "myMultiArgTemplate" (args 1 2)}} ``` > 引自:[Template examples](https://prometheus.io/docs/prometheus/latest/configuration/template_examples/) ### 3.5 规则单元测试(Unit testing for rules) 可用 `promtool` 测试规则: ```shell # For a single test file. ./promtool test rules test.yml # If you have multiple test files, say test1.yml,test2.yml,test3.yml ./promtool test rules test1.yml test2.yml test3.yml ``` #### 测试文件格式 ```yaml # This is a list of rule files to consider for testing. Globs are supported. rule_files: [ - ] [ evaluation_interval: | default = 1m ] # Setting fuzzy_compare true will very slightly weaken floating point comparisons. # This will (effectively) ignore differences in the last bit of the mantissa. [ fuzzy_compare: | default = false ] # The order in which group names are listed below will be the order of evaluation of # rule groups (at a given evaluation time). The order is guaranteed only for the groups mentioned below. # All the groups need not be mentioned below. group_eval_order: [ - ] # All the tests are listed here. tests: [ - ] ``` #### `` ```yaml # Series data [ interval: | default = evaluation_interval ] input_series: [ - ] # Name of the test group [ name: ] # Start timestamp for the test group. This sets the base time for all samples # and evaluations in this test group. # Accepts either a Unix timestamp (e.g., 1609459200) or an RFC3339 formatted # timestamp (e.g., "2021-01-01T00:00:00Z"). # Default: 0 (Unix epoch: 1970-01-01 00:00:00 UTC) [ start_timestamp: | | default = 0 ] # Unit tests for alerting rules. We consider the alerting rules from the input file. alert_rule_test: [ - ] # Unit tests for PromQL expressions. promql_expr_test: [ - ] # External labels accessible to the alert template. external_labels: [ : ... ] # External URL accessible to the alert template. # Usually set using --web.external-url. [ external_url: ] ``` #### ``:输入序列记法 `series: ` 遵循通常的 series 记法 `'{