Metric#
统计 API 请求: 如果使用此配置向 创建一个指定 size 大小和给定 name 名称的共享内存区域来存储指标。该区域名称作为 参数: 如果为 如果为 mode — 数据处理算法(参见 操作模式 部分); parameters — 所选模式的附加设置(例如, 使用示例: 在 API 树中,共享内存区域模板如下所示: 数字;共享内存区域中被丢弃的指标数量 对象;其成员是具有定义键和计算值的指标 备注 在 1 MB 区域中,键大小为 39 字节且单一指标模式时,大约可以存储 8,000 个唯一键条目。 定义一个 复合指标 — 一组具有独立模式的指标。
块体中的每一行定义一个 子指标名称、一个 模式 以及可选的模式 参数。 使用示例: 在 API 树中,这样的复合指标模板如下所示: 数字;共享内存区域中被丢弃的指标数量 对象;其成员是具有设定键的复合指标。它们是包含一组具有计算值的子指标的对象 计算指定共享内存区域 name 的指标值。 参数: 最大长度为 255 字节。如果键更长,将被截断为 255 字节并附加省略号 如果省略,默认为 如果为 如果为 如果为 备注 在内部重定向的情况下, 使用示例: 备注 具有空键或无效 这对于 备注 请记住,变量在不同阶段进行求值。例如,无法在 可用指标操作模式列表: 计数器在每次指标更新时将其值增加 默认值 — 备注 任何指标更新(使用任何值)都会单调地将计数器增加 示例: 更新指标: API 中的预期指标值: gauge 根据传入数字的符号增加或减少其值。正值增加计数器,负值减少计数器。值为 默认值 — 示例: 更新指标: API 中的预期指标值: 进一步更新: API 中的预期指标值: 存储最后接收到的值,不进行任何聚合。如果省略 value,则使用 示例: 更新指标: API 中的预期指标值: 进一步更新: API 中的预期指标值: 保存两个值中的最小值 — 当前存储的值和新值。 示例: 更新指标: API 中的预期指标值: 保存两个值中的最大值 — 当前存储的值和新值。 示例: 更新指标: API 中的预期指标值: 使用 指数平滑 算法计算平均值。 接受可选参数 系数越高,新值的权重越大。如果指定 示例: 更新指标: API 中的预期指标值: 计算算术平均值。接受可选参数 备注 例如,:samp:window=5s 将仅考虑最近 5 秒内的事件。 示例: 更新指标: API 中的预期指标值: 如果从最后一次更新等待 5 秒,预期值将为: 创建一组"桶",如果新值不超过桶的阈值,则递增相关计数器。参数以数值阈值列表的形式提供。对于分析分布(如响应时间)很有用。 必需参数是 numbers — 桶的阈值,按升序列出。 备注 桶值 示例: 更新指标: API 中的预期指标值: 进一步更新: API 中的预期指标值: 进一步更新: API 中的预期指标值: 为每个指标创建以下变量: 对于复杂指标,会添加额外的变量: 与 metric 指令类似, 用于设置变量的值必须遵循 使用示例: 使用 njs 模块计算指标: 文件 在对 备注 设置变量后,可以获取其值;它将等于
指定的 此外,存储在 备注 对于复杂指标, 使用示例: 使用此配置,对 对于 备注 如果将空字符串赋值给 仅在 在这种情况下,存储在 对于复杂指标,可以使用 使用示例: 使用此配置,对 响应: 响应: 响应: Angie 包含一个 内置模块,用于以
Prometheus 格式
显示指标,该模块支持自定义指标。 作为集成示例,请考虑以下配置: 在对 指标值将为: 以 Prometheus 格式,
该指标可在 ngx_http_metric_module 模块允许创建任意的实时计算指标。这些指标值存储在共享内存中,并在 /status/http/metric_zones/ API 分支中实时显示。
支持多种数据聚合类型(计数器、直方图、移动平均等),并可按任意键进行分组。配置示例#
http {
metric_zone api_requests:1m count;
server {
listen 80;
location /api/ {
allow 127.0.0.1;
deny all;
api /status/;
metric api_requests $http_user_agent on=request;
}
}
}
/api/ 发起请求:$ curl 127.0.0.1/api/ --user-agent "Firefox"
api_requests 指标会实时更新:{
"http": {
"metric_zones": {
"api_requests": {
"discarded": 0,
"metrics": {
"Firefox": 1
}
}
}
}
}
指令#
metric_zone#
/status/http/metric_zones/ 分支中的节点。expire=<on|off> — 区域满时的行为:on,则丢弃最旧的指标(按更新时间)以释放内存供新指标使用;off (默认)— 丢弃新传入的指标,保留现有条目。discard_key=<name> — 定义一个键为 name 的指标,用于累积被丢弃指标的值。默认情况下不创建此类指标。保留键不能手动更新。average exp 的 factor)。metric_zone request_time:1m max;
{
"discarded": 0,
"metrics": {
"key1": 123,
"key2": 10.5,
}
}
discardedmetricsmetric_complex_zone#
metric_complex_zone requests:1m expire=on discard_key="old" {
# 子指标名称 模式 参数
min_time min;
avg_time average exp factor=60;
max_time max;
total count;
}
{
"discarded": 3,
"metrics": {
"key1": {
"min_time": 20,
"avg_time": 50,
"max_time": 80,
"total": 2
},
"old": {
"min_time": 3,
"avg_time": 40,
"max_time": 152,
"total": 80
}
}
}
discardedmetricsmetric#
...;0。如果参数无法转换为数字,则默认为 1;on — 可选参数,指定何时计算指标:on=request,在接收到请求时计算;on=response,在准备响应期间计算;on=end (默认),在发送响应后计算。on=request 阶段的指标在原始 location 中计算。但是,on=response 和 on=end 指标将在新的 location 中计算。metric requests $http_user_agent=$request_time;
key=value 对的指标将被忽略。
省略的 value 被视为 0:metric foo $bar; # 等同于 $bar=0
count 模式很有用,该模式忽略数值,只对指标被更新这一事实做出反应。on=request (接收请求时)使用 $bytes_sent (发送给客户端的字节数)。操作模式#
count — 计数器;gauge — 仪表(增加/减少);last — 最后接收到的值;min — 最小值;max — 最大值;average exp — 指数移动平均(EMA)(参数 factor);average mean — 窗口内的平均值(参数 window 和 count);histogram — 跨"桶"的分布(阈值列表)。count#
1。0。1。metric_zone count:1m count;
# 作为复合指标的一部分:
#
# metric_complex_zone count:1m {
# some_metric_name count;
# }
server {
listen 80;
location /metric/ {
metric count KEY;
}
location ~ ^/metric/set/(.+)$ {
metric count KEY=$1;
}
location /api/ {
api /status/http/metric_zones/count/metrics/;
}
}
$ curl 127.0.0.1/metric/
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/set/23
$ curl 127.0.0.1/metric/set/-32
{
"KEY": 4
}
gauge#
0 时不改变计数器。0。metric_zone gauge:1m gauge;
# 作为复杂指标的一部分:
#
# metric_complex_zone gauge:1m {
# some_metric_name gauge;
# }
server {
listen 80;
location /metric/ {
metric gauge KEY;
}
location ~ ^/metric/set/(.+)$ {
metric gauge KEY=$1;
}
location /api/ {
api /status/http/metric_zones/gauge/metrics/;
}
}
$ curl 127.0.0.1/metric/
{
"KEY": 0
}
$ curl 127.0.0.1/metric/set/5
$ curl 127.0.0.1/metric/set/-5
$ curl 127.0.0.1/metric/set/8
{
"KEY": 8
}
last#
0。metric_zone last:1m last;
# 作为复杂指标的一部分:
#
# metric_complex_zone last:1m {
# some_metric_name last;
# }
server {
listen 80;
location /metric/ {
metric last KEY;
}
location ~ ^/metric/set/(.+)$ {
metric last KEY=$1;
}
location /api/ {
api /status/http/metric_zones/last/metrics/;
}
}
$ curl 127.0.0.1/metric/
{
"KEY": 0
}
$ curl 127.0.0.1/metric/set/8000
$ curl 127.0.0.1/metric/set/37
$ curl 127.0.0.1/metric/set/-3.5
{
"KEY": -3.5
}
min#
metric_zone min:1m min;
# 作为复杂指标的一部分:
#
# metric_complex_zone min:1m {
# some_metric_name min;
# }
server {
listen 80;
location /metric/ {
metric min KEY;
}
location ~ ^/metric/set/(.+)$ {
metric min KEY=$1;
}
location /api/ {
api /status/http/metric_zones/min/metrics/;
}
}
$ curl 127.0.0.1/metric/set/42.999
$ curl 127.0.0.1/metric/set/-512
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/
{
"KEY": -512
}
max#
metric_zone max:1m max;
# 作为复杂指标的一部分:
#
# metric_complex_zone max:1m {
# some_metric_name max;
# }
server {
listen 80;
location /metric/ {
metric max KEY;
}
location ~ ^/metric/set/(.+)$ {
metric max KEY=$1;
}
location /api/ {
api /status/http/metric_zones/max/metrics/;
}
}
$ curl 127.0.0.1/metric/set/42.999
$ curl 127.0.0.1/metric/set/-512
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/
{
"KEY": 42.999
}
average exp#
factor=<number> — 决定新值对平均值影响程度的系数。允许的整数值范围为 0 到 99。默认值为 90。90,结果将是新值的 90% 加上先前平均值的 10%。metric_zone avg_exp:1m average exp factor=60;
# 作为复杂指标的一部分:
#
# metric_complex_zone avg_exp:1m {
# some_metric_name average exp factor=60;
# }
server {
listen 80;
location ~ ^/metric/set/(.+)$ {
metric avg_exp KEY=$1;
}
location /api/ {
api /status/http/metric_zones/avg_exp/metrics/;
}
}
$ curl 127.0.0.1/metric/set/100
$ curl 127.0.0.1/metric/set/200
$ curl 127.0.0.1/metric/set/0
$ curl 127.0.0.1/metric/set/8
$ curl 127.0.0.1/metric/set/30
{
"KEY": 30.16
}
average mean#
window=<off|time> 和 count=<number>,分别定义用于平均的时间间隔和样本大小。默认值:window=off`(使用整个样本)和 :samp:`count=10。window 参数不能为 0。count=number 参数控制样本大小(缓存值),以实现更平滑的平均值计算。metric_zone avg_mean:1m average mean window=5s count=8;
# 作为复杂指标的一部分:
#
# metric_complex_zone avg_mean:1m {
# some_metric_name average mean window=5s count=8;
# }
server {
listen 80;
location ~ ^/metric/set/(.+)$ {
metric avg_mean KEY=$1;
}
location /api/ {
api /status/http/metric_zones/avg_mean/metrics/;
}
}
$ curl 127.0.0.1/metric/set/0.1
$ curl 127.0.0.1/metric/set/0.1
$ curl 127.0.0.1/metric/set/0.4
$ curl 127.0.0.1/metric/set/10
$ curl 127.0.0.1/metric/set/1
$ curl 127.0.0.1/metric/set/1
{
"KEY": 2.1
}
{
"KEY": 0
}
histogram#
inf 或 +Inf 可用于捕获所有超过最高指定桶的值。metric_zone hist:1m histogram 0.1 0.2 0.5 1 2 inf;
# 作为复杂指标的一部分:
#
# metric_complex_zone hist:1m {
# some_metric_name histogram 0.1 0.2 0.5 1 2 inf;
# }
server {
listen 80;
location ~ ^/metric/set/(.+)$ {
metric histogram KEY=$1;
}
location /api/ {
api /status/http/metric_zones/hist/metrics/;
}
}
$ curl 127.0.0.1/metric/set/0.25
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 1,
"inf": 1
}
}
$ curl 127.0.0.1/metric/set/2
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 2,
"inf": 2
}
}
$ curl 127.0.0.1/metric/set/1000
{
"KEY": {
"0.1": 0,
"0.2": 0,
"0.5": 1,
"1": 1,
"2": 2,
"inf": 3
}
}
内置变量#
$metric_<name>$metric_<name>_key$metric_<name>_value$metric_<name>_value_<metric>$metric_<name>#$metric_<name> 变量设置器可用于更新指标。计算发生在
Rewrite 阶段,
允许从 njs 模块处理指标。key=value 结构。
键和值都可以由文本、变量及其组合构成。
键是用于分组值的任意字符串。值是由所选模式处理的数字。
如果省略,则默认为 0。
如果参数无法转换为数字,则默认为 1。http {
metric_zone counter:1m count;
# 此时添加了 $metric_counter 变量
server {
listen 80;
location /metric/ {
set $metric_counter $http_user_agent; # 等同于 $http_user_agent=0
}
location /api/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/counter/;
}
}
}
http {
js_import metrics.js;
resolver 127.0.0.53;
metric_complex_zone requests:1m {
min_time min;
max_time max;
total count;
}
location /metric/ {
js_content metrics.js_request;
js_fetch_trusted_certificate /path/to/ISRG_Root_X1.pem;
}
location /api/ {
allow 127.0.0.1;
deny all;
api /static/http/metric_zones/requests/;
}
}
metrics.js:async function js_request(r) {
let start_time = Date.now();
let results = await Promise.all([ngx.fetch('https://google.com/'),
ngx.fetch('https://google.ru/')]);
// 使用 $metric_requests 变量设置器
r.variables.metric_requests = `google={Date.now() - start_time}`;
}
export default {js_request};
location /metric/ 发起多次请求后,值可能如下所示:{
"discarded": 0,
"metrics": {
"google": {
"min_time": 70,
"max_time": 432,
"total": 6
}
}
}
key=value 对。$metric_<name>_key 变量中的值
将更改为指定的键。$metric_<name>_key 和 $metric_<name>_value#$metric_<name>_key 和 $metric_<name>_value 变量
分别定义键和值。当设置 $metric_<name>_value 时会发生指标更新,
前提是 $metric_<name>_key 中的键已经定义。$metric_<name>_value 变量中的子指标值
使用 ", " 分隔符连接。http {
metric_zone gauge:1m gauge;
# 此处添加了变量 $metric_gauge、$metric_gauge_key 和 $metric_gauge_value。
metric_complex_zone complex:1m {
hist histogram 1 2 3;
avg average exp;
}
# 此处添加了 $metric_complex、$metric_complex_key 和 $metric_complex_value。
server {
listen 80;
location /gauge/ {
set $metric_gauge_key "foo";
set $metric_gauge_value 1;
# 或者:set $metric_gauge foo=1;
return 200 "Updated with '$metric_gauge'\nValue='$metric_gauge_value'\n";
}
location /complex/ {
set $metric_complex_key "foo";
set $metric_complex_value 3;
# 或者:set $metric_complex foo=3;
return 200 "Updated with '$metric_complex'\nValue='$metric_complex_value'\n";
}
}
}
/gauge/ 的请求产生:$ curl 127.0.0.1/gauge/
Updated with 'foo=1'
Value='1'
/complex/:$ curl 127.0.0.1/complex/
Updated with 'foo=3'
Value='0 0 1, 3'
$metric_<name>_value,该值将被
识别为 0。如果字符串由无法转换为数字的字符组成,
则被识别为 1。$metric_<name>_key 和
$metric_<name>_value 都已设置后才会进行计算。$metric_<name> 中的值将等于
新的 key=value 对。$metric_<name>_key 中的值表示通过变量指定的最后一个键。$metric_<name>_value 中的值表示为
$metric_<name>_key 中设置的键计算的最后一个值。$metric_<name>_value_<metric>#$metric_<name>_value_<metric> 变量获取
特定子指标的值,其中 <metric> 是子指标的名称。http {
metric_complex_zone foo:1m {
count count;
min min;
avg average exp;
}
# 添加 $metric_foo、$metric_foo_key、$metric_foo_value,
# 以及 $metric_foo_value_count、$metric_foo_value_min、$metric_foo_value_avg。
server {
listen 80;
location /foo/ {
set $metric_foo_key bar;
set $metric_foo_value 9;
# 或者:set $metric_foo bar=9;
return 200 "Updated with '$metric_foo'\nValues='$metric_foo_value'\nCount='$metric_foo_value_count'\n";
}
}
}
/foo/ 的请求产生:$ curl 127.0.0.1/foo/
Updated with 'bar=9'
Values='1, 9, 9'
Count='1'
其他示例#
监控 HTTP 方法#
metric_zone http_methods:1m count;
server {
listen 80;
location / {
metric http_methods $request_method;
}
location /metrics/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/http_methods/metrics/;
}
}
{
"GET": 65,
"POST": 20,
"PUT": 10,
"DELETE": 5
}
上游响应时间分布#
metric_zone upstream_time:10m expire=on histogram
0.05 0.1 0.3 0.5 1 2 5 10 inf;
server {
listen 80;
location /backend/ {
proxy_pass http://backend;
metric upstream_time $upstream_addr=$upstream_response_time on=end;
}
location /metrics/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/upstream_time/;
}
}
{
"discarded": 0,
"metrics": {
"backend1:8080": {
"0.05": 12,
"0.1": 28,
"0.3": 56,
"0.5": 78,
"1": 92,
"2": 97,
"5": 99,
"10": 100,
"inf": 100
}
}
}
活动连接数#
metric_zone active_connections:2m gauge;
server {
listen 80;
server_name site1.com;
location / {
# 连接时增加
metric active_connections site1=1 on=request;
# 结束时减少
metric active_connections site1=-1 on=end;
}
}
server {
listen 80;
server_name site2.com;
location / {
metric active_connections site2=1 on=request;
metric active_connections site2=-1 on=end;
}
}
server {
listen 8080;
location /connections/ {
allow 127.0.0.1;
deny all;
api /status/http/metric_zones/active_connections/metrics;
}
}
{
"site1": 42,
"site2": 17
}
Prometheus 支持#
http {
# 创建 "upload" 指标
metric_complex_zone upload:1m discard_key="other" {
stats histogram 64 256 1024 4096 16384 +Inf;
sum gauge;
count count;
avg_size average exp;
}
# 描述 "upload" 指标的 Prometheus 模板
prometheus_template upload_metric {
'stats{le="$1"}' $p8s_value
path=~^/http/metric_zones/upload/metrics/angie/stats/(.+)$
type=histogram;
'stats_sum' $p8s_value
path=/http/metric_zones/upload/metrics/angie/sum;
'stats_count' $p8s_value
path=/http/metric_zones/upload/metrics/angie/count;
'avg_size' $p8s_value
path=/http/metric_zones/upload/metrics/angie/avg_size;
}
server {
listen 80;
# 更新指标
location ~ ^/upload/(.*)$ {
api /status/http/metric_zones/upload/metrics/angie/;
metric upload angie=$1 on=request;
}
# 指标抓取目标
location /prometheus/upload_metric/ {
prometheus upload_metric;
}
}
}
/upload/... 发起多次请求后:$ curl 127.0.0.1/upload/16384
$ curl 127.0.0.1/upload/64448
$ curl 127.0.0.1/upload/64
$ curl 127.0.0.1/upload/1028
$ curl 127.0.0.1/upload/1028
{
"stats": {
"64": 1,
"256": 1,
"1024": 1,
"4096": 3,
"16384": 4,
"+Inf": 5
},
"sum": 82952,
"count": 5,
"avg_size": 1077.9376
}
/prometheus/upload_metric/ 获取:# Angie Prometheus template "upload_metric"
# TYPE stats histogram
stats{le="64"} 1
stats{le="256"} 1
stats{le="1024"} 1
stats{le="4096"} 3
stats{le="16384"} 4
stats{le="+Inf"} 5
stats_sum 82952
stats_count 5
avg_size 1077.9376