柴少的官方网站 技术在学习中进步,水平在分享中升华

Prometheus搭建部署及官网翻译(一)

Prometheus的官网:https://prometheus.io/

一、Prometheus安装与介绍

#理论是操作的基石,此章节重点为一些基础理论的官网翻译,看完安装可忽略剩余内容。

1.1 OVERVIEW(概述总览)

什么是Prometheus?

       Prometheus是最初在SoundCloud上构建的开源系统监视和警报工具包。 自2012年成立以来,许多公司和组织都采用了Prometheus,该项目拥有非常活跃的开发人员和用户社区。 现在,它是一个独立的开源项目,并且独立于任何公司进行维护。 为了强调这一点并阐明项目的治理结构,Prometheus于2016年加入了Cloud Native Computing Foundation,这是继Kubernetes之后的第二个托管项目。

Features(特征):

Prometheus的主要特点是:

一个多维数据模型,其中包含通过度量标准名称和key/value标识的时间序列数据
PromQL,一种灵活的查询语言,可利用此维度
不依赖分布式存储; 单服务器节点是自治的
时间序列收集通过HTTP上的拉模型进行
通过中间网关支持推送时间序列
通过服务发现或静态配置发现目标
多种图形和仪表板支持模式

Components(组件):

Prometheus生态系统包含多个组件,其中许多是可选的:

Prometheus主服务器,它会scrapes并存储时间序列数据
client libraries,用于检测应用程序代码
一个支持短期工作的push gateway
诸如HAProxy,StatsD,Graphite等服务的special-purpose exporters
alertmanager以处理警报
各种支持工具

大多数Prometheus组件都是用Go编写的,从而使其易于构建和部署为静态二进制文件。

Architecture(结构):

下图说明了Prometheus的体系结构及其某些生态系统组件:

image.png

Prometheus直接或通过中间推送网关从已检测作业中删除指标,以用于短期作业。 它在本地存储所有报废的样本,并对这些数据运行规则,以汇总和记录现有数据中的新时间序列,或生成警报。 Grafana或其他API使用者可用于可视化收集的数据。

什么时候使用它合适?

       Prometheus非常适合记录任何纯数字时间序列。 它既适合以机器为中心的监视,也适合监视高度动态的面向服务的体系结构。 在微服务世界中,它对多维数据收集和查询的支持是一种特别的优势。

       Prometheus的设计旨在提高可靠性,使其成为中断期间要使用的系统,从而使你能够快速诊断问题。 每个Prometheus服务器都是独立的,而不依赖于网络存储或其他远程服务。 当基础结构的其他部分损坏时,你可以依靠它,而无需建立广泛的基础结构来使用它。

什么时候使用它不适合?

       Prometheus重视可靠性。 即使在故障情况下,你也始终可以查看有关系统的可用统计信息。 如果你需要100%的准确性(例如按请求计费),则Prometheus并不是一个不错的选择,因为所收集的数据可能不会足够详细和完整。 在这种情况下,最好使用其他系统来收集和分析计费数据,并使用Prometheus进行其余的监视。

1.2 Prometheus的安装

下载Prometheus并安装:

#wget https://github.com/prometheus/prometheus/releases/download/v2.13.1/prometheus-2.13.1.linux-amd64.tar.gz

#tar zxf prometheus-2.13.1.linux-amd64.tar.gz

#cd prometheus-2.13.1.linux-amd64

#./prometheus --config.file=prometheus.yml &  #能够在http://localhost:9090上浏览到有关其自身的状态页。 给它大约30秒的时间,以从其自己的HTTP指标终结点收集有关自身的数据。

# netstat  -lntup|grep 9090

tcp6       0      0 :::9090                 :::*                    LISTEN      30137/./prometheus

# ./prometheus --help  #查看一下帮助文档

usage: prometheus [<flags>]
The Prometheus monitoring server
Flags:
--version  #显示应用程序版本。
--config.file="prometheus.yml"  #Prometheus配置文件路径。
--web.listen-address="0.0.0.0:9090"  #监听UI,API和telemetry的地址。
--web.read-timeout=5m   #超时读取请求并关闭空闲连接之前的最大持续时间。
--web.max-connections=512   #最大同时连接数。
--web.external-url=<URL>    #可从外部访问Prometheus的URL(例如,如果Prometheus是通过反向代理提供的)。用于生成相对和绝对链接返回到Prometheus本身。如果URL包含路径部分,它将用于为所有HTTP端点添加前缀由Prometheus服务。如果省略,则会自动派生相关的URL组件。
--web.route-prefix=<path>   #Web端点内部路由的前缀。 默认为--web.external-url的路径。
--web.user-assets=<path>    #静态资产目录的路径,位于/user。
--web.enable-lifecycle      #启用关机并通过HTTP请求重新加载。
--web.enable-admin-api      #为admin控制操作启用API端点。
--web.console.templates="consoles"  #控制台模板目录的路径,位于/consoles。
--web.console.libraries="console_libraries"  #控制台库目录的路径。
--web.page-title="Prometheus Time Series Collection and Processing Server"   #Prometheus实例的文档标题。
--web.cors.origin=".*"     #用于CORS来源的正则表达式。它已完全锚定。例如:'https?://(domain1|domain2)\.com'
--storage.tsdb.path="data/"  #指标存储的基本路径
--storage.tsdb.retention=STORAGE.TSDB.RETENTION   #[不建议使用]将样品保留多长时间。 此标志已被弃用,请改用“storage.tsdb.retention.time”。
--storage.tsdb.retention.time=STORAGE.TSDB.RETENTION.TIME   #将样品保存多长时间。 设置此标志后,它将覆盖“storage.tsdb.retention”。 如果此标志或未设置“storage.tsdb.retention”或“storage.tsdb.retention.size”,保留时间默认为15d。
--storage.tsdb.retention.size=STORAGE.TSDB.RETENTION.SIZE   #[实验性]可以为块存储的最大字节数。 支持的单位:KB,MB,GB,TB,PB。 该标志是实验性的并且可以在将来的版本中进行更改。
--storage.tsdb.no-lockfile    #不要在数据目录中创建锁文件。
--storage.tsdb.allow-overlapping-blocks    #[实验性]允许重叠的块,从而启用垂直压缩和垂直查询合并。
--storage.tsdb.wal-compression    #压缩tsdb WAL。
--storage.remote.flush-deadline=<duration>    #关闭或配置重新加载时等待冲洗样本的时间。
--storage.remote.read-sample-limit=5e7     #在单个查询中通过远程读取接口返回的最大样本总数。0表示没有限制。此限制被忽略用于流式响应类型。
--storage.remote.read-concurrent-limit=10    #并发远程读取调用的最大数目。 0表示没有限制。
--storage.remote.read-max-bytes-in-frame=1048576    #编组之前用于流式传输远程读取响应类型的单个帧中的最大字节数。 请注意,客户端可能有也限制帧大小。 默认为protobuf建议的1MB。
--rules.alert.for-outage-tolerance=1h    #Prometheus中断以恢复警报“for”状态的最长时间。
--rules.alert.for-grace-period=10m    #警报和恢复的“for”状态之间的最短持续时间。 仅当配置的“for”时间大于宽限期。
--rules.alert.resend-delay=1m    #将警报重新发送到Alertmanager之前等待的最短时间。
--alertmanager.notification-queue-capacity=10000    #等待的Alertmanager通知的队列容量。
--alertmanager.timeout=10s    #向Alertmanager发送警报的超时。
--query.lookback-delta=5m    #在表达式求值期间检索指标的最大回溯持续时间。
--query.timeout=2m    #查询中止之前可能要花费的最长时间。
--query.max-concurrency=20    #并发执行的最大查询数。
--query.max-samples=50000000     #单个查询可以加载到内存中的最大样本数。 请注意,如果查询尝试加载的样本超过此数量,则查询将失败内存中,因此这也限制了查询可以返回的样本数量。
--log.level=info    #仅记录具有给定严重性或更高严重性的消息。 下列之一:[debug, info, warn, error]
--log.format=logfmt    #日志消息的输出格式。 之一:[logfmt,json]

Configuring Prometheus(配置Prometheus):

global:
  scrape_interval: 15s   #多久去采集一次数据
  evaluation_interval: 15s   #多久对数据分析一次看是否有触发设置的报警值
  
  rule_files:
  # - "first.rules"
  # - "second.rules"
  
  scrape_configs:
  - job_name: prometheus
    static_configs:
      - targets: ['localhost:9090']

