一、PromQL介绍

PromQL(Prometheus Query Language)为Prometheus tsdb的查询语言。是结合grafana进行数据展示和告警规则的配置的关键部分。

  • 官方文档:prometheus.io/docs/promet…
  • 关于Prometheus全体介绍,能够参阅我这篇文章:Prometheus原理详解
  • Prometheus和Pushgetway的安装,能够参阅我这篇文章:【云原生】Prometheus Pushgetway解说与实战操作
  • 关于AlertManager介绍,能够参阅我这篇文章:【云原生】Prometheus AlertManager解说与实战操作

二、四种方针类型

  • counter(计数器)
  • gauge (仪表类型)
  • histogram(直方图类型)
  • summary (摘要类型)

1)counter(计数器)

Counter (只增不减的计数器) 类型的方针其工作办法和计数器一样,只增不减。常见的监控方针,如 http_requests_totalnode_cpu_seconds_total 都是 Counter 类型的监控方针。

在 node-exporter 回来的样本数据中,其注释中也包括了该样本的类型。例如:

# HELP node_cpu_seconds_total Seconds the cpus spent in each mode.
# TYPE node_cpu_seconds_total counter
node_cpu_seconds_total{cpu="cpu0",mode="idle"} 362812.7890625
  • #HELP:解释当时方针的含义,上面表明在每种方式下node节点的cpu花费的时刻,以s为单位。
  • #TYPE:阐明当时方针的数据类型,上面是counter类型。

counter 是一个简略但又强壮的工具,例如咱们能够在应用程序中记载某些事件产生的次数,经过以时刻序列的方式存储这些数据,咱们能够轻松的了解该事件产生的速率改变。PromQL 内置的聚合操作和函数能够让用户对这些数据进行进一步的剖析,例如,经过 rate() 函数获取 HTTP 恳求量的增长率:

rate(http_requests_total[5m])

查询当时体系中,访问量前 10 的 HTTP 恳求:

topk(10, http_requests_total)

2)gauge (仪表类型)

Counter 不同, Gauge(可增可减的仪表盘)类型的方针侧重于反响体系的当时状态。因而这类方针的样本数据可增可减。常见方针如:node_memory_MemFree_bytes(主机当时空闲的内存巨细)、 node_memory_MemAvailable_bytes(可用内存巨细)都是 Gauge 类型的监控方针。经过 Gauge 方针,用户能够直接检查体系的当时状态:

node_memory_MemFree_bytes

对于 Gauge 类型的监控方针,经过 PromQL 内置函数 delta() 能够获取样本在一段时刻规模内的改变状况。例如,核算 CPU 温度在两个小时内的差异:

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

还能够直接运用 predict_linear() 对数据的改变趋势进行猜测。例如,猜测体系磁盘空间在4个小时之后的剩余状况:

predict_linear(node_filesystem_free_bytes[1h], 4 * 3600)

3)Histogram(直方图类型) 和 Summary(摘要类型)

除了 CounterGauge 类型的监控方针以外,Prometheus 还界说了 HistogramSummary 的方针类型。HistogramSummary 主用用于核算和剖析样本的散布状况。

  • 在大多数状况下人们都倾向于运用某些量化方针的均匀值,例如 CPU 的均匀运用率、页面的均匀呼应时刻,这种办法也有很明显的问题,以体系 API 调用的均匀呼应时刻为例:假如大多数 API 恳求都维持在 100ms 的呼应时刻规模内,而个别恳求的呼应时刻需求 5s,那么就会导致某些 WEB 页面的呼应时刻落到中位数上,而这种现象被称为长尾问题
  • 为了区别是均匀的慢仍是长尾的慢,最简略的办法便是依照恳求推迟的规模进行分组。例如,核算推迟在 010ms 之间的恳求数有多少而 1020ms 之间的恳求数又有多少。经过这种办法能够快速剖析体系慢的原因。HistogramSummary 都是为了能够处理这样的问题存在的,经过 HistogramSummary 类型的监控方针,咱们能够快速了解监控样本的散布状况。

