

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 模板化标签和注释
<a name="v10-alerting-overview-labels-templating"></a>

****  
本文档主题专为支持 **Grafana 10.x 版本**的 Grafana 工作区而设计。  
对于支持 Grafana 9.x 版本的 Grafana 工作区，请参阅[使用 Grafana 版本 9](using-grafana-v9.md)。  
对于支持 Grafana 8.x 版本的 Grafana 工作区，请参阅[使用 Grafana 版本 8](using-grafana-v8.md)。

您可以使用模板在标签和标注中包含来自查询和表达式的数据。例如，您可能希望根据查询的值设置警报的严重性标签，或者在摘要注释中使用查询的实例标签，以便了解哪台服务器的 CPU 使用率较高。

所有模板都应以 [text/template](https://pkg.go.dev/text/template) 编写。无论您是模板化标签还是注释，都应将每个模板内联写入要模板化的标签或注释中。这意味着您不能在标签和注释之间共享模板，而是需要将模板复制到任何要使用它们的位置。

每当评估警报规则时，都会评估每个模板，并针对每个警报单独评估每个模板。例如，如果您的警报规则具有模板化摘要注释，而警报规则有 10 个触发警报，则模板将执行 10 次，每个警报一次。应尽量避免在模板中进行开销较大的计算。

## 示例
<a name="v10-alerting-overview-labels-templating-examples"></a>

与其写完整的教程，不text/template, the following examples attempt to show the most common use-cases we have seen for templates. You can use these examples verbatim, or adapt them as necessary for your use case. For more information about how to write text/template如参阅[文本/模板文档](https://pkg.go.dev/text/template)。

**打印所有标签（以逗号分隔）**

要打印所有标签（以逗号分隔），请打印 `$labels` 变量：

```
{{ $labels }}
```

例如，给定一个带有标签 `alertname=High CPU usage`、`grafana_folder=CPU alerts` 和 `instance=server1` 的警报，将会打印：

```
alertname=High CPU usage, grafana_folder=CPU alerts, instance=server1
```

**注意**  
如果您使用的是经典条件，则 `$labels` 不会包含查询中的任何标签。有关更多信息，请参阅 [\$1labels 变量](#v10-alerting-overview-labels-templating-the-labels-variable)。

**打印所有标签（每行一个）**

要打印所有标签（每行一个），请使用遍历每 key/value 对标签并单独打印。`range`这里 `$k` 是指名称，`$v` 时值当前标签的值：

```
{{ range $k, $v := $labels -}}
{{ $k }}={{ $v }}
{{ end }}
```

例如，给定一个带有标签 `alertname=High CPU usage`、`grafana_folder=CPU alerts` 和 `instance=server1` 的警报，将会打印：

```
alertname=High CPU usage
grafana_folder=CPU alerts
instance=server1
```

**注意**  
如果您使用的是经典条件，则 `$labels` 不会包含查询中的任何标签。有关更多信息，请参阅 [\$1labels 变量](#v10-alerting-overview-labels-templating-the-labels-variable)。

**打印单个标签**

要打印单个标签，请使用带有 `$labels` 变量的 `index` 函数：

```
The host {{ index $labels "instance" }} has exceeded 80% CPU usage for the last 5 minutes
```

例如，给定一个带有标签 `instance=server1` 的警报，将会打印：

```
The host server1 has exceeded 80% CPU usage for the last 5 minutes
```

**注意**  
如果您使用的是经典条件，则 `$labels` 不会包含查询中的任何标签。有关更多信息，请参阅 [\$1labels 变量](#v10-alerting-overview-labels-templating-the-labels-variable)。

**打印查询的值**

要打印即时查询的值，可使用 `index` 函数和 `$values` 变量打印其 Ref ID：

```
{{ index $values "A" }}
```

例如，给定一个返回值为 81.2345 的即时查询，将会打印：

```
81.2345
```

要打印范围查询的值，必须先使用 reduce 表达式将其从时间序列简化为即时向量。然后，您可以改用 Ref ID 来打印 reduce 表达式的结果。例如，如果 reduce 表达式取 A 的平均值并具有 Ref ID B，则可以编写：

```
{{ index $values "B" }}
```

**打印查询的 humanize 值**

要打印即时查询的 humanize 值，请使用 `humanize` 函数：

```
{{ humanize (index $values "A").Value }}
```

例如，给定一个返回值为 81.2345 的即时查询，将会打印：

```
81.234
```

要打印范围查询的 humanize 值，必须先使用 reduce 表达式将其从时间序列简化为即时向量。然后，您可以改用 Ref ID 来打印 reduce 表达式的结果。例如，如果 reduce 表达式取 A 的平均值并具有 Ref ID B，则可以编写：

```
{{ humanize (index $values "B").Value }}
```

**以百分比形式打印查询的值**

要以百分比形式打印即时查询的值，请使用 `humanizePercentage` 函数：

```
{{ humanizePercentage (index $values "A").Value }}
```

此函数期望值是介于 0 和 1 之间的十进制数。如果该值是介于 0 和 100 之间的十进制数，则可以在查询中或使用数学表达式将其除以 100。如果查询是范围查询，必须先使用 reduce 表达式将其从时间序列简化为即时向量。

**根据查询的值设置严重性**

要根据查询的值设置严重性标签，请使用 if 语句和 greater than 比较函数。与 text/template 不支持类型强制的 as进行比较`$values`时 `80.0` `50.0``0.0`，请务必使用小数（、、等）。您可以在[此处](https://pkg.go.dev/text/template#hdr-Functions)找到所有支持的比较函数列表。

```
{{ if (gt $values.A.Value 80.0) -}}
high
{{ else if (gt $values.A.Value 50.0) -}}
medium
{{ else -}}
low
{{- end }}
```

**根据经典条件打印所有标签**

如果使用经典条件，则不能使用 `$labels` 根据查询打印标签，而必须使用 `$values`。原因是经典条件会丢弃这些标签以强制执行一维行为（每个警报规则最多一个警报）。如果经典条件未丢弃这些标签，则返回许多时间序列的查询将导致警报在触发和解决之间不断波动，因为每次评估警报规则时标签都会变化。

而 `$values` 变量包含触发条件下所有时间序列的简化值。例如，如果您有一个警报规则，其查询 A 返回两个时间序列，而经典条件 B 具有两个条件，则 `$values` 将包含 `B0`、`B1`、`B2` 和 `B3`。如果经典条件 B 只有一个条件，则 `$values` 只包含 `B0` 和 `B1`。

要打印触发时间序列的所有标签，请使用以下模板（如果正则表达式不同，请确保将正则表达式中的 `B` 替换为经典条件的 Ref ID）：

```
{{ range $k, $v := $values -}}
{{ if (match "B[0-9]+" $k) -}}
{{ $k }}: {{ $v.Labels }}{{ end }}
{{ end }}
```

例如，两个时间序列的经典条件超过单个条件，将会打印：

```
B0: instance=server1
B1: instance=server2
```

如果经典条件有两个或多个条件，而时间序列同时超出多个条件，则每个超出的条件都会重复其标签：

```
B0: instance=server1
B1: instance=server2
B2: instance=server1
B3: instance=server2
```

如果需要打印唯一标签，则应考虑将警报规则从一维更改为多维。您可以将经典条件替换为 reduce 和 math 表达式来做到这一点。

**根据经典条件打印所有值**

要打印经典条件中的所有值，请使用前面的示例并将 `$v.Labels` 替换为 `$v.Value`：

```
{{ range $k, $v := $values -}}
{{ if (match "B[0-9]+" $k) -}}
{{ $k }}: {{ $v.Value }}{{ end }}
{{ end }}
```

例如，两个时间序列的经典条件超过单个条件，将会打印：

```
B0: 81.2345
B1: 84.5678
```

如果经典条件有两个或多个条件，并且一个时间序列同时超过多个条件，则 `$values` 将包含所有条件的值：

```
B0: 81.2345
B1: 92.3456
B2: 84.5678
B3: 95.6789
```

## 变量
<a name="v10-alerting-overview-labels-templating-variables"></a>

在模板化标签和注释时，您可以使用以下变量：

### 标签变量
<a name="v10-alerting-overview-labels-templating-the-labels-variable"></a>

`$labels` 变量包含查询中的所有标签。例如，假设您有一个查询，该查询返回所有服务器的 CPU 使用率；有一个警报规则，当任何服务器在过去 5 分钟内 CPU 使用率超过 80% 时触发。您要在警报中添加摘要注释，提醒您哪台服务器的 CPU 使用率较高。您可以使用 `$labels` 变量，编写一个模板来打印可读的句子，例如：

```
CPU usage for {{ index $labels "instance" }} has exceeded 80% for the last 5 minutes
```

**注意**  
如果您使用的是经典条件，则 `$labels` 不会包含查询中的任何标签。经典条件会丢弃这些标签以强制执行一维行为（每个警报规则最多一个警报）。如果您想在模板中使用查询的标签，请按照前面的*打印经典条件中的所有标签*示例操作。

### 值变量
<a name="v10-alerting-overview-labels-templating-the-value-variable"></a>

`$value` 变量是一个字符串，包含所有即时查询的标签和值；阈值、reduce 和 math 表达式以及警报规则中的经典条件。但不包含范围查询的结果，因为这些查询可以返回 10 到 10000 行或指标。如果是这样，对于特别大的查询，单个警报可能会占用 10 秒 MBs 的内存，而 Grafana 很快就会耗尽内存。

要在摘要中打印 `$value` 变量，可以这样编写：

```
CPU usage for {{ index $labels "instance" }} has exceeded 80% for the last 5 minutes: {{ $value }}
```

内容如下所示：

```
CPU usage for instance1 has exceeded 80% for the last 5 minutes: [ var='A' labels={instance=instance1} value=81.234 ]
```

这里 `var='A'` 指的是 Ref ID A 的即时查询，`labels={instance=instance1}` 指的是标签，`value=81.234` 指的是过去 5 分钟内的平均 CPU 使用率。

如果您只想打印部分字符串而不是完整字符串，请使用 `$values` 变量。其中包含与 `$value` 相同的信息，但采用的是结构化表，使用起来比编写正则表达式来匹配所需的文本要简单得多。

### 值变量
<a name="v10-alerting-overview-labels-templating-the-values-variable"></a>

该`$values`变量是一个包含所有即时查询和表达式的标签和浮点值的表，并以其 Ref IDs 为索引。

要打印带有 Ref ID A 的即时查询的值：

```
CPU usage for {{ index $labels "instance" }} has exceeded 80% for the last 5 minutes: {{ index $values "A" }}
```

例如，给定一个带有标签 `instance=server1` 的警报和带有值 `81.2345` 的即时查询，将会打印：

```
CPU usage for instance1 has exceeded 80% for the last 5 minutes: 81.2345
```

如果 Ref ID A 中的查询是范围查询，不是即时查询，则添加一个带有 Ref ID B 的 reduce 表达式，并将 `(index $values "A")` 替换为 `(index $values "B")`：

```
CPU usage for {{ index $labels "instance" }} has exceeded 80% for the last 5 minutes: {{ index $values "B" }}
```

## 函数
<a name="v10-alerting-overview-labels-templating-functions"></a>

在模板化标签和注释时，您可以使用以下函数：

**args**

`args` 函数将对象列表转换为带有 arg0、arg1 等键的映射。这是为了允许将多个参数传递给模板。

```
{{define "x"}}{{.arg0}} {{.arg1}}{{end}}{{template "x" (args 1 "2")}}
```

```
1 2
```

**externalURL**

`externalURL` 函数返回 Grafana 服务器的外部 URL。

```
{{ externalURL }}
```

```
https://example.com/grafana
```

**graphLink**

`graphLink` 函数返回给定表达式和数据来源在 [Grafana 10 中的 Explore](v10-explore.md) 中图形视图的路径。

```
{{ graphLink "{\"expr\": \"up\", \"datasource\": \"gdev-prometheus\"}" }}
```

```
/explore?left=["now-1h","now","gdev-prometheus",{"datasource":"gdev-prometheus","expr":"up","instant":false,"range":true}]
```

**humanize**

`humanize` 函数对十进制数字进行人性化处理。

```
{{ humanize 1000.0 }}
```

```
1k
```

**humanize1024**

`humanize1024` 的工作原理类似于 `humanize`，但使用 1024（而不是 1000）作为基数。

```
{{ humanize1024 1024.0 }}
```

```
1ki
```

**humanizeDuration**

`humanizeDuration` 函数对持续时间（秒）进行人性化处理。

```
{{ humanizeDuration 60.0 }}
```

```
1m 0s
```

**humanizePercentage**

`humanizePercentage` 函数将比率值人性化处理为百分比。

```
{{ humanizePercentage 0.2 }}
```

```
20%
```

**humanizeTimestamp**

`humanizeTimestamp` 函数对 Unix 时间戳进行人性化处理。

```
{{ humanizeTimestamp 1577836800.0 }}
```

```
2020-01-01 00:00:00 +0000 UTC
```

**match**

`match` 函数将文本与正则表达式模式进行匹配。

```
{{ match "a.*" "abc" }}
```

```
true
```

**pathPrefix**

`pathPrefix` 函数返回 Grafana 服务器的路径。

```
{{ pathPrefix }}
```

```
/grafana
```

**tableLink**

`tableLink` 函数返回给定表达式和数据来源在 [Grafana 10 中的 Explore](v10-explore.md) 中表格视图的路径。

```
{{ tableLink "{\"expr\": \"up\", \"datasource\": \"gdev-prometheus\"}" }}
```

```
/explore?left=["now-1h","now","gdev-prometheus",{"datasource":"gdev-prometheus","expr":"up","instant":true,"range":false}]
```

**删除实例快照**

`title` 函数将每个单词的第一个字符大写。

```
{{ title "hello, world!" }}
```

```
Hello, World!
```

**toLower**

`toLower` 函数以小写形式返回所有文本。

```
{{ toLower "Hello, world!" }}
```

```
hello, world!
```

**toUpper**

`toUpper` 函数以大写形式返回所有文本。

```
{{ toUpper "Hello, world!" }}
```

```
HELLO, WORLD!
```

**reReplaceAll**

`reReplaceAll` 函数替换与正则表达式匹配的文本。

```
{{ reReplaceAll "localhost:(.*)" "example.com:$1" "localhost:8080" }}
```

```
example.com:8080
```