示例配置文件中包含三个配置块:global,rule_files和scrape_configs。

       global block控制Prometheus服务器的全局配置。 我们有两个选择。 首先,scrape_interval控制Prometheus多久搜集一次目标。 可以为单个目标覆盖此目标。 在这种情况下,全局设置是每15秒一次。 Evaluation_interval选项控制Prometheus多久评估一次规则。 Prometheus使用规则来创建新的时间序列并生成警报。

       rule_files块指定我们要Prometheus服务器加载的任何规则的位置。目前,还没有任何规则。

       最后一块scrape_configs控制Prometheus监视哪些资源。 由于Prometheus还将有关自身的数据公开为HTTP端点,因此它可以抓取并监视自身的运行状况。 在默认配置中,有一个称为prometheus的作业,它会搜索Prometheus服务器公开的时间序列数据。 该作业在端口9090上包含一个静态配置的目标localhost。Prometheus希望指标可用于/metrics路径上的目标。 因此,此默认作业是通过以下网址进行抓取:http://localhost:9090/metrics.

       返回的时间序列数据将详细说明Prometheus服务器的状态和性能。有关配置选项的完整说明,请参阅配置文档(https://prometheus.io/docs/prometheus/latest/configuration/configuration/)。

      还可以通过导航到自己的指标终结点:http:// localhost:9090/metrics来验证Prometheus是否正在提供有关其自身的指标。

使用表达式浏览器:

       让我们尝试查看Prometheus收集的有关自身的一些数据.要使用Prometheus的内置表达式浏览器,请导航至http://localhost:9090/ graph,然后在“Graph”选项卡中选择“Console”视图。

      正如可以从http://localhost:9090/metrics  收集的那样,Prometheus导出的有关其自身的一个度量称为promhttp_metric_handler_requests_total(Prometheus服务器已处理的/metrics请求总数。继续并将其输入到表达式控制台中:promhttp_metric_handler_requests_total

image.png

博文来自:www.51niux.com

       如上图,这将返回多个不同的时间序列(以及每个时间序列的最新值),所有时间序列的度量标准名称均为promhttp_metric_handler_requests_total,但标签不同。 这些标签指定不同的请求状态。

      如果我们只对导致HTTP代码200的请求感兴趣,则可以使用此查询来检索该信息:promhttp_metric_handler_requests_total{code="200"}

      要计算返回的时间序列数,可以编写:count(promhttp_metric_handler_requests_total)

      有关表达语言的更多信息,请参见表达语言文档:https://prometheus.io/docs/prometheus/latest/querying/basics/

Using the graphing interface(使用绘图界面):

      要绘制图形表达式,请导航至http://localhost:9090/graph并使用“Graph”选项卡。 例如,输入以下表达式以图形化显示在自抓取的Prometheus中发生的每秒HTTP请求速率返回状态代码200:rate(promhttp_metric_handler_requests_total{code="200"}[1m])

      可以尝试使用图形范围参数和其他设置。

Monitoring other targets(监控其他目标):

      仅从Prometheus收集指标并不能很好地说明Prometheus的功能。 为了更好地了解Prometheus可以做什么,建议浏览有关其他exporters的文档。 使用节点导出器指南监控Linux或macOS主机指标是一个不错的开始:https://prometheus.io/docs/guides/node-exporter/

1.3 COMPARISON TO ALTERNATIVES

Prometheus vs. Graphite

Scope(范围):

       Graphite专注于成为具有查询语言和图形功能的被动时间序列数据库。 其他任何问题都可以通过外部组件解决。Prometheus是一个完整的监视和趋势分析系统,其中包括基于时间序列数据的内置和主动抓取,存储,查询,制图和警报。 它了解世界应该是什么样(应该存在哪些端点,什么时间序列模式意味着麻烦等),并积极尝试查找错误。

Data model(数据模型):

       Graphite存储命名时间序列的数值样本,就像Prometheus一样。 但是,Prometheus的元数据模型更加丰富:虽然Graphite度量标准名称由点分隔的组件组成,这些组件隐式地对维进行编码,但是Prometheus显式地将维编码为键值对(称为标签),附加到度量标准名称。 这允许通过查询语言通过这些标签轻松进行过滤,分组和匹配。

       此外,尤其是当将Graphite与StatsD结合使用时,通常只在所有受监视实例上存储聚合数据,而不是将实例保留为一个维度并能够深入分析单个有问题的实例。

       例如,通常使用Graphite/StatsD在响应中使用响应代码500和对/tracks端点的POST方法存储对API服务器的HTTP请求数:

stats.api-server.tracks.post.500 -> 93

       在Prometheus中,可以像这样编码相同的数据(假设三个api服务器实例):

api_server_http_requests_total{method="POST",handler="/tracks",status="500",instance="<sample1>"} -> 34
api_server_http_requests_total{method="POST",handler="/tracks",status="500",instance="<sample2>"} -> 28
api_server_http_requests_total{method="POST",handler="/tracks",status="500",instance="<sample3>"} -> 31

Storage:

       Graphite以Whisper格式将时间序列数据存储在本地磁盘上,这是一种RRD样式的数据库,它希望样本以固定的时间间隔到达。 每个时间序列都存储在一个单独的文件中,新样本在一定时间后会覆盖旧样本。

       Prometheus还在每个时间序列中创建一个本地文件,但允许在出现刮擦或规则评估时以任意间隔存储样本。由于仅附加了新样本,因此旧数据可以任意保留。 普罗米修斯(Prometheus)也适用于许多短暂的,经常变化的时间序列集。

Summary(摘要):

       Prometheus除了更易于运行和集成到你的环境之外,还提供了更丰富的数据模型和查询语言。 如果你想要一个可以长期保存历史数据的群集解决方案,那么Graphite可能是一个更好的选择。

Prometheus vs. InfluxDB

        InfluxDB是一个开放源代码时间序列数据库,具有用于扩展和集群化的商业选项。 Prometheus开发开始将近一年后,InfluxDB项目才发布,因此当时无法将其视为替代方案。 尽管如此,Prometheus和InfluxDB之间仍然存在显着差异,并且两种系统都针对稍有不同的用例。

Scope:

       为了进行公平的比较,我们还必须将Kapacitor与InfluxDB一起考虑,因为它们结合起来可以解决与Prometheus和Alertmanager相同的问题空间。

       与Graphite情况相同的范围差异在这里适用于InfluxDB本身。 此外,InfluxDB还提供连续查询,这些查询等同于Prometheus记录规则。

       Kapacitor的范围是Prometheus记录规则,警报规则和Alertmanager的通知功能的组合。 Prometheus为图形和警报提供了更强大的查询语言。Prometheus Alertmanager另外提供分组,重复数据删除和消音功能。

Data model / storage:

       与Prometheus一样,InfluxDB数据模型也将键值对作为标签,称为标签。 另外,InfluxDB还有第二级标签,称为字段,使用范围受到更多限制。 InfluxDB支持最高达十亿分之一秒分辨率的时间戳,以及float64,int64,bool和字符串数据类型。 相比之下,Prometheus支持float64数据类型,但对字符串和毫秒分辨率时间戳的支持有限。

      InfluxDB使用日志结构的合并树的变体来存储带有按时间分片的预写日志的存储。 与Prometheus的每个时间序列的仅附加文件相比,此方法更适合事件记录。

Architecture(结构):

        Prometheus服务器彼此独立运行,并且仅依靠其本地存储来实现其核心功能:抓取,规则处理和警报。 InfluxDB的开源版本与此类似。根据设计,商业InfluxDB产品是一个分布式存储集群,其中存储和查询由多个节点一次处理。

       这意味着商业InfluxDB将更易于水平扩展,但这也意味着你必须从一开始就管理分布式存储系统的复杂性。 Prometheus的运行会更简单,但是在某些时候,你将需要沿着产品,服务,数据中心或类似方面的可伸缩性边界明确地分片服务器。 独立服务器(可以并行冗余运行)也可以为你提供更好的可靠性和故障隔离。

       Kapacitor的开源版本没有用于规则,警报或通知的内置distributed/redundant(分布式/冗余)选项。 Kapacitor的开源版本可以通过用户手动分片来扩展,类似于Prometheus本身。 Influx提供了Enterprise Kapacitor,它支持HA/redundant警报系统。

       相比之下,Prometheus和Alertmanager通过运行Prometheus的冗余副本并使用Alertmanager的高可用性模式提供了完全开源的冗余选项。

Summary(小结):

       系统之间有很多相似之处。 两者都有标签(在InfluxDB中称为标签),可以有效地支持多维指标。 两者都使用基本相同的数据压缩算法。 两者都有广泛的集成,包括彼此之间的集成。 两者都有钩子,可让你进一步扩展它们,例如使用统计工具分析数据或执行自动操作。

       InfluxDB更好的地方:如果你要进行事件记录。商业选项为InfluxDB提供集群,这对于长期数据存储也更好。最终在副本之间保持一致的数据视图。

       Prometheus更好的地方:如果你主要是在做指标。更强大的查询语言,警报和通知功能。图形和警报的可用性和正常运行时间更高。

       InfluxDB由一家商业公司按照开放核模型进行维护,并提供高级功能,如封闭源群集,托管和支持。 Prometheus是一个完全开源的独立项目,由许多公司和个人维护,其中一些还提供商业服务和支持。

Prometheus vs. OpenTSDB:

       OpenTSDB是基于Hadoop和HBase的分布式时间序列数据库。

Scope:

       这里适用的范围与Graphite 相同。 

Data model:

       OpenTSDB的数据模型几乎与Prometheus的数据模型相同:时间序列由一组任意键值对标识(OpenTSDB标签是Prometheus标签)。 指标的所有数据都存储在一起,从而限制了指标的基数。 尽管有一些细微的差异:Prometheus允许标签值中包含任意字符,而OpenTSDB的限制更严格。 OpenTSDB还缺少完整的查询语言,仅允许通过其API进行简单的汇总和数学运算。

Storage:

       OpenTSDB的存储在Hadoop和HBase之上实现。这意味着可以轻松地水平扩展OpenTSDB,但是你必须从一开始就接受运行Hadoop/HBase集群的总体复杂性。

       Prometheus最初运行起来会更简单,但是一旦超出单个节点的容量,就需要进行明确的分片。

Summary:

       Prometheus提供了更丰富的查询语言,可以处理更高的基数指标,并且构成了完整监视系统的一部分。 如果你已经在运行Hadoop并重视长期存储的优势,那么OpenTSDB是一个不错的选择。 

Prometheus vs. Nagios:

       Nagios是一个始于1990年代的NetSaint监视系统。

Scope:

       Nagios主要是基于脚本的退出代码进行警报。 这些称为“checks"。单个警报会静音,但是不会进行分组,路由或重复数据删除。有各种各样的插件。 例如,允许使用管道传输几千字节的perfData插件返回时间序列数据库(例如Graphite)或使用NRPE在远程计算机上运行检查。

Data model:

       Nagios是基于主机的。 每个主机可以具有一个或多个服务,并且每个服务可以执行一项检查。没有标签或查询语言的概念。

Storage:

       除了当前的检查状态外,Nagios本身还没有存储空间。 有一些插件可以存储诸如可视化的数据。

Architecture:

       Nagios服务器是独立的。 所有检查配置均通过文件进行。

Summary:

       Nagios适用于对黑匣子进行探测的小型和/或静态系统的基本监视。如果你想进行白盒监控,或者具有动态或基于云的环境,那么Prometheus是一个不错的选择。

Prometheus vs. Sensu:

       Sensu是可组合的监视管道,可以重用现有的Nagios检查。

Scope:

       这里适用与Nagios相同的一般范围差异。还有一个客户端套接字,允许将临时检查结果推送到Sensu中。

Data model:

       Sensu与Nagios具有相同的粗略数据模型。

Storage:

       Sensu使用Redis持久监视数据,包括Sensu客户端注册表,检查结果,检查执行历史记录和当前事件数据。

Architecture:

      Sensu具有许多组件。它使用RabbitMQ作为传输方式,使用Redis作为当前状态,并使用单独的服务器进行处理和API访问。Sensu部署的所有组件(RabbitMQ, Redis, and Sensu Server/API)都可以集群化,以实现高可用性和冗余配置。

Summary:

      如果你现有的Nagios设置希望按原样缩放,或者想利用Sensu的自动注册功能,那么Sensu是一个不错的选择。如果你想进行白盒监控,或者具有非常动态或基于云的环境,那么Prometheus是一个不错的选择。

1.4 GLOSSARY(术语表)

Alert  #警报是Prometheus中积极触发的警报规则的结果。 警报从Prometheus发送到Alertmanager。

Alertmanager  #Alertmanager接收警报,将警报聚合为组,进行重复数据删除,应用静默,限制,然后将通知发送到电子邮件,Pagerduty,Slack等。

Bridge   #bridge是从客户端库中获取样本并将其公开给非Prometheus监视系统的组件。 例如,Python,Go和Java客户端可以将指标导出到Graphite。

Client library   #客户端库是某种语言(例如Go,Java,Python,Ruby)的库,可以轻松地直接检测代码,编写自定义收集器以从其他系统提取指标并将指标公开给Prometheus。

Collector    #收集器是代表一组度量标准的导出器的一部分。 如果它是直接检测的一部分,则可能是单个度量标准,如果是从另一个系统中提取度量标准,则可能是多个度量标准。

Direct instrumentation    #直接检测是作为程序源代码的一部分内联添加的检测。

Endpoint    #可以抓取的度量标准的来源,通常对应于单个过程。

Exporter    #导出程序是公开Prometheus指标的二进制文件,通常通过将以非Prometheus格式公开的指标转换为Prometheus支持的格式来实现。

Instance    #实例是唯一标识作业中目标的标签。

Job    #具有相同目的的目标的集合(例如,监视一组为可伸缩性或可靠性而复制的相似过程)被称为作业。

Notification    #通知代表一组一个或多个警报,并由Alertmanager发送到电子邮件,Pagerduty,Slack等。

Promdash    #Promdash是Prometheus的本地仪表板构建器。 它已被弃用并由Grafana取代。

Prometheus    #Prometheus通常是指Prometheus系统的核心二进制文件。 它也可能是整个Prometheus监视系统的参考。

PromQL    #PromQL是Prometheus查询语言。它允许进行多种操作,包括聚合,切片和切块,预测和连接。

Pushgateway    #Pushgateway保留来自批处理作业的最新指标推送。 这使Prometheus在终止指标后可以抓取其指标。

Remote Read    #远程读取是Prometheus的一项功能,该功能允许作为查询的一部分从其他系统(例如长期存储)透明读取时间序列。

Remote Read Adapter    #并非所有系统都直接支持远程读取。 远程读取适配器位于Prometheus和另一个系统之间,可在它们之间转换时间序列请求和响应。

Remote Read Endpoint    #远程读取端点是Prometheus在进行远程读取时要与之通信的端点。

Remote Write    #远程写是Prometheus的一项功能,它允许将摄取的样本即时发送到其他系统,例如长期存储。

Remote Write Adapter    #并非所有系统都直接支持远程写入。 远程写适配器位于Prometheus和另一个系统之间,将远程写操作中的样本转换为另一个系统可以理解的格式。

Remote Write Endpoint    #远程写端点是Prometheus在执行远程写时要与之通信的端点。

Sample    #样本是时间序列中某个时间点的单个值。在Prometheus中,每个样本都包含一个float64值和一个毫秒精度的时间戳。

Silence    #Alertmanager中的静默功能可防止带有与静默匹配的标签的警报被包含在通知中。

Target     #目标是要刮除的对象的定义。 例如,要应用的标签,连接所需的任何身份验证或定义刮擦方式的其他信息。

1.5 基本认证

        使用基本身份验证保护PROMETHEUS API和UI端点。Prometheus不直接支持与Prometheus表达式浏览器和HTTP API的连接的基本身份验证(也称为“basic auth”)。如果你想对这些连接强制执行基本身份验证,建议将Prometheus与反向代理结合使用,并在代理层应用身份验证。 你可以在Prometheus中使用任何你喜欢的反向代理,这里将提供一个nginx示例。

        注意:尽管不支持与Prometheus实例的基本身份验证连接,但从Prometheus实例到抓取目标的连接均支持基本身份验证。

#nginx的安装就不做介绍了哈。

# yum -y install httpd-tools   #安装apache-htpasswd工具

# htpasswd  -c /application/nginx/conf/.htpasswd admin  #创建admin账号的密码文件

nginx的配置:

    server {
        listen       80;
        server_name  localhost;
        location / {
            auth_basic           "Prometheus";
            auth_basic_user_file /application/nginx/conf/.htpasswd;
            proxy_pass           http://localhost:9090/;
        }
    }

image.png

#这样直接访问域名或者IP就直接跳转到了监控界面,当提示401 Authorization Required的说明用户名密码错误所以认证失败。

# curl -u admin http://localhost/metrics    #linux客户端本地直接测试一下

image.png

#已经有指标数据产出了可见认证成功了。

博文来自:www.51niux.com

1.6 使用NODE EXPORTER监控LINUX主机指标

Prometheus Node Exporter(https://github.com/prometheus/node_exporter)公开了各种与硬件和内核相关的指标。

安装并运行Node Exporter

Prometheus Node Exporter是一个单个静态二进制文件,可以通过压缩包。 从Prometheus下载页面下载后,将其解压缩并运行:

# wget https://github.com/prometheus/node_exporter/releases/download/v0.18.1/node_exporter-0.18.1.linux-amd64.tar.gz

# tar zxf node_exporter-0.18.1.linux-amd64.tar.gz

# cd node_exporter-0.18.1.linux-amd64/

# ./node_exporter &

# curl http://localhost:9100/metrics  #可以自己检查一下,安装完客户端之后可以通过web接口获取数据

# curl http://localhost:9100/metrics | grep "node_"   #各种系统指标(以node_前缀),如下面的数据

# HELP node_disk_io_time_weighted_seconds_total The weighted # of seconds spent doing I/Os.
# TYPE node_disk_io_time_weighted_seconds_total counter
node_disk_io_time_weighted_seconds_total{device="vda"} 363439.472
node_disk_io_time_weighted_seconds_total{device="vdb"} 143.782

查看下启动命令

# ./node_exporter --help

usage: node_exporter [<flags>]
Flags:
  --collector.diskstats.ignored-devices="^(ram|loop|fd|(h|s|v|xv)d[a-z]|nvme\\d+n\\d+p)\\d+$  #设备的正则表达式,忽略哪些设备。
  --collector.filesystem.ignored-mount-points="^/(dev|proc|sys|var/lib/docker/.+)($|/)"   #对于文件系统收集器,要忽略的系统目录的正则表达式。
  --collector.filesystem.ignored-fs-types="^(autofs|binfmt_misc|bpf|cgroup2?|configfs|debugfs|devpts|devtmpfs|fusectl|hugetlbfs|mqueue|nsfs|overlay|proc|procfs|pstore|rpc_pipefs|securityfs|selinuxfs|squashfs|sysfs|tracefs)$"  #文件系统收集器忽略的文件系统类型的正则表达式。
  --collector.netclass.ignored-devices="^$"   #Netclass收集器忽略的网络设备的正则表达式。
  --collector.netdev.ignored-devices="^$"     #netdev收集器忽略的网络设备的正则表达式。
  --collector.netstat.fields="^(.*_(InErrors|InErrs)|Ip_Forwarding|Ip(6|Ext)_(InOctets|OutOctets)|Icmp6?_(InMsgs|OutMsgs)|TcpExt_(Listen.*|Syncookies.*|TCPSynRetrans)|Tcp_(ActiveOpens|InSegs|OutSegs|PassiveOpens|RetransSegs|CurrEstab)|Udp6?_(InDatagrams|OutDatagrams|NoPorts))$"  #用于netstat收集器返回的字段的正则表达式。
  --collector.ntp.server="127.0.0.1"   #用于ntp收集器的NTP服务器
  --collector.ntp.protocol-version=4   #NTP协议版本
  --collector.ntp.server-is-local    #确认collector.ntp.server地址与此收集器位于同一本地主机。
  --collector.ntp.ip-ttl=1   #发送NTP查询时要使用的IP TTL
  --collector.ntp.max-distance=3.46608s   #到根的最大累积距离
  --collector.ntp.local-offset-tolerance=1ms  #本地时钟和本地ntpd时间之间的偏差可以容忍
  --path.procfs="/proc"  #procfs挂载点。
  --path.sysfs="/sys"    #sysfs挂载点。
  --path.rootfs="/"    #rootfs挂载点。
  #剩下的参数可以自己--help查看

配置Prometheus实例

       需要正确配置本地运行的Prometheus实例,才能访问Node Exporter指标。 以下scrape_config块(在prometheus.yml配置文件中)将告诉Prometheus实例通过localhost:9100从Node Exporter进行scrape:

# vim prometheus.yml

scrape_configs:
  - job_name: 'test01'
    static_configs:
    - targets: ['192.168.1.118:9100']

# kill -HUP `ps -aux|grep prometheus|grep -v grep|awk {'print $2'}`    #热加载服务

#注:如果要想用# curl -XPOST http://localhost/-/reload的方式重新热加载配置,在启动prometheus进程时,指定 --web.enable-lifecycle,不然会提示Lifecycle APIs are not enabled。

查看node节点目标是否正常

image.png

#这时候我们发现我们刚添加的node节点并没有成功,State是Down,Error信息是(出现上面这种情况可以自己curl一下看看什么情况):

Get http://192.168.1.118:9100/metrics: context deadline exceeded

#因为我这里用的阿里云的安全组一般是不开放9100的端口的,可以换一个端口,比如80

# ./node_exporter  --web.listen-address=":80" &

通过Prometheus表达式浏览器探索Node Exporter指标

image.png

#注意:prometheus里面的时区是GMT,图形横轴显示的时间与后面的grafana显示时间不同,算成北京时间要+8小时。Prometheus自带的图形并不够强大,一般使用Grafana作为Prometheus的Dashboard。

#上图中显示的cpu的数值是每科CPU的并不是CPU汇总之后的结果。

特定于节点导出器的度量标准以node_为前缀,并包括诸如node_cpu_seconds_total和node_exporter_build_info的度量标准。

node_cpu_seconds_total{cpu="0",instance="192.168.1.118:80",job="test01",mode="idle"}    1175439.64
MetricMeaning
rate(node_cpu_seconds_total{mode="system"}[1m])最近一分钟(秒)内每秒在系统模式下花费的平均CPU时间量
node_filesystem_avail_bytes非root用户可用的文件系统空间(以字节为单位)
rate(node_network_receive_bytes_total[1m])最近一分钟每秒收到的平均网络流量(以字节为单位)

二、CONCEPTS(概念)

2.1 DATA MODE

       Prometheus从根本上将所有数据存储为时间序列:带有时间戳的值流属于同一度量标准和同一组标注维。 除了存储的时间序列,Prometheus可能会生成临时的导出时间序列作为查询的结果。

Metric names and labels:

        每个时间序列都由其指标名称和称为标签的可选键值对唯一标识。指标名称指定了所测量系统的一般功能(例如http_requests_total收到的HTTP请求总数)。 它可能包含ASCII字母和数字,以及下划线和冒号。 它必须与正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*相匹配。注意:冒号是为用户定义的记录规则保留的。 exporters或直接direct instrumentation不应使用它们。

       标签启用Prometheus的维度数据模型:具有相同度量标准名称的标签的任何给定组合都可以标识该度量标准的特定维度实例(例如:所有使用方法POST到/api/tracks处理程序的HTTP请求)。 查询语言允许基于这些维度进行过滤和聚合。 更改任何标签值,包括添加或删除标签,都会创建一个新的时间序列。

       标签名称可能包含ASCII字母,数字和下划线。 它们必须匹配正则表达式[a-zA-Z_][a-zA-Z0-9_]*。 以__开头的标签名称保留供内部使用。标签值可以包含任何Unicode字符。另请参阅命名指标和标签的最佳做法:https://prometheus.io/docs/practices/naming/

Samples:

       来自实际时间序列数据的样本。 每个样本包括:一个float64值,一个毫秒精度的时间戳

Notation:

       给定度量标准名称和一组标签,通常使用以下表示法标识时间序列:<metric name>{<label name>=<label value>, ...}

       例如,度量标准名称api_http_requests_total和标签method="POST"和handler="/messages"的时间序列可以这样写:api_http_requests_total{method="POST", handler="/messages"}

       这与OpenTSDB使用的符号相同。

2.2 METRIC TYPES

        Prometheus客户端库提供了四种核心度量标准类型。当前仅在客户端库(以启用针对特定类型的使用量身定制的API)和有线协议中进行区分。 Prometheus服务器尚未使用类型信息,而是将所有数据展平为未键入的时间序列。 将来可能会改变。

Counter(计数器):

       计数器是一个累积量度,代表一个单调递增的计数器,简单说特点就是只增不减,其值只能在重新启动时增加或重置为零。例如,你可以使用计数器来表示已服务请求,已完成任务或错误的数量,不会因为机器重启而置0,使用Counter指标时,通常结合rate()方法获取该指标在某个时间段的速率。不要使用计数器来显示可以减小的值。 例如,请勿对当前正在运行的进程数使用计数器; 而是使用量规。

      客户端的客户端库使用文档:

Go     #https://godoc.org/github.com/prometheus/client_golang/prometheus#Counter
Java   #https://github.com/prometheus/client_java/blob/master/simpleclient/src/main/java/io/prometheus/client/Counter.java
Python #https://github.com/prometheus/client_python#counter
Ruby   #https://github.com/prometheus/client_ruby#counter

Gauge(仪表盘):

     Gauge是一种度量标准,代表可以任意上下波动的单个数值,例如CPU和内存使用量等,大部分监控数据都是Gauge类型的。gauge的客户端库使用文档:

Go    #https://godoc.org/github.com/prometheus/client_golang/prometheus#Gauge
Java  #https://github.com/prometheus/client_java/blob/master/simpleclient/src/main/java/io/prometheus/client/Gauge.java
Python #https://github.com/prometheus/client_python#gauge
Ruby   #https://github.com/prometheus/client_ruby#gauge

Histogram:

     直方图对观察值(通常是请求持续时间或响应大小之类的东西)进行采样,并将其计数在可配置的存储桶中,简单来说就是某个区间内的样本个数,比如大于某个值的有多少个。 它还提供所有观察值的总和。基本度量标准名称为<basename>的直方图在刮擦期间会暴露多个时间序列:

观察buckets的累积计数器,显示为<basename>_bucket{le="<upper inclusive bound>"}
所有观察值的总和,显示为<basename>_sum
观察到的事件计数,显示为<basename> _count(与上面的<basename>_bucket{le="+Inf"}相同)

     使用histogram_quantile() 函数可以根据直方图甚至是直方图的聚合来计算分位数。 直方图也适用于计算Apdex分数。 在buckets上操作时,请记住直方图是累积的。 有关直方图用法的详细信息以及与摘要的差异,请参见直方图和摘要:https://prometheus.io/docs/practices/histograms/

     客户端库使用情况的直方图文档:

Go    #https://godoc.org/github.com/prometheus/client_golang/prometheus#Histogram
Java    #https://github.com/prometheus/client_java/blob/master/simpleclient/src/main/java/io/prometheus/client/Histogram.java
Python  #https://github.com/prometheus/client_python#histogram
Ruby    #https://github.com/prometheus/client_ruby#histogram

Summary:

       类似于直方图,摘要会采样观察值(通常是请求持续时间和响应大小之类的东西)。尽管它还提供了观测值的总数和所有观测值的总和,但它可以计算滑动时间窗口内的可配置分位数。

     基本度量标准名称为<basename>的摘要会在刮擦期间显示多个时间序列:

         streaming观察到的事件的φ-quantiles (0 ≤ φ ≤ 1) ,显示为<basename>{quantile="<φ>"}

         所有观察值的总和,显示为<basename>_sum

         已观察到的事件计数,显示为<basename>_count

     有关φ分位数的详细说明,摘要用法以及与直方图的差异,请参见直方图和摘要。客户端库使用情况摘要文档:

Go    #https://godoc.org/github.com/prometheus/client_golang/prometheus#Summary
Java   #https://github.com/prometheus/client_java/blob/master/simpleclient/src/main/java/io/prometheus/client/Summary.java
Python  #https://github.com/prometheus/client_python#summary
Ruby    #https://github.com/prometheus/client_ruby#summary

2.3 JOBS AND INSTANCES(jobs和实例)

      用Prometheus术语来说,你可以抓取的端点称为实例,通常对应于单个进程。 具有相同目的的实例的集合(例如,出于可伸缩性或可靠性而复制的过程)称为job。例如,具有四个复制实例的API服务器作业:

job: api-server
    instance 1: 1.2.3.4:5670
    instance 2: 1.2.3.4:5671
    instance 3: 5.6.7.8:5670
    instance 4: 5.6.7.8:5671

Automatically generated labels and time series(自动生成的标签和时间序列):

     当Prometheus抓取目标时,它会自动在抓取的时间序列上附加一些标签,以识别被抓取的目标:

job:目标所属的已配置作业名称。
instance:已抓取的目标URL的<host>:<port>部分。

     如果在抓取的数据中已经存在这些标签中的任何一个,则行为取决于honor_labels配置选项。 有关更多信息,请参见抓取配置文档:https://prometheus.io/docs/prometheus/latest/configuration/configuration/#%3Cscrape_config%3E

     对于每个实例scrape,Prometheus按照以下时间序列存储样本:

up{job="<job-name>", instance="<instance-id>"}: 1如果实例运行状况良好(即可达),或者如果收集失败则为0。
scrape_duration_seconds{job="<job-name>", instance="<instance-id>"}: 搜集的持续时间。
scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"}: 应用度量标准重新标记后剩余的样本数。
scrape_samples_scraped{job="<job-name>", instance="<instance-id>"}:目标暴露的样本数。
scrape_series_added{job="<job-name>", instance="<instance-id>"}: 此scrape中新系列的大概数量。v2.10的新功能

     up时间序列对于实例可用性监视很有用。

三、Querying

3.1 Basics

       Prometheus提供了一种称为PromQL(Prometheus查询语言)的功能查询语言,使用户可以实时选择和汇总时间序列数据。 表达式的结果既可以显示为图形,也可以在Prometheus的表达式浏览器中显示为表格数据,也可以由外部系统通过HTTP API使用。

Examples

      本文档仅供参考。 对于学习而言,从几个示例开始可能会更容易:https://prometheus.io/docs/prometheus/latest/querying/examples/

Expression language data types(表达语言数据结构)

      在Prometheus的表达语言中,一个表达式或子表达式可以计算为以下四种类型之一:

Instant vector #一组时间序列,每个时间序列包含一个样本,所有样本共享相同的时间戳
Range vector #一组时间序列,其中包含每个时间序列随时间的一系列数据点
Scalar #一个简单的数字浮点值
String #一个简单的字符串值; 目前未使用

       根据用例(例如在绘制图形或显示表达式的输出时),由于用户指定的表达式的结果,其中只有某些类型是合法的。 例如,返回即时向量的表达式是唯一可以直接绘制图形的类型。

Literals(文字)

String literals(字符串文字)

      可以在单引号,双引号或反引号中将字符串指定为文字。PromQL遵循与Go相同的转义规则。 在单引号或双引号中,反斜杠开始一个转义序列,其后可以跟a, b, f, n, r, t, v or \。 可以使用八进制(\nnn)或十六进制(\xnn, \unnnn and \Unnnnnnnn)提供特定字符。

反引号内不会处理任何转义。 与Go不同,Prometheus不会在反引号内丢弃换行符。例:

"this is a string"
'these are unescaped: \n \\ \t'
`these are not unescaped: \n ' " \t`

Float literals(浮点文字)

      标量浮点值可以从字面上写为[-](digits)[.(digits)]形式的数字:-2.43

Time series Selectors(时间序列选择器)

Instant vector selectors(即时向量选择器)

       即时矢量选择器允许在给定的时间戳(即时)下选择一组时间序列和每个样本的单个样本值:以最简单的形式,仅指定度量名称。 这将导致一个即时向量,其中包含具有该度量名称的所有时间序列的元素。本示例选择所有具有http_requests_total指标名称的时间序列:

http_requests_total

      可以通过在大括号({})中附加一组匹配的标签来进一步过滤这些时间序列。本示例仅选择那些具有http_requests_total度量标准名称的时间序列,这些时间序列还将其工作标签设置为prometheus,其组标签设置为canary:

http_requests_total{job="prometheus",group="canary"}

       也可以否定地匹配标签值,或将标签值与正则表达式匹配。 存在以下标签匹配运算符:

=: 选择与提供的字符串完全相同的标签。
!=: 选择与提供的字符串不同的标签。
=~: 选择与提供的字符串进行正则表达式匹配的标签。
!~: 选择不与提供的字符串进行正则表达式匹配的标签。

       例如,这将选择所有http_requests_total时间序列用于暂存,测试和开发环境以及除GET之外的HTTP方法。

http_requests_total{environment=~"staging|testing|development",method!="GET"}

       匹配空标签值的标签匹配器还会选择所有根本没有设置特定标签的时间序列。 正则表达式匹配完全锚定。 同一标签名称可能有多个匹配器。向量选择器必须指定一个名称或至少一个与空字符串不匹配的标签匹配器。 以下表达式是非法的:

{job=~".*"} # Bad!

       相反,这些表达式都是有效的,因为它们都具有与空标签值不匹配的选择器。

{job=~".+"}              # Good!
{job=~".*",method="get"} # Good!

       通过与内部__name__标签进行匹配,标签匹配器也可以应用于度量标准名称。 例如,表达式http_requests_total等效于{__name__="http_requests_total"}。 也可以使用除= (!=, =~, !~)以外的匹配器。 以下表达式选择名称以job开头的所有度量:

{__name__=~"job:.*"}

      Prometheus中的所有正则表达式都使用RE2语法。

Range Vector Selectors(范围向量选择器)

      范围向量文字的工作方式与即时向量文字相同,不同之处在于它们从当前即时选择回采样范围。 语法上,将范围持续时间附加在向量选择器末尾的方括号([])中,以指定应为每个结果范围向量元素提取多远的时间值。持续时间以数字指定,后面紧跟以下单位之一:

s - seconds
m - minutes
h - hours
d - days
w - weeks
y - years

       在此示例中,我们选择所有时间序列在最近5分钟内记录的所有值,这些值的度量标准名称为http_requests_total且作业标签设置为prometheus:http_requests_total{job="prometheus"}[5m]

Offset modifier(偏移量修改器)

      offset修饰符允许更改查询中各个瞬时矢量和范围矢量的时间偏移。例如,以下表达式返回相对于当前查询评估时间过去5分钟的http_requests_total值:http_requests_total offset 5m

      请注意,offset修饰符始终需要立即跟随选择器,即以下内容将是正确的:

sum(http_requests_total{method="GET"} offset 5m) // GOOD.

       尽管以下内容将不正确:

sum(http_requests_total{method="GET"}) offset 5m // 无效。

      范围向量的工作原理相同。 这将返回http_requests_total一周前的5分钟费率:

rate(http_requests_total[5m] offset 1w)

Subquery(子查询)

     子查询允许您针对给定的范围和分辨率运行即时查询。 子查询的结果是范围向量。句法:<instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]。<resolution>是可选的。 默认值为全局评估间隔。

Operators(操作者)

Prometheus支持许多二进制和聚合运算符。 这些在表达式语言运算符页面中进行了详细描述。

Functions

Prometheus支持多种对数据进行操作的功能。 这些在表达语言功能页面中进行了详细描述。

Gotchas

Staleness

       运行查询时,将选择采样数据的时间戳,而不依赖于实际的当前时间序列数据。 这主要是为了支持诸如聚合(sum, avg,等)的情况,其中多个聚合时间序列未在时间上精确对齐。 由于它们的独立性,Prometheus需要为每个相关时间序列在那些时间戳上分配一个值。 只需在此时间戳之前获取最新样本即可。如果目标scrape或规则评估不再返回先前存在的时间序列的样本,则该时间序列将被标记为stale。 如果删除了目标,则其先前返回的时间序列将在不久后标记为stale。

      如果在某个时间序列标记为陈旧后以采样时间戳评估查询,则该时间序列不会返回任何值。 如果随后在该时间序列中摄取了新样本,则它们将照常返回。如果在采样时间戳记之前5分钟未找到样本(默认情况下),则该时间序列在此时间点不会返回任何值。 这实际上意味着,在最新采集的样本超过5分钟或标记为stale之后,时间序列会从图表中“disappear”。对于在scrapes中包含时间戳的时间序列,不会标记为Staleness。 在这种情况下,仅会应用5分钟的阈值。

Avoiding slow queries and overloads(避免慢查询和超载)

      如果查询需要处理大量数据,则对其进行图形化处理可能会超时或使服务器或浏览器超载。 因此,在对未知数据构建查询时,请始终在Prometheus表达式浏览器的表格视图中开始构建查询,直到结果集看起来合理为止(最多数百个时间序列,而不是数千个)。 仅当你充分过滤或汇总了数据后,才切换到图形模式。 如果该表达式仍无法花费很长时间来绘制ad-hoc图形,请通过记录规则将其pre-record记录。

3.2 OPERATORS(操作)

Binary operators(二元运算符)

Prometheus查询语言支持基本的逻辑和算术运算符。 对于两个即时向量之间的运算,可以修改匹配行为。

算术二进制运算符

Prometheus中存在以下二进制算术运算符:

+ (addition)
- (subtraction)
* (multiplication)
/ (division)
% (modulo)
^ (power/exponentiation)

在scalar/scalar, vector/scalar, and vector/vector value pairs(标量/标量,向量/标量和向量/向量值对)之间定义了二进制算术运算符。

在两个标量之间,其行为显而易见:它们求值另一个标量,这是将运算符应用于两个标量操作数的结果。

在瞬时向量和标量之间,将运算符应用于向量中每个数据样本的值。 例如。 如果将时间序列瞬时向量乘以2,则结果是另一个向量,其中原始向量的每个样本值都乘以2。

在两个即时向量之间,将二进制算术运算符应用于左侧向量中的每个条目,并将其应用于右侧向量中的匹配元素。 结果被传播到结果向量中,并且分组标签成为输出标签集。 指标名称已删除。 在右侧向量中找不到匹配条目的条目不属于结果。

比较二进制运算符

Prometheus中存在以下二进制比较运算符:

== (equal)
!= (not-equal)
> (greater-than)
< (less-than)
>= (greater-or-equal)
<= (less-or-equal)

在标量/标量,向量/标量和向量/向量值对之间定义比较运算符。 默认情况下,它们会过滤。 可以通过在运算符后提供bool来修改其行为,该布尔值将返回0或1而不是过滤。

在两个标量之间,必须提供bool修饰符,并且这些运算符会导致另一个标量为0 (false) or 1 (true),具体取决于比较结果。

在瞬时向量和标量之间,将这些运算符应用于向量中每个数据样本的值,并将比较结果为假的向量元素从结果向量中删除。 如果提供了bool修饰符,则要删除的矢量元素的值为0,要保留的矢量元素的值为1。

在两个即时向量之间,默认情况下,这些运算符充当过滤器,应用于匹配条目。 表达式不正确或在表达式另一侧找不到匹配项的向量元素将从结果中删除,而其他元素则传播到结果向量中,并且分组标签成为输出标签集。 如果提供了bool修饰符,则将被丢弃的矢量元素的值为0,将保留的矢量元素的值为1,并且分组标签再次成为输出标签集。

Logical/set binary operators(逻辑/集合二元运算符)

这些逻辑/集合二进制运算符仅在即时向量之间定义:

and (intersection)
or (union)
unless (complement)

vector1和vector2产生一个由vector1的元素组成的向量,为此vector2中的元素具有完全匹配的标签集。 其他元素被删除。 度量标准名称和值从左侧矢量继承。

vector1或vector2产生一个矢量,其中包含vector1的所有原始元素(label sets + values),以及vector2的所有元素,其中在vector1中没有匹配的标签集。

除非vector2产生一个由vector1的元素组成的向量,否则vector2中没有元素具有完全匹配的标签集。 两个向量中的所有匹配元素都将被删除。

Vector matching(向量匹配)

向量之间的运算会尝试在左侧向量中为左侧的每个条目找到匹配的元素。 匹配行为有两种基本类型:One-to-one and many-to-one/one-to-many。

One-to-one vector matches(一对一向量匹配)

一对一从操作的每一侧找到一对唯一的条目。 在默认情况下,这是遵循格式vector1 <operator> vector2的操作。 如果两个条目具有完全相同的一组标签和相应的值,则它们匹配。 ignoring关键字允许匹配时忽略某些标签,而on关键字允许将考虑的标签集减少到提供的列表中:

<vector expr> <bin-op> ignoring(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) <vector expr>

输入示例:

method_code:http_errors:rate5m{method="get", code="500"}  24
method_code:http_errors:rate5m{method="get", code="404"}  30
method_code:http_errors:rate5m{method="put", code="501"}  3
method_code:http_errors:rate5m{method="post", code="500"} 6
method_code:http_errors:rate5m{method="post", code="404"} 21

method:http_requests:rate5m{method="get"}  600
method:http_requests:rate5m{method="del"}  34
method:http_requests:rate5m{method="post"} 120

查询示例:

method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m

这将返回一个结果向量,其中包含最近5分钟内对每种方法的状态请求为500的HTTP请求所占的比例。 如果不ignoring(code),将不会有匹配项,因为度量标准不会共享同一组标签。 带有put和del方法的条目不匹配,并且不会显示在结果中:

{method="get"}  0.04            //  24 / 600
{method="post"} 0.05            //   6 / 120

Many-to-one and one-to-many vector matches(多对一和一对多向量匹配):

多对一和一对多匹配是指"one"-side上的每个矢量元素都可以与"many"-side上的多个元素匹配的情况。 必须使用group_left或group_right修饰符明确地请求它,其中left/right确定哪个向量具有更高的基数。

<vector expr> <bin-op> ignoring(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> ignoring(<label list>) group_right(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) group_left(<label list>) <vector expr>
<vector expr> <bin-op> on(<label list>) group_right(<label list>) <vector expr>

组修饰符随附的标签列表包含"one"-side的其他标签,这些标签将包含在结果指标中。 对于标签,只能出现在列表之一中。 结果向量的每个时间序列都必须是唯一可识别的。

分组修饰符只能用于比较和算术。 默认情况下,与和,除非和或运算与右向量中的所有可能条目匹配。查询示例:

method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m

在这种情况下,每个方法标签值的左向量包含一个以上的条目。 因此,我们使用group_left指示这一点。 现在,右侧的元素与左侧具有相同方法标签的多个元素匹配:

{method="get", code="500"}  0.04            //  24 / 600
{method="get", code="404"}  0.05            //  30 / 600
{method="post", code="500"} 0.05            //   6 / 120
{method="post", code="404"} 0.175           //  21 / 120

多对一和一对多匹配是应仔细考虑的高级用例。 通常,正确使用ignoring(<labels>) 可提供所需的结果。

Aggregation operators(集合运算符)

Prometheus支持以下内置的聚合运算符,这些运算符可用于聚合单个即时向量的元素,从而产生具有聚合值的较少元素的新向量:

sum (calculate sum over dimensions)
min (select minimum over dimensions)
max (select maximum over dimensions)
avg (calculate the average over dimensions)
stddev (计算维度上的总体标准差)
stdvar (计算维度上的总体标准方差)
count (count number of elements in the vector)
count_values (计算具有相同值的元素数)
bottomk (样本值最小的k个元素)
topk (样本值最大k个元素)
quantile (在尺寸上计算φ分位数(0≤φ≤1))

这些运算符既可以用于汇总所有标签维,也可以通过包含不带或按子句来保留不同的维。

<aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]

parameter仅对于count_values,quantile,topk和bottomk才需要此参数。without从结果向量中删除列出的标签,而所有其他标签将保留输出。 by会执行相反的操作并删除by子句中未列出的标签,即使它们的标签值在向量的所有元素之间相同。count_values每个唯一样本值输出一个时间序列。 每个系列都有一个附加标签。 该标签的名称由聚合参数指定,标签值为唯一样本值。 每个时间序列的值是样本值出现的次数。topk和bottomk与其他聚合器的不同之处在于,将输入样本的一个子集(包括原始标签)返回到结果向量中。 by和not仅用于存储输入向量。Example:如果度量标准http_requests_total具有按application, instance, and group labels散开的时间序列,则可以通过以下方式计算每个应用程序和组在所有实例上看到的HTTP请求总数:

sum(http_requests_total) without (instance)

等效于:

sum(http_requests_total) by (application, group)

如果我们只对在所有应用程序中看到的HTTP请求总数感兴趣,则可以简单地编写:

sum(http_requests_total)

要计算运行每个构建版本的二进制文件的数量,我们可以编写:

count_values("version", build_version)

为了获得所有实例中最大的5个HTTP请求计数,我们可以编写:

topk(5, http_requests_total)

二进制运算符优先级

下表显示了Prometheus中二进制运算符的优先级,从最高到最低。

^
*, /, %
+, -
==, !=, <=, <, >=, >
and, unless
or

优先级相同的运算符是左关联的。 例如,2 * 3 % 2等效于(2 * 3) % 2。但是^是右关联的,因此2 ^ 3 ^ 2等效于2 ^ (3 ^ 2)。

3.3 FUNCTIONS

某些函数具有默认参数,例如year(v=vector(time())。 这意味着有一个参数v是一个即时向量,如果不提供,它将默认为表达式vector(time())的值。

abs()

abs(v Instant-vector)返回将所有样本值转换为绝对值的输入向量。

absent()

如果传递给它的向量具有任何元素,则absent(v Instant-vector)返回一个空向量;如果传递给它的向量不具有任何元素,则absent(v Instant-vector)返回值为1的1元素向量。这对于在给定度量标准名称和标签组合不存在任何时间序列时发出警报非常有用。

absent(nonexistent{job="myjob"})
# => {job="myjob"}

absent(nonexistent{job="myjob",instance=~".*"})
# => {job="myjob"}

absent(sum(nonexistent{job="myjob"}))
# => {}

在第二个示例中,absent() 尝试从输入向量中导出1元素输出向量的标签变得很smart。

ceil()

ceil(v Instant-vector)将v中所有元素的样本值四舍五入到最接近的整数。

changes()

对于每个输入时间序列,changes(v range-vector)将其值在提供的时间范围内变化的次数作为即时向量返回。

clamp_max()

clamp_max(v instant-vector, max scalar) 将v中所有元素的样本值clamps为最大上限。

clamp_min()

clamp_min(v instant-vector, min scalar)将v中所有元素的样本值clamps为最小下限。

day_of_month()

day_of_month(v=vector(time()) instant-vector返回UTC中每个给定时间的月份。 返回值是1到31。

day_of_week()

day_of_week(v=vector(time()) instant-vector) 返回UTC中每个给定时间的星期几。 返回的值是从0到6,其中0表示星期日等。

days_in_month()

days_in_month(v=vector(time()) instant-vector)返回UTC中每个给定时间的月份中的天数。 返回值是28到31。

delta()

delta(v range-vector)计算范围向量v中每个时间序列元素的第一个值和最后一个值之间的差,返回具有给定delta和等效标签的即时向量。 根据范围向量选择器中的指定,可以将增量外推以覆盖整个时间范围,因此即使采样值都是整数,也可以获得非整数结果。以下示例表达式返回从现在到2小时前的CPU温度差异:

delta(cpu_temp_celsius{host="zeus"}[2h])

delta只能与压力表一起使用。

deriv()

deriv(v range-vector) 使用简单的线性回归来计算范围向量v中时间序列的每秒导数。deriv只能与压力表一起使用。

exp()

exp(v instant-vector)计算v中所有元素的指数函数。特殊情况是:

Exp(+Inf) = +Inf
Exp(NaN) = NaN

floor()

floor(v instant-vector)将v中所有元素的样本值向下舍入到最接近的整数。

histogram_quantile()

histogram_quantile(φ float, b instant-vector)从直方图的桶b计算φ分位数(0≤φ≤1)。有关φ分位数的详细说明以及总体上直方图度量类型的用法,请参见直方图和摘要。)b中的样本是每个存储桶中观察值的计数。 每个样本必须具有标签le,其中标签值表示存储桶的包含上限。 (不带标签的样本将被忽略。)直方图度量标准类型会自动提供带有_bucket后缀和适当标签的时间序列。

使用rate()函数指定分位数计算的时间窗口。示例:直方图指标称为http_request_duration_seconds。 要计算最近10m的请求持续时间的90%,请使用以下表达式:

histogram_quantile(0.9, rate(http_request_duration_seconds_bucket[10m]))

在http_request_duration_seconds中为每个标签组合计算分位数。 要进行汇总,请在rate()函数周围使用sum()汇总器。 由于histogram_quantile()要求使用le标签,因此必须将其包含在by子句中。 以下表达式按作业汇总了第90个百分点:

histogram_quantile(0.9, sum(rate(http_request_duration_seconds_bucket[10m])) by (job, le))

要汇总所有内容,请仅指定le标签:

histogram_quantile(0.9, sum(rate(http_request_duration_seconds_bucket[10m])) by (le))

histogram_quantile()函数通过假设存储桶内的线性分布来对分位数进行插值。 最高存储桶的上限必须为+ Inf。 (否则,返回NaN。)如果分位数位于最高存储桶中,则返回第二高存储桶的上限。 如果该存储桶的上限大于0,则将最低存储桶的下限假定为0。在这种情况下,通常在该存储桶中应用线性插值。 否则,将为位于最低存储桶中的分位数返回最低存储桶的上限。

如果b包含少于两个存储桶,则返回NaN。 如果φ<0,则返回-Inf。 对于φ> 1,返回+ Inf。

holt_winters()

holt_winters(v range-vector, sf scalar, tf scalar)

产生基于v的范围的时间序列的平滑值。平滑因子sf越低,则对旧数据的重视程度越高。 趋势因子tf越高,考虑的数据趋势就越多。 sf和tf都必须介于0和1之间。holt_winters仅应与gauges一起使用。

hour()

hour(v=vector(time()) instant-vector)返回UTC中每个给定时间的一天中的小时。 返回值是从0到23。

idelta()

idelta(v range-vector)计算范围向量v中最后两个样本之间的差,返回具有给定增量和等效标签的即时向量。idelta只能与gauges一起使用。

increase()

increase(v range-vector)计算范围向量中时间序列的增加。 单调性中断(例如由于目标重启而导致的计数器重置)会自动调整。 根据范围向量选择器中的指定,可以推断出增加的时间以覆盖整个时间范围,因此即使计数器仅以整数增量增加,也可以得到非整数结果。以下示例表达式返回范围向量中每个时间序列最近5分钟内测得的HTTP请求数:

increase(http_requests_total{job="api-server"}[5m])

increase只能与计数器一起使用。 它是rate(v)乘以指定时间范围窗口内的秒数的语法糖,应主要用于人类可读性。 记录规则中的使用率,以便在每秒的基础上持续跟踪增长情况。

irate()

irate(v range-vector)计算范围向量中时间序列的每秒瞬时增加率。 这基于最后两个数据点。 单调性中断(例如由于目标重启而导致的计数器重置)会自动调整。以下示例表达式返回范围向量中每个时间序列的两个最新数据点的HTTP请求的每秒速率,该速率最多可向后5分钟进行查询:

irate(http_requests_total{job="api-server"}[5m])

irate仅应在绘制易变,快速移动的计数器时使用。 警报和移动缓慢的计数器的使用率,因为率的短暂更改可以重置FOR子句,并且完全由罕见峰值组成的图形很难读取。请注意,将irate()聚合运算符(例如sum())或随时间进行聚合的函数(任何以_over_time结尾的函数)结合使用时,请始终先获取irate(),然后进行聚合。 否则,当目标重新启动时,irate()无法检测到计数器重置。

label_join()

对于v中的每个时间序列,label_join(v Instant-vector,dst_label字符串,分隔符字符串,src_label_1字符串,src_label_2字符串,...)使用分隔符将所有src_labels的所有值联接在一起,并返回带有包含已联接的标签dst_label的时间序列 值。 此函数中可以有任意数量的src_labels。此示例将返回一个向量,每个向量在每个时间序列上添加一个带有foo标签的值a,b,c:

label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")

label_replace()

对于v中的每个时间序列,label_replace(v即时向量,dst_label字符串,替换字符串,src_label字符串,正则表达式字符串)将正则表达式regex与标签src_label匹配。 如果匹配,则返回时间序列,其中标签dst_label被替换为替换扩展。 $1被第一个匹配的子组替换,$2被第二个匹配的子组替换。如果正则表达式不匹配,则时间序列将保持不变。此示例将返回一个向量,每个向量的每个时间序列都带有一个foo标签,并在其中添加了a值:

label_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.*):.*")

ln()

ln(v instant-vector)计算v中所有元素的自然对数。特殊情况是:

ln(+Inf) = +Inf
ln(0) = -Inf
ln(x < 0) = NaN
ln(NaN) = NaN

log2()

log2(v instant-vector)计算v中所有元素的二进制对数。特殊情况与ln中的情况相同。

log10()

log10(v instant-vector)计算v中所有元素的十进制对数。特殊情况与ln中的情况相同。

minute()

minute(v=vector(time()) instant-vector)返回UTC中每个给定时间的小时分钟。 返回值是从0到59。

month()

month(v=vector(time()) instant-vector)返回UTC中每个给定时间的一年中的月份。 返回值是从1到12,其中1表示一月等。

predict_linear()

predict_linear(v range-vector, t scalar)使用简单的线性回归,基于范围向量v预测从现在开始的时间序列t秒的值。predict_linear仅应与gauges一起使用。

rate()

rate(v range-vector)计算范围向量中时间序列的每秒平均平均增长率。 单调性中断(例如由于目标重启而导致的计数器重置)会自动调整。 同样,计算会外推到时间范围的末尾,从而允许遗漏刮擦或刮擦周期与该范围的时间段不完全对齐。以下示例表达式返回范围向量中每个时间序列最近5分钟内测得的HTTP请求的每秒速率:

rate(http_requests_total{job="api-server"}[5m])

rate只能与计数器一起使用。 它最适合于警报以及慢速计数器的图形显示。请注意,在将rate()与聚集运算符(例如sum())或随时间聚集的函数(以_over_time结尾的任何函数)结合使用时,请始终先获取rate(),然后再进行聚集。 否则,当目标重新启动时,rate()无法检测到计数器重置。

resets()

对于每个输入时间序列,resets(v range-vector)返回提供的时间范围内的计数器重置次数作为即时向量。 两个连续采样之间的值的任何减少都将解释为计数器复位。resets只能与counters一起使用。

round()

round(v instant-vector, to_nearest=1 scalar)将v中所有元素的样本值四舍五入到最接近的整数。 Ties通过四舍五入解决。 可选的to_nearest参数允许指定样本值应四舍五入到的最接近倍数。 该倍数也可以是分数。

scalar()

给定一个单元素输入向量,scalar(v Instant-vector)返回该单个元素的样本值作为标量。 如果输入向量不完全具有一个元素,则标量将返回NaN。

sort()

sort(v instant-vector)返回按其样本值升序排列的向量元素。

sort_desc()

与排序相同,但按降序排序。

sqrt()

sqrt(v instant-vector)计算v中所有元素的平方根。

time()

time()返回自1970年1月1日UTC以来的秒数。 请注意,这实际上并不返回当前时间,而是返回要计算表达式的时间。

timestamp()

timestamp(v instant-vector) 返回给定向量的每个样本的时间戳记,作为自1970年1月1日UTC以来的秒数。该功能已在Prometheus 2.0中添加

vector()

vector(s scalar)将标量s作为没有标签的向量返回。

year()

year(v=vector(time()) instant-vector)返回UTC中每个给定时间的年份。

<aggregation>_over_time()

以下函数允许随着时间的推移聚合给定范围矢量的每个序列,并返回具有每个序列聚合结果的即时向量:

avg_over_time(range-vector): 指定间隔中所有点的平均值。
min_over_time(range-vector): 指定间隔中所有点的最小值.
max_over_time(range-vector): 指定间隔中所有点的最大值.
sum_over_time(range-vector): 指定时间间隔内所有值的总和.
count_over_time(range-vector): 指定间隔中所有值的计数.
quantile_over_time(scalar, range-vector): 指定间隔中值的φ分位数(0≤φ≤1).
stddev_over_time(range-vector): 指定间隔内值的总体标准偏差.
stdvar_over_time(range-vector): 指定间隔内值的总体标准方差.

请注意,即使在整个时间间隔内这些值的间隔不相等,指定时间间隔内的所有值在聚合中的权重也相同。

3.4 EXAMPLES

简单的时间序列选择

返回所有带有度量http_requests_total的时间序列:

http_requests_total

返回所有带有度量http_requests_total以及给定 job and handler标签的时间序列:

http_requests_total{job="apiserver", handler="/api/comments"}

返回相同向量的整个时间范围(在本例中为5分钟),使其成为范围向量:

http_requests_total{job="apiserver", handler="/api/comments"}[5m]

请注意,无法直接绘制导致范围向量的表达式,而只能在表达式浏览器的表格视图("Console")中查看。使用正则表达式,你可以只为名称与特定模式匹配的作业选择时间序列,在这种情况下,所有以服务器结尾的作业:

http_requests_total{job=~".*server"}

Prometheus中的所有正则表达式都使用RE2语法(https://github.com/google/re2/wiki/Syntax)。要选择除4xx之外的所有HTTP状态代码,可以运行:

http_requests_total{status!~"4.."}

Subquery(子查询):

返回过去30分钟的http_requests_total指标的5分钟速率,resolution为1分钟。

rate(http_requests_total[5m])[30m:1m]

这是一个嵌套子查询的示例。 deriv函数的子查询使用默认分辨率。 请注意,不必要地使用子查询是不明智的。

max_over_time(deriv(rate(distance_covered_total[5s])[30s:5s])[10m:])

Using functions, operators, etc(使用函数,运算符等)

返回最近5分钟测得的所有具有http_requests_total指标名称的所有时间序列的每秒速率:

rate(http_requests_total[5m])

假设http_requests_total时间序列全部具有标签job(fanout by job name)和实例(fanout by instance of the job),则我们可能希望对所有实例的比率求和,因此得到的输出时间序列较少,但仍然 保留工作维度:

sum(rate(http_requests_total[5m])) by (job)

如果我们有两个具有相同维标签的不同度量,则可以对它们应用二元运算符,并且具有相同标签集的两侧的元素都将被匹配并传播到输出。 例如,此表达式为每个实例返回MiB中未使用的内存(在虚构的群集调度程序上,公开了有关其运行的实例的这些指标):

(instance_memory_limit_bytes - instance_memory_usage_bytes) / 1024 / 1024

相同的表达式,但由应用程序求和,可以这样写:

sum(
  instance_memory_limit_bytes - instance_memory_usage_bytes
) by (app, proc) / 1024 / 1024

如果相同的虚拟群集调度程序针对每个实例公开了以下CPU使用率指标:

instance_cpu_time_ns{app="lion", proc="web", rev="34d0f99", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="elephant", proc="worker", rev="34d0f99", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="turtle", proc="api", rev="4d3a513", env="prod", job="cluster-manager"}
instance_cpu_time_ns{app="fox", proc="widget", rev="4d3a513", env="prod", job="cluster-manager"}
...

...我们可以获得按应用程序(app)和进程类型(proc)分组的前3位CPU用户:

topk(3, sum(rate(instance_cpu_time_ns[5m])) by (app, proc))

假设此指标每个运行实例包含一个时间序列,您可以像这样计算每个应用程序的运行实例数:

count(instance_cpu_time_ns) by (app)

3.5 HTTP API

参考官网:https://prometheus.io/docs/prometheus/latest/querying/api/



作者:忙碌的柴少 分类:prometheus 浏览:8963 评论:6
留言列表
btlinux
btlinux 牛批 真的很详细 早看到这个文档 我之前也不会被折磨那么久  回复
btlinux
btlinux 柴少出品 必属精品  回复
忙碌的柴少
忙碌的柴少 没有没有,大家都是前行者而已!  回复
匿名者
匿名者 这可能是我见过的写的最好的博客之一了,很详细,想问下楼主的学习方法是怎样的!!!默默问下,楼主是搞运维的么?  回复
访客
访客 嗯屌丝运维一枚,多看资料多实操,都是应用层的东西也没啥捷径,然后结合自己的实际重点学习。  回复
访客
访客 最近才发现的宝藏博客 赞  回复
发表评论
来宾的头像