例如,方针 prometheus_tsdb_wal_fsync_duration_seconds 的方针类型为 Summary。它记载了 Prometheus Server 中 wal_fsync 的处理时刻,经过访问 Prometheus Server 的 /metrics 地址,能够获取到以下监控样本数据:

# HELP prometheus_tsdb_wal_fsync_duration_seconds Duration of WAL fsync.
# TYPE prometheus_tsdb_wal_fsync_duration_seconds summary
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.5"} 0.012352463
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.9"} 0.014458005
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.99"} 0.017316173
prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
prometheus_tsdb_wal_fsync_duration_seconds_count 216

从上面的样本中能够得知当时 Prometheus Server 进行 wal_fsync 操作的总次数为216次,耗时2.888716127000002s。其间中位数(quantile=0.5)的耗时为0.012352463,9分位数(quantile=0.9)的耗时为0.014458005s。

在 Prometheus Server 本身回来的样本数据中,咱们还能找到类型为 Histogram 的监控方针 prometheus_tsdb_compaction_chunk_range_seconds_bucket

# HELP prometheus_tsdb_compaction_chunk_range_seconds Final time range of chunks on their first compaction
# TYPE prometheus_tsdb_compaction_chunk_range_seconds histogram
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="100"} 71
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="400"} 71
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="1600"} 71
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="6400"} 71
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="25600"} 405
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="102400"} 25690
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="409600"} 71863
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="1.6384e+06"} 115928
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="6.5536e+06"} 2.5687892e+07
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="2.62144e+07"} 2.5687896e+07
prometheus_tsdb_compaction_chunk_range_seconds_bucket{le="+Inf"} 2.5687896e+07
prometheus_tsdb_compaction_chunk_range_seconds_sum 4.7728699529576e+13
prometheus_tsdb_compaction_chunk_range_seconds_count 2.5687896e+07

Summary 类型的方针相似之处在于 Histogram 类型的样本同样会反响当时方针的记载的总数(以 _count 作为后缀)以及其值的总量(以 _sum 作为后缀)。不同在于 Histogram 方针直接反响了在不同区间内样本的个数,区间经过标签 le 进行界说。

三、表达式四种数据类型

PromQL查询语句即表达式,实现的四种数据类型:

  • 瞬时向量(Instant vector):一组时刻序列,每个时刻序列包括单个样本,它们同享相同的时刻戳。也便是说,表达式的回来值中只会包括该时刻序列中最新的一个样本值。

  • 区间向量(Range vector):一组时刻序列,每个时刻序列包括一段时刻规模内的样本数据。

  • 标量(Scalar):一个浮点型的数据值,没有时序。能够写成[-](digits)[.(digits)]的方式。需求留意的是,运用表达式count(http_requests_total)回来的数据类型依然是瞬时向量,用户能够经过内置函数scalar()将单个瞬时向量转换为标量。

  • 字符串(String):一个简略的字符串值。字符串能够用单引号(”)、双引号(””)或反引号(“)来指定。

1)瞬时向量(Instant vector)

Instance vector(瞬时向量)表明一个时刻序列的调集,可是每个时序只要最近的一个点,而不是线。

【云原生】Prometheus PromQL讲解与实战操作

2)区间向量(Range vector)

Range vector(规模向量)表明一段时刻规模里的时序,每个时序可包括多个点 。

【云原生】Prometheus PromQL讲解与实战操作

3)标量(Scalar)

Scalar(标量)一般为数值,能够将只要一个时序的Instance vector转换成Scalar。

4) 字符串(String)

一个简略的字符串值。字符串能够用单引号(”)、双引号(””)或反引号(“)来指定。

四、时刻序列(向量)

依照时刻次序记载体系、设备状态改变的数据,每个数据成为一个样本。

  • 数据采集以特定的时刻周期进行,因而,随着时刻消逝,将这些样本数据记载下来,将生成一个离散的样本数据序列。
  • 该序列也称为向量(Vector),以时刻轴为横坐标、序列为纵坐标,这些数据点连接起来就会构成一个矩阵。

【云原生】Prometheus PromQL讲解与实战操作

1)时刻序列的构成

每条时刻序列(Time Series)是经过方针称号(Metrics name)和一组标签集(Label set)来命名的。

