<a id="http-metric"></a>

# Metric

`ngx_http_metric_module` 模块允许创建任意的实时计算指标。这些指标值存储在共享内存中，并在 `/status/http/metric_zones/` API 分支中实时显示。
支持多种数据聚合类型（计数器、直方图、移动平均等），并可按任意键进行分组。

<a id="configuration-example-30"></a>

## 配置示例

统计 API 请求：

```nginx
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/` 发起请求：

```console
$ curl 127.0.0.1/api/ --user-agent "Firefox"
```

`api_requests` 指标会实时更新：

```json
{
    "http": {
       "metric_zones": {
           "api_requests": {
               "discarded": 0,
               "metrics": {
                   "Firefox": 1
               }
           }
       }
    }
}
```

<a id="directives-31"></a>

## 指令

<a id="index-0"></a>

<a id="metric-zone"></a>

### metric_zone

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `metric_zone` name:size [`expire`=`on`| `off`] [`discard_key`=`name`] mode [parameters];   |
|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------|
| 默认值                                                                                  | —                                                                                          |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http                                                                                       |

创建一个指定 size 大小和给定 name 名称的共享内存区域来存储指标。该区域名称作为 `/status/http/metric_zones/` 分支中的节点。

参数：

- `expire=<on|off>` — 区域满时的行为：
  - 如果为 `on`，则丢弃最旧的指标（按更新时间）以释放内存供新指标使用；
  - 如果为 `off` （默认）— 丢弃新传入的指标，保留现有条目。