假如time相同,可是方针称号或许标签集不同,那么时刻序列也不同。

2)样本构成

矩阵中每一个点都可称为一个样本(Sample),样本首要由3方面构成。

  • 方针(Metrics):包括方针称号(Metrics name)和一组标签集(Label set)称号,如request_total{path=”/status”,method=”GET”}。
  • 时刻戳(TimeStamp):这个值默许准确到毫秒。
  • 样本值(Value):这个值默许运用Float64浮点类型。

时刻序列的方针(Metrics)存储格式为key-value。

【云原生】Prometheus PromQL讲解与实战操作

http_request_total{status=”200″,method=”GET”}@1434417560938=>94355为例,在Key-Value联系中,94355作为Value(也便是样本值Sample Value),前面的http_request_total{status=”200″,method=”GET”}@1434417560938一概作为Key。

3)key的组成

  • Metric Name:方针名(比方中的http_request_total)
  • Label:标签(比方中的{status=”200″,method=”GET”})
  • Timestamp:时刻戳(比方中的@1434417560938)

Prometheus Metrics两种表现方式:

【云原生】Prometheus PromQL讲解与实战操作

五、标签过滤器4种运算符

  • =:与字符串匹配
  • !=:与字符串不匹配
  • =~:与正则匹配
  • !~:与正则不匹配

1)匹配器(Matcher)

匹配器是作用于标签上的,标签匹配器能够对时刻序列进行过滤,Prometheus支撑彻底匹配和正则匹配两种方式:彻底匹配正则表达式匹配

2)彻底匹配

1、持平匹配器(=)

持平匹配器(Equality Matcher),用于挑选与供给的字符串彻底相同的标签。下面介绍的比方中就会运用持平匹配器依照条件进行一系列过滤。

node_cpu_seconds_total{instance="ydzs-master"}

2、不持平匹配器(!=)

不持平匹配器(Negative Equality Matcher),用于挑选与供给的字符串不相同的标签。它和持平匹配器是彻底相反的。举个比方,假如想要检查job并不是HelloWorld的HTTP恳求总数,能够运用如下不持平匹配器。

3)正则表达式匹配

1、正则表达式匹配器(=~)

正则表达式匹配器(Regular Expression Matcher),用于挑选与供给的字符串进行正则运算后所得成果相匹配的标签。Prometheus的正则运算是强指定的,比方正则表达式a只会匹配到字符串a,而并不会匹配到ab或许ba或许abc。假如你不想运用这样的强指定功用,能够在正则表达式的前面或许后边加上“.*”。比方下面的比方表明job是一切以Hello最初的HTTP恳求总数。

node_cpu_seconds_total{instance=~"ydzs-.*", mode="idle"}

node_cpu_seconds_total直接等效于**{__name__=”node_cpu_seconds_total”},后者也能够运用和前者一样的4种匹配器(=,!=,=,!**)。比方下面的案例能够表明一切以Hello最初的方针。

{__name__="node_cpu_seconds_total",instance=~"ydzs-.*", mode="idle"}

2、正则表达式相反匹配器(!~)

正则表达式相反匹配器(Negative Regular Expression Matcher),用于挑选与供给的字符串进行正则运算后所得成果不匹配的标签。因为PromQL的正则表达式根据RE2的语法,可是RE2不支撑向前不匹配表达式,所以**!~**的出现是作为一种替代计划,以实现根据正则表达式扫除指定标签值的功用。在一个挑选器当中,能够针对同一个标签来运用多个匹配器。比方下面的比方,能够实现查找job名是node且安装在/prometheus目录下,可是并不在/prometheus/user目录下的一切文件体系并确认其巨细。

node_filesystem_size_bytes{job="node",mountpoint=~"/prometheus/.*", mountpoint!~ "/prometheus/user/.*"}

六、规模挑选器

咱们能够经过将时刻规模挑选器([])(prometheus.io/docs/promet…

时刻规模经过数字来表明,单位能够运用以下其间之一的时刻单位:

  • s – 秒
  • m – 分钟
  • h – 小时
  • d – 天
  • w – 周
  • y – 年

比方 node_cpu_seconds_total{instance="ydzs-master",mode="idle"} 这个查询语句,假如添加上 [1m] 这个时刻规模挑选器,则咱们能够得到如下所示的信息:

node_cpu_seconds_total{instance="ydzs-master",mode="idle"}[5m]

【云原生】Prometheus PromQL讲解与实战操作

这是因为现在每一个时刻序列中都有多个时刻戳多个值,所以没办法渲染,有必要是标量或许瞬时向量才能够制作图形。

不过一般区间向量都会应用一个函数后变成能够制作的瞬时向量,Prometheus 中对瞬时向量和区间向量有很多操作的函数(prometheus.io/docs/promet…

  • rate(): 核算整个时刻规模内区间向量中时刻序列的每秒均匀增长率。
  • irate(): 仅运用时刻规模中的最终两个数据点来核算区间向量中时刻序列的每秒均匀增长率, irate 只能用于制作快速改变的序列,在长期趋势剖析或许告警中更引荐运用 rate 函数。
  • increase(): 核算所选时刻规模内时刻序列的增量,它基本上是速率乘以时刻规模挑选器中的秒数。

七、PromQL 运算符

1)数学运算符

数学运算符比较简略,便是简略的加减乘除等。

例如:咱们经过 prometheus_http_response_size_bytes_sum 能够查询到 Prometheus 这个应用的 HTTP 呼应字节总和。可是这个单位是字节,咱们期望用 MB 显现。那么咱们能够这么设置:prometheus_http_response_size_bytes_sum/8/1024

PromQL支撑的一切数学运算符如下所示:

  • + (加法)
  • - (减法)
  • * (乘法)
  • / (除法)
  • % (求余)
  • ^ (幂运算)

2)布尔运算符

布尔运算符支撑用户根据时刻序列中样本的值,对时刻序列进行过滤。

例如:咱们能够经过 prometheus_http_requests_total 查询出每个接口的恳求次数,可是假如咱们想筛选出恳求次数超过 20 次的接口呢?

此刻咱们能够用下面的 PromQL 表达式:

prometheus_http_requests_total > 20

【云原生】Prometheus PromQL讲解与实战操作

从上面的图中咱们能够看到,value 的值仍是详细的数值。但假如咱们期望对契合条件的数据,value 变为 1。不契合条件的数据,value 变为 0。那么咱们能够运用bool修饰符。

咱们运用下面的 PromQL 表达式:

prometheus_http_requests_total > bool 20

现在,Prometheus支撑以下布尔运算符如下:

  • ==(持平)
  • !=(不持平)
  • >(大于)
  • <(小于)
  • >=(大于或等于)
  • <=(小于或等于)

3)调集运算符

经过调集运算,能够在两个瞬时向量与瞬时向量之间进行相应的调集操作。现在,Prometheus支撑以下调集运算符:

  • and 与操作
  • or 或操作
  • unless 扫除操作

1、and 与操作

vector1 and vector2 进行一个与操作,会产生一个新的调集。该调集中的元素同时在 vector1 和 vector2 中都存在。

例如:咱们有 vector1 为 A B C,vector2 为 B C D,那么 vector1 and vector2 的成果为:B C。

2、or 或操作

vector1 and vector2 进行一个或操作,会产生一个新的调集。该调集中包括 vector1 和 vector2 中的一切元素。

例如:咱们有 vector1 为 A B C,vector2 为 B C D,那么 vector1 or vector2 的成果为:A B C D。

3、unless 扫除操作

vector1 and vector2 进行一个或操作,会产生一个新的调集。该调集首先取 vector1 调集的一切元素,然后扫除去一切在 vector2 中存在的元素。

例如:咱们有 vector1 为 A B C,vector2 为 B C D,那么 vector1 unless vector2 的成果为:A。

4)操作符优先级

在PromQL操作符中优先级由高到低顺次为:

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

八、PromQL 内置函数

Prometheus 供给了其它很多的内置函数,能够对时序数据进行丰富的处理。某些函数有默许的参数,例如:year(v=vector(time()) instant-vector)。其间参数 v 是一个瞬时向量,假如不供给该参数,将运用默许值 vector(time())。instant-vector 表明参数类型。