- `discard_key=<name>` — 定义一个键为 name 的指标，用于累积被丢弃指标的值。默认情况下不创建此类指标。保留键不能手动更新。
- mode — 数据处理算法（参见 [操作模式](#metric-modes) 部分）；
- parameters — 所选模式的附加设置（例如，`average exp` 的 `factor`）。

使用示例：

```nginx
metric_zone request_time:1m max;
```

在 API 树中，共享内存区域模板如下所示：

```json
{
    "discarded": 0,
    "metrics": {
        "key1": 123,
        "key2": 10.5,
    }
}
```

| `discarded`   | 数字；共享内存区域中被丢弃的指标数量   |
|---------------|----------------------|
| `metrics`     | 对象；其成员是具有定义键和计算值的指标  |

#### NOTE
在 1 MB 区域中，键大小为 39 字节且单一指标模式时，大约可以存储 8,000 个唯一键条目。

<a id="index-1"></a>

<a id="metric-complex-zone"></a>

### metric_complex_zone

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `metric_complex_zone` name:size [`expire`=`on`| `off`] [`discard_key`=`name`] { ... }   |
|--------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------|
| 默认值                                                                                  | —                                                                                       |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http                                                                                    |

定义一个 复合指标 — 一组具有独立模式的指标。
块体中的每一行定义一个 子指标名称、一个 模式 以及可选的模式 参数。

使用示例：

```nginx
metric_complex_zone requests:1m expire=on discard_key="old" {
    # 子指标名称      模式          参数
    min_time           min;
    avg_time           average exp   factor=60;
    max_time           max;
    total              count;
}
```

在 API 树中，这样的复合指标模板如下所示：

```json
{
    "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
        }
    }
}
```

| `discarded`   | 数字；共享内存区域中被丢弃的指标数量                    |
|---------------|---------------------------------------|
| `metrics`     | 对象；其成员是具有设定键的复合指标。它们是包含一组具有计算值的子指标的对象 |

<a id="index-2"></a>

<a id="id5"></a>

### metric

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `metric` name key=value [`on`=`request`| `response`| `end`];   |
|--------------------------------------------------------------------------------------|----------------------------------------------------------------|
| 默认值                                                                                  | —                                                              |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location                                         |

计算指定共享内存区域 name 的指标值。

参数：

- key — 任意字符串（通常是变量），用于对值进行分组。
  : 最大长度为 255 字节。如果键更长，将被截断为 255 字节并附加省略号 `...`；
- value — 由所选模式处理的数字（可以是变量）。
  : 如果省略，默认为 `0`。如果参数无法转换为数字，则默认为 `1`；
- `on` — 可选参数，指定何时计算指标：
  - 如果为 `on=request`，在接收到请求时计算；
  - 如果为 `on=response`，在准备响应期间计算；
  - 如果为 `on=end` （默认），在发送响应后计算。

#### NOTE
在内部重定向的情况下，`on=request` 阶段的指标在原始 `location` 中计算。但是，`on=response` 和 `on=end` 指标将在新的 `location` 中计算。

使用示例：

```nginx
metric requests $http_user_agent=$request_time;
```

#### NOTE
具有空键或无效 `key=value` 对的指标将被忽略。
省略的 value 被视为 `0`：

```nginx
metric foo $bar;  # 等同于 $bar=0
```

这对于 `count` 模式很有用，该模式忽略数值，只对指标被更新这一事实做出反应。

#### NOTE
请记住，变量在不同阶段进行求值。例如，无法在 `on=request` （接收请求时）使用 `$bytes_sent` （发送给客户端的字节数）。

<a id="metric-modes"></a>

## 操作模式

可用指标操作模式列表：

* `count` — 计数器；
* `gauge` — 仪表（增加/减少）；
* `last` — 最后接收到的值；
* `min` — 最小值；
* `max` — 最大值；
* `average exp` — 指数移动平均（EMA）（参数 `factor`）；
* `average mean` — 窗口内的平均值（参数 `window` 和 `count`）；
* `histogram` — 跨"桶"的分布（阈值列表）。

<a id="count"></a>

### count

计数器在每次指标更新时将其值增加 `1`。

默认值 — `0`。

#### NOTE
任何指标更新（使用任何值）都会单调地将计数器增加 `1`。

示例：

```nginx
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/;
    }
}
```

更新指标：

```console
$ 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
```

API 中的预期指标值：

```json
{
    "KEY": 4
}
```

<a id="gauge"></a>

### gauge

gauge 根据传入数字的符号增加或减少其值。正值增加计数器,负值减少计数器。值为 `0` 时不改变计数器。

默认值 — `0`。

示例:

```nginx
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/;
    }
}
```

更新指标:

```console
$ curl 127.0.0.1/metric/
```

API 中的预期指标值:

```json
{
    "KEY": 0
}
```

进一步更新:

```console
$ curl 127.0.0.1/metric/set/5
$ curl 127.0.0.1/metric/set/-5
$ curl 127.0.0.1/metric/set/8
```

API 中的预期指标值:

```json
{
    "KEY": 8
}
```

<a id="last"></a>

### last

存储最后接收到的值,不进行任何聚合。如果省略 value,则使用 `0`。

示例:

```nginx
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/;
    }
}
```

更新指标:

```console
$ curl 127.0.0.1/metric/
```

API 中的预期指标值:

```json
{
    "KEY": 0
}
```

进一步更新:

```console
$ 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
```

API 中的预期指标值:

```json
{
   "KEY": -3.5
}
```

<a id="min"></a>

### min

保存两个值中的最小值 — 当前存储的值和新值。

示例:

```nginx
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/;
    }
}
```

更新指标:

```console
$ 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/
```

API 中的预期指标值:

```json
{
    "KEY": -512
}
```

<a id="max"></a>

### max

保存两个值中的最大值 — 当前存储的值和新值。

示例:

```nginx
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/;
    }
}
```

更新指标:

```console
$ 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/
```

API 中的预期指标值:

```json
{
    "KEY": 42.999
}
```

<a id="average-exp"></a>

### average exp

使用 [指数平滑](https://en.wikipedia.org/wiki/Exponential_smoothing) 算法计算平均值。

接受可选参数 `factor=<number>` — 决定新值对平均值影响程度的系数。允许的整数值范围为 `0` 到 `99`。默认值为 `90`。

系数越高,新值的权重越大。如果指定 `90`,结果将是新值的 `90%` 加上先前平均值的 `10%`。

示例:

```nginx
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/;
    }
}
```

更新指标:

```console
$ 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
```

API 中的预期指标值:

```json
{
    "KEY": 30.16
}
```

<a id="average-mean"></a>

### average mean

计算算术平均值。接受可选参数 `window=<off|time>` 和 `count=<number>`,分别定义用于平均的时间间隔和样本大小。默认值:`window=off`(使用整个样本)和 :samp:`count=10`。

#### NOTE
例如,:samp:window=5s 将仅考虑最近 5 秒内的事件。`window` 参数不能为 `0`。`count=number` 参数控制样本大小(缓存值),以实现更平滑的平均值计算。

示例:

```nginx
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/;
    }
}
```

更新指标:

```console
$ 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
```

API 中的预期指标值:

```json
{
    "KEY": 2.1
}
```

如果从最后一次更新等待 5 秒,预期值将为:

```json
{
    "KEY": 0
}
```

<a id="histogram"></a>

### histogram

创建一组"桶",如果新值不超过桶的阈值,则递增相关计数器。参数以数值阈值列表的形式提供。对于分析分布(如响应时间)很有用。

必需参数是 numbers — 桶的阈值,按升序列出。

#### NOTE
桶值 `inf` 或 `+Inf` 可用于捕获所有超过最高指定桶的值。

示例:

```nginx
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/;
    }
}
```

更新指标:

```console
$ curl 127.0.0.1/metric/set/0.25
```

API 中的预期指标值:

```json
{
    "KEY": {
        "0.1": 0,
        "0.2": 0,
        "0.5": 1,
        "1": 1,
        "2": 1,
        "inf": 1
    }
}
```

进一步更新:

```console
$ curl 127.0.0.1/metric/set/2
```

API 中的预期指标值:

```json
{
    "KEY": {
        "0.1": 0,
        "0.2": 0,
        "0.5": 1,
        "1": 1,
        "2": 2,
        "inf": 2
    }
}
```

进一步更新:

```console
$ curl 127.0.0.1/metric/set/1000
```

API 中的预期指标值:

```json
{
    "KEY": {
       "0.1": 0,
       "0.2": 0,
       "0.5": 1,
       "1": 1,
       "2": 2,
       "inf": 3
    }
}
```

<a id="built-in-variables-5"></a>

## 内置变量

为每个指标创建以下变量:

- `$metric_<name>`
- `$metric_<name>_key`
- `$metric_<name>_value`

对于复杂指标,会添加额外的变量:

- `$metric_<name>_value_<metric>`

<a id="v-metric-zone"></a>

### `$metric_<name>`

与 [metric](#id5) 指令类似，`$metric_<name>` 变量设置器可用于更新指标。计算发生在
[Rewrite](https://angie.software/angie/docs/configuration/modules/http/http_rewrite/) 阶段，
允许从 [njs](https://angie.software/angie/docs/configuration/modules/http/http_js/) 模块处理指标。

用于设置变量的值必须遵循 `key=value` 结构。
键和值都可以由文本、变量及其组合构成。
键是用于分组值的任意字符串。值是由所选模式处理的数字。
如果省略，则默认为 `0`。
如果参数无法转换为数字，则默认为 `1`。

使用示例：

```nginx
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/;
        }
    }
}
```

使用 [njs](https://angie.software/angie/docs/configuration/modules/http/http_js/) 模块计算指标：

```nginx
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`：

```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/` 发起多次请求后，值可能如下所示：

```json
{
    "discarded": 0,
    "metrics": {
        "google": {
            "min_time": 70,
            "max_time": 432,
            "total": 6
        }
    }
}
```

#### NOTE
设置变量后，可以获取其值；它将等于
指定的 `key=value` 对。

此外，存储在 `$metric_<name>_key` 变量中的值
将更改为指定的键。

<a id="v-metric-zone-key"></a>

<a id="v-metric-zone-value"></a>

### `$metric_<name>_key` 和 `$metric_<name>_value`

`$metric_<name>_key` 和 `$metric_<name>_value` 变量
分别定义键和值。当设置 `$metric_<name>_value` 时会发生指标更新，
前提是 `$metric_<name>_key` 中的键已经定义。

#### NOTE
对于复杂指标，`$metric_<name>_value` 变量中的子指标值
使用 `", "` 分隔符连接。

使用示例：

```nginx
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/` 的请求产生：

```console
$ curl 127.0.0.1/gauge/
Updated with 'foo=1'
Value='1'
```

对于 `/complex/`：

```console
$ curl 127.0.0.1/complex/
Updated with 'foo=3'
Value='0 0 1, 3'
```

#### NOTE
如果将空字符串赋值给 `$metric_<name>_value`，该值将被
识别为 `0`。如果字符串由无法转换为数字的字符组成，
则被识别为 `1`。

仅在 `$metric_<name>_key` 和
`$metric_<name>_value` 都已设置后才会进行计算。

在这种情况下，存储在 `$metric_<name>` 中的值将等于
新的 `key=value` 对。

`$metric_<name>_key` 中的值表示通过变量指定的最后一个键。

`$metric_<name>_value` 中的值表示为
`$metric_<name>_key` 中设置的键计算的最后一个值。

<a id="v-metric-zone-value-metric"></a>

### `$metric_<name>_value_<metric>`

对于复杂指标，可以使用 `$metric_<name>_value_<metric>` 变量获取
特定子指标的值，其中 <metric> 是子指标的名称。

使用示例：

```nginx
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/` 的请求产生：

```console
$ curl 127.0.0.1/foo/
Updated with 'bar=9'
Values='1, 9, 9'
Count='1'
```

<a id="additional-examples"></a>

## 其他示例

<a id="monitoring-http-methods"></a>

### 监控 HTTP 方法

```nginx
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/;
    }
}
```

响应：

```json
{
    "GET": 65,
    "POST": 20,
    "PUT": 10,
    "DELETE": 5
}
```

<a id="upstream-response-time-distribution"></a>

### 上游响应时间分布

```nginx
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/;
    }
}
```

响应：

```json
{
    "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
        }
    }
}
```

<a id="active-connections"></a>

### 活动连接数

```nginx
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;
    }
}
```

响应：

```json
{
    "site1": 42,
    "site2": 17
}
```

<a id="prometheus-support"></a>

## Prometheus 支持

Angie 包含一个 [内置模块](https://cn.angie.software//angie/docs/configuration/modules/http/http_prometheus.md#http-prometheus)，用于以
[Prometheus 格式](https://prometheus.io/docs/instrumenting/exposition_formats/)
显示指标，该模块支持自定义指标。

作为集成示例，请考虑以下配置：

```nginx
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/...` 发起多次请求后：

```console
$ 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
```

指标值将为：

```json
{
    "stats": {
        "64": 1,
        "256": 1,
        "1024": 1,
        "4096": 3,
        "16384": 4,
        "+Inf": 5
    },

    "sum": 82952,
    "count": 5,
    "avg_size": 1077.9376
}
```

以 [Prometheus 格式](https://prometheus.io/docs/instrumenting/exposition_formats/)，
该指标可在 `/prometheus/upload_metric/` 获取：

```text
# 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
```