1) abs()

abs(v instant-vector) 回来输入向量的一切样本的绝对值。

2)absent()

absent(v instant-vector),假如传递给它的向量参数具有样本数据,则回来空向量;假如传递的向量参数没有样本数据,则回来不带衡量方针称号且带有标签的时刻序列,且样本值为1。

当监控衡量方针时,假如获取到的样本数据是空的, 运用 absent 办法对告警对错常有用的。例如:

# 这儿供给的向量有样本数据
absent(http_requests_total{method="get"})  => no data
absent(sum(http_requests_total{method="get"}))  => no data
# 因为不存在衡量方针 nonexistent,所以 回来不带衡量方针称号且带有标签的时刻序列,且样本值为1
absent(nonexistent{job="myjob"})  => {job="myjob"}  1
# 正则匹配的 instance 不作为回来 labels 中的一部分
absent(nonexistent{job="myjob",instance=~".*"})  => {job="myjob"}  1
# sum 函数回来的时刻序列不带有标签,且没有样本数据
absent(sum(nonexistent{job="myjob"}))  => {}  1

3)ceil()

ceil(v instant-vector) 将 v 中一切元素的样本值向上四舍五入到最接近的整数。例如:

node_load5{instance="192.168.1.75:9100"} # 成果为 2.79
ceil(node_load5{instance="192.168.1.75:9100"}) # 成果为 3

4)changes()

changes(v range-vector) 输入一个区间向量, 回来这个区间向量内每个样本数据值改变的次数(瞬时向量)。例如:

# 假如样本数据值没有产生改变,则回来成果为 1
changes(node_load5{instance="192.168.1.75:9100"}[1m]) # 成果为 1

5)clamp_max()

clamp_max(v instant-vector, max scalar)函数,输入一个瞬时向量和最大值,样本数据值若大于 max,则改为 max,不然不变。例如:

node_load5{instance="192.168.1.75:9100"} # 成果为 2.79
clamp_max(node_load5{instance="192.168.1.75:9100"}, 2) # 成果为 2

6)clamp_min()

clamp_min(v instant-vector, min scalar)函数,输入一个瞬时向量和最小值,样本数据值若小于 min,则改为 min,不然不变。例如:

node_load5{instance="192.168.1.75:9100"} # 成果为 2.79
clamp_min(node_load5{instance="192.168.1.75:9100"}, 3) # 成果为 3

7)day_of_month()

day_of_month(v=vector(time()) instant-vector)函数,回来被给定 UTC 时刻地点月的第几天。回来值规模:1~31。

8)day_of_week()

day_of_week(v=vector(time()) instant-vector) 函数,回来被给定 UTC 时刻地点周的第几天。回来值规模:0~6,0 表明星期天。

9)days_in_month()

days_in_month(v=vector(time()) instant-vector)函数,回来当月一共有多少天。回来值规模:28~31。

10)delta()

delta(v range-vector)的参数是一个区间向量,回来一个瞬时向量。它核算一个区间向量 v 的第一个元素和最终一个元素之间的差值。因为这个值被外推到指定的整个时刻规模,所以即便样本值都是整数,你依然可能会得到一个非整数值。

例如,下面的比方回来曩昔两小时的 CPU 温度差:

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

11)deriv()

deriv(v range-vector)的参数是一个区间向量,回来一个瞬时向量。它运用简略的线性回归核算区间向量 v 中各个时刻序列的导数。这个函数一般只用在 Gauge 类型的时刻序列上。

12)exp()

exp(v instant-vector) 函数,输入一个瞬时向量,回来各个样本值的 e 的指数值,即 e 的 N 次方。当 N 的值足够大时会回来 +Inf。特殊状况为:

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

13)floor()

floor(v instant-vector)函数与 ceil() 函数相反,将 v 中一切元素的样本值向下四舍五入到最接近的整数。

14)histogram_quantile()

histogram_quantile( float, b instant-vector) 从 bucket 类型的向量 b 中核算 (0 ≤ ≤ 1) 分位数(百分位数的一般方式)的样本的最大值。(有关 分位数的详细阐明以及直方图方针类型的运用,请参阅直方图和摘要)。向量 b 中的样本是每个 bucket 的采样点数量。每个样本的 labels 中有必要要有 le 这个 label 来表明每个 bucket 的上边界,没有 le 标签的样本会被疏忽。直方图方针类型主动供给带有 _bucket 后缀和相应标签的时刻序列。能够运用 rate() 函数来指定分位数核算的时刻窗口。

例如:一个直方图方针称号为 employee_age_bucket_bucket,要核算曩昔 10 分钟内 第 90 个百分位数,请运用以下表达式:

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

回来:

{instance="10.0.86.71:8080",job="prometheus"} 35.714285714285715

这表明最近 10 分钟之内 90% 的样本的最大值为 35.714285714285715。

15)holt_winters()

holt_winters(v range-vector, sf scalar, tf scalar)函数根据区间向量 v,生成时刻序列数据滑润值。滑润因子 sf 越低, 对旧数据的注重程度越高。趋势因子 tf 越高,对数据的趋势的考虑就越多。其间,0< sf, tf <=1。holt_winters 仅适用于 Gauge 类型的时刻序列。

16)hour()

hour(v=vector(time()) instant-vector)函数回来被给定 UTC 时刻的当时第几个小时,时刻规模:0~23。

17)idelta()

idelta(v range-vector)的参数是一个区间向量, 回来一个瞬时向量。它核算最新的 2 个样本值之间的差值。 这个函数一般只用在 Gauge 类型的时刻序列上。

18)increase()

increase(v range-vector)函数获取区间向量中的第一个和最终一个样本并回来其增长量, 它会在单调性产生改变时(如因为采样方针重启引起的计数器复位)主动中止。因为这个值被外推到指定的整个时刻规模,所以即便样本值都是整数,你依然可能会得到一个非整数值。

例如:以下表达式回来区间向量中每个时刻序列曩昔 5 分钟内 HTTP 恳求数的增长数:

increase(http_requests_total{job="apiserver"}[5m])

increase 的回来值类型只能是计数器类型,首要作用是增加图表和数据的可读性。运用 rate 函数记载规则的运用率,以便继续跟踪数据样本值的改变。

19)irate()

irate(v range-vector) 函数用于核算区间向量的增长率,可是其反响出的是瞬时增长率。irate 函数是经过区间向量中最终两个两本数据来核算区间向量的增长速率,它会在单调性产生改变时(如因为采样方针重启引起的计数器复位)主动中止。这种办法能够防止在时刻窗口规模内的“长尾问题”,并且体现出更好的灵敏度,经过irate函数制作的图标能够更好的反响样本数据的瞬时改变状态。

例如:以下表达式回来区间向量中每个时刻序列曩昔 5 分钟内最终两个样本数据的 HTTP 恳求数的增长率:

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

20)label_join()

label_join(v instant-vector, dst_label string, separator string, src_label_1 string, src_label_2 string, ...)函数能够将时刻序列 v 中多个标签 src_label 的值,经过 separator 作为连接符写入到一个新的标签 dst_label 中。能够有多个 src_label 标签。

例如:以下表达式回来的时刻序列多了一个 foo 标签,标签值为 etcd,etcd-k8s:

up{endpoint="api",instance="192.168.123.248:2379",job="etcd",namespace="monitoring",service="etcd-k8s"}
=> up{endpoint="api",instance="192.168.123.248:2379",job="etcd",namespace="monitoring",service="etcd-k8s"}  1
label_join(up{endpoint="api",instance="192.168.123.248:2379",job="etcd",namespace="monitoring",service="etcd-k8s"}, "foo", ",", "job", "service")
=> up{endpoint="api",foo="etcd,etcd-k8s",instance="192.168.123.248:2379",job="etcd",namespace="monitoring",service="etcd-k8s"}  1

21)label_replace()

为了能够让客户端的图标更具有可读性,能够经过 label_replace 函数为时刻序列添加额外的标签。label_replace 的详细参数如下:

label_replace(v instant-vector, dst_label string, replacement string, src_label string, regex string)

该函数会顺次对 v 中的每一条时刻序列进行处理,经过 regex 匹配 src_label 的值,并将匹配部分 relacement 写入到 dst_label 标签中。如下所示:

label_replace(up, "host", "$1", "instance",  "(.*):.*")

函数处理后,时刻序列将包括一个 host 标签,host 标签的值为 Exporter 实例的 IP 地址:

up{host="localhost",instance="localhost:8080",job="cadvisor"}   1
up{host="localhost",instance="localhost:9090",job="prometheus"}   1
up{host="localhost",instance="localhost:9100",job="node"}   1

22)ln()

ln(v instant-vector) 核算瞬时向量 v 中一切样本数据的自然对数。特殊状况:

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

23)log2()

log2(v instant-vector)函数核算瞬时向量 v 中一切样本数据的二进制对数。特殊状况同上。

24)log10()

log10(v instant-vector) 核算瞬时向量 v 中一切样本数据的十进制对数。特殊状况同上。

25)minute()

minute(v=vector(time()) instant-vector)函数回来给定 UTC 时刻当时小时的第多少分钟。成果规模:0~59。

26)month()

month(v=vector(time()) instant-vector)函数回来给定 UTC 时刻当时属于第几个月,成果规模:0~12。

27)predict_linear()

predict_linear(v range-vector, t scalar)函数能够猜测时刻序列 v 在 t 秒后的值。它根据简略线性回归的办法,对时刻窗口内的样本数据进行核算,从而能够对时刻序列的改变趋势做出猜测。该函数的回来成果不带有衡量方针,只要标签列表。

例如,根据 2 小时的样本数据,来猜测主机可用磁盘空间的是否在 4 个小时候被占满,能够运用如下表达式:

predict_linear(node_filesystem_free{job="node"}[2h], 4 * 3600) < 0

28)rate()

rate(v range-vector) 函数能够直接核算区间向量 v 在时刻窗口内均匀增长速率,它会在单调性产生改变时(如因为采样方针重启引起的计数器复位)主动中止。该函数的回来成果不带有衡量方针,只要标签列表。

例如,以下表达式回来区间向量中每个时刻序列曩昔 5 分钟内 HTTP 恳求数的每秒增长率:

rate(http_requests_total[5m])
成果:
{code="200",handler="label_values",instance="120.77.65.193:9090",job="prometheus",method="get"} 0
{code="200",handler="query_range",instance="120.77.65.193:9090",job="prometheus",method="get"}  0
{code="200",handler="prometheus",instance="120.77.65.193:9090",job="prometheus",method="get"}   0.2
...

rate() 函数回来值类型只能用计数器,在长期趋势剖析或许告警中引荐运用这个函数。

留意:

当将 rate() 函数与聚合运算符(例如 sum())或随时刻聚合的函数(任何以 _over_time 结尾的函数)一起运用时,有必要先履行rate 函数,然后再进行聚合操作,不然当采样方针重新启动时 rate() 无法检测到计数器是否被重置。

29)resets()

resets(v range-vector)的参数是一个区间向量。对于每个时刻序列,它都回来一个计数器重置的次数。两个连续样本之间的值的减少被以为是一次计数器重置。

这个函数一般只用在计数器类型的时刻序列上。

30)round()

round(v instant-vector, to_nearest=1 scalar) 函数与 ceil 和 floor 函数类似,回来向量中一切样本值的最接近的整数。to_nearest 参数是可选的,默许为 1,表明样本回来的是最接近 1 的整数倍的值。你也能够将该参数指定为恣意值(也能够是小数),表明样本回来的是最接近它的整数倍的值。

31)scalar()

scalar(v instant-vector)函数的参数是一个单元素的瞬时向量,它回来其仅有的时刻序列的值作为一个标量。假如衡量方针的样本数量大于 1 或许等于 0, 则回来 NaN。

32) sort()

sort(v instant-vector)函数对向量按元素的值进行升序排序,回来成果:key: value = 衡量方针:样本值[升序摆放]。

33)sort_desc()

sort(v instant-vector) 函数对向量按元素的值进行降序排序,回来成果:key: value = 衡量方针:样本值[降序摆放]。

34) sqrt()

sqrt(v instant-vector) 函数核算向量 v 中一切元素的平方根。

35)time()

time()函数回来从 1970-01-01 到现在的秒数。留意:它不是直接回来当时时刻,而是时刻戳

36)timestamp()

timestamp(v instant-vector) 函数回来向量 v 中的每个样本的时刻戳(从 1970-01-01 到现在的秒数)。

该函数从 Prometheus 2.0 版别开端引入。

37)vector()

vector(s scalar)函数将标量 s 作为没有标签的向量回来,即回来成果为:key: value= {}, s。

38)year()

year(v=vector(time()) instant-vector)函数回来被给定 UTC 时刻的当时年份。

39)<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) : 区间向量内每个衡量方针的样本数据值分位数,-quantile (0 ≤  ≤ 1)。
stddev_over_time(range-vector) : 区间向量内每个衡量方针的整体规范差。
stdvar_over_time(range-vector) : 区间向量内每个衡量方针的整体规范方差。
12345678

留意:

即便区间向量内的值散布不均匀,它们在聚合时的权重也是相同的。

八、PromQL 聚合操作

Prometheus 还供给了聚合操作符,这些操作符作用于瞬时向量。能够将瞬时表达式回来的样本数据进行聚合,构成一个新的时刻序列。现在支撑的聚合函数有:

  • sum (求和)
  • min (最小值)
  • max (最大值)
  • avg (均匀值)
  • stddev (规范差)
  • stdvar (规范方差)
  • count (计数)
  • count_values (对value进行计数)
  • bottomk (后n条时序)
  • topk (前n条时序)

1)sum 求和

用于对记载的 value 值进行求和。

例如:sum(prometheus_http_requests_total) 表明核算一切 HTTP 恳求的次数。

sum(prometheus_http_requests_total)

2)min 最小值

回来一切记载的最小值。

例如:min(prometheus_http_requests_total) 表明获取数据调集中的最小值。

min(prometheus_http_requests_total)

3)max 最大值

回来一切记载的最大值。

例如:maxmetheus_http_requests_total)` 表明获取数据调集中的最大值。

max(prometheus_http_requests_total)

4)avg 均匀值

avg 函数回来一切记载的均匀值。

例如:avg(metheus_http_requests_total) 表明获取数据调集中的均匀值。

avg(prometheus_http_requests_total)

5)stddev 规范差

规范差(Standard Deviation)常用来描述数据的动摇巨细。

例如: 核算出不同 HTTP 恳求的数量动摇状况。

stddev(prometheus_http_requests_total)

6)count 计数

count 函数回来一切记载的计数。

例如:count(prometheus_http_requests_total) 表明核算一切 HTTP 恳求的次数。

count(prometheus_http_requests_total)

7)bottomk 后几条

bottomk 用于对样本值进行排序,回来当时样本值后 N 位的时刻序列。

例如:获取 HTTP 恳求量后 5 位的恳求,能够运用表达式:

bottomk(5, prometheus_http_requests_total)

8)topk 前几条

topk 用于对样本值进行排序,回来当时样本值前 N 位的时刻序列。

例如:获取 HTTP 恳求量前 5 位的恳求,能够运用表达式:

topk(5, prometheus_http_requests_total)

九、PromQL 不合法总结

因为一切的PromQL表达式有必要至少包括一个方针称号,或许至少有一个不会匹配到空字符串的标签过滤器,因而结合Prometheus官方文档,能够梳理出如下不合法示例。

{job=~".*"} # 不合法! .*表明恣意一个字符,这就包括空字符串,且还没有方针称号
{job=""}    # 不合法!
{job!=""}   # 不合法!

相反,如下表达式是合法的。

{job=~".+"}               # 合法!.+表明至少一个字符
{job=~".*",method="get"}  # 合法!.*表明恣意一个字符
{job="",method="post"}    # 合法!存在一个非空匹配
{job=~".+",method="post"} # 合法!存在一个非空匹配

关于Prometheus PromQL解说就先到这儿了,其实官网介绍的很清楚,也不难,多运用就很容易把握了,有疑问的小伙伴欢迎给我留言,后续会继续更新【云原生+大数据】的文章,请小伙伴耐性等待~

【云原生】Prometheus PromQL讲解与实战操作