

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

# 模板和变量
<a name="templates-and-variables"></a>

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

变量是值的占位符。您可以在指标查询和面板标题中使用变量。变量使您能够创建更具交互性和动态性的控制面板。无需在指标查询中对服务器、应用程序和传感器名称之类的内容进行硬编码，您可以使用变量来代替这些内容。

变量以下拉列表的形式显示在控制面板顶部。当您使用控制面板顶部的下拉列表更改值时，面板的指标查询会反映新的值。

对于希望允许查看者快速调整可视化效果但又不想向这些查看者授予完全编辑权限的管理员来说，这些功能可能特别有用。Grafana 查看器可以使用变量。

通过使用变量和模板，您可以让控制面板使用单个数据来源。如果有多个相同的数据来源或服务器，则可以创建一个控制面板，使用变量来更改您查看的内容。这简化了维护和修复的过程。

有关支持的变量类型的列表以及添加每类变量的说明，请参阅[变量类型](variables-types.md)

## 模板
<a name="templates"></a>

 *模板*是任何包含变量的查询。

例如，如果您要管理一个控制面板来监控多台服务器，则可以为每台服务器创建一个控制面板。或者，您也可以创建一个控制面板并使用包含模板查询的面板，如以下示例所示。

```
wmi_system_threads{instance=~"$server"}
```

变量值将始终使用语法 `var-<varname>=value` 同步到 URL。

## 变量最佳实践
<a name="variable-best-practices"></a>

变量下拉列表按照**控制面板设置**的变量列表中列出的顺序显示。

将经常更改的变量放在顶部，这样它们就会首先显示在控制面板的最左边。

## 变量语法
<a name="variable-syntax"></a>

 面板标题和指标查询可以使用两种不同的语法来查看变量：
+  `$varname` 此语法更易于阅读，如以下示例所示：`apps.frontend.$server.requests.count`。但是，您不能在单词中间使用变量。
+  `${var_name}` 如果要在表达式中间插入变量，请使用此语法。
+  `${var_name:<format>}` 这种格式使您能够更好地控制 Grafana 如何插入值。有关更多信息，请参阅 [高级变量格式选项](#advanced-variable-format-options)。

 在将查询发送到您的数据来源之前，会对查询进行*插值*，这意味着变量将替换为其当前值。在插值过程中，变量值可能会被*转义*以符合查询语言的语法及其使用位置。例如，Prometheus 查询的正则表达式中使用的变量将通过正则表达式转义。有关插值期间进行值转义的详细信息，请阅读具体数据来源的文档主题。

 有关覆盖数据来源默认格式的高级语法的信息，请参见[高级变量格式选项](#advanced-variable-format-options)。

## 其他变量选项
<a name="other-variable-options"></a>

本节说明了其他可用的变量选项。

### 输入变量选择选项
<a name="enter-variable-selection-options"></a>

您可以使用**选择选项**来管理变量选项选择。所有选择选项都是可选的，默认处于关闭状态。

#### Multi-value
<a name="multi-value"></a>

如果启用此选项，则变量下拉列表支持同时选择多个选项。有关更多信息，请参阅 [格式化多值变量](#formatting-multi-value-variables)。

#### 包含全部选项
<a name="include-all-option"></a>

Grafana 工作区在变量下拉列表中添加了一个`All`选项。如果最终用户选择此选项，则会选择所有变量选项。

#### 自定义所有值
<a name="custom-all-value"></a>

仅当选择**包含全部选项**时，此选项才可见。

要定义`All`选项的值，请在**自定义所有值**字段中输入正则表达式、glob 或 Lucene 语法。

默认情况下，`All`值包括组合表达式中的所有选项。该值可能会变得很长，并且可能会出现性能问题。有时最好指定一个自定义所有值，比如通配符正则表达式。

在**自定义所有值**选项中使用自定义正则表达式、glob 或 Lucene 语法时，它永远不会被转义，因此必须考虑数据来源的有效值是什么。

### 高级变量格式选项
<a name="advanced-variable-format-options"></a>

 变量插值的格式取决于数据来源，但在某些情况下，可能需要更改默认格式。

 例如，MySQL 数据来源的默认格式是以逗号分隔的形式联接多个值，并使用引号：`'server01','server02'`。在某些情况下，您可能希望使用逗号分隔的字符串，但不使用引号：`server01,server02`。为此，请使用以下高级变量格式选项。

#### 一般语法
<a name="general-syntax"></a>

 语法：`${var_name:option}`

如果指定了任何无效的格式选项，`glob` 则为默认选项或备用选项。

#### CSV
<a name="variables-csv"></a>

 将具有多个值的变量格式化为逗号分隔的字符串。

```
servers = ['test1', 'test2']
String to interpolate: '${servers:csv}'
Interpolation result: 'test1,test2'
```

#### 分布式 OpenTSDB
<a name="distributed---opentsdb"></a>

 以 OpenTSDB 自定义格式来格式化具有多个值的变量。

```
servers = ['test1', 'test2']
String to interpolate: '${servers:distributed}'
Interpolation result: 'test1,servers=test2'
```

#### Doublequote
<a name="doublequote"></a>

 将单值和多值变量格式化为逗号分隔的字符串，在每个值中使用 `\"` 对 `"` 进行转义，并在每个值两侧加上 `"`。

```
servers = ['test1', 'test2']
String to interpolate: '${servers:doublequote}'
Interpolation result: '"test1","test2"'
```

#### Glob – Graphite
<a name="glob---graphite"></a>

 将具有多个值的变量格式化为 glob（用于 Graphite 查询）。

```
servers = ['test1', 'test2']
String to interpolate: '${servers:glob}'
Interpolation result: '{test1,test2}'
```

#### JSON
<a name="json"></a>

 将具有多个值的变量格式化为逗号分隔的字符串。

```
servers = ['test1', 'test2']
String to interpolate: '${servers:json}'
Interpolation result: '["test1", "test2"]'
```

#### Lucene- OpenSearch
<a name="lucene---opensearch"></a>

 以 Lucene 格式格式化具有多个值的变量。 OpenSearch

```
servers = ['test1', 'test2']
String to interpolate: '${servers:lucene}'
Interpolation result: '("test1" OR "test2")'
```

#### Percentencode
<a name="percentencode"></a>

 格式化单值和多值变量以用于 URL 参数。

```
servers = ['foo()bar BAZ', 'test2']
String to interpolate: '${servers:percentencode}'
Interpolation result: 'foo%28%29bar%20BAZ%2Ctest2'
```

#### Pipe
<a name="pipe"></a>

 将具有多个值的变量格式化为以竖线分隔的字符串。

```
servers = ['test1.', 'test2']
String to interpolate: '${servers:pipe}'
Interpolation result: 'test1.|test2'
```

#### Raw
<a name="raw"></a>

 关闭特定于数据来源的格式化，如 SQL 查询中的单引号。

```
servers = ['test1.', 'test2']
String to interpolate: '${var_name:raw}'
Interpolation result: '{test.1,test2}'
```

#### 正则表达式
<a name="regex"></a>

 将具有多个值的变量格式化为正则表达式字符串。

```
servers = ['test1.', 'test2']
String to interpolate: '${servers:regex}'
Interpolation result: '(test1\.|test2)'
```

#### Singlequote
<a name="singlequote"></a>

 将单值和多值变量格式化为逗号分隔的字符串，在每个值中使用 `\'` 对 `'` 进行转义，并在每个值两侧加上 `'`。

```
servers = ['test1', 'test2']
String to interpolate: '${servers:singlequote}'
Interpolation result: "'test1','test2'"
```

#### Sqlstring
<a name="sqlstring"></a>

 将单值和多值变量格式化为逗号分隔的字符串，在每个值中使用 `''` 对 `'` 进行转义，并在每个值两侧加上 `'`。

```
servers = ["test'1", "test2"]
String to interpolate: '${servers:sqlstring}'
Interpolation result: "'test''1','test2'"
```

#### 文本
<a name="text"></a>

 将单值和多值变量格式化为其文本表示形式。对于单个变量，仅返回文本表示形式。对于多值变量，它将返回与 `+` 组合的文本表示形式。

```
servers = ["test1", "test2"]
String to interpolate: '${servers:text}'
Interpolation result: "test1 + test2"
```

### 格式化多值变量
<a name="formatting-multi-value-variables"></a>

对选择了多个值的变量进行插值会比较麻烦，因为如何将多个值格式化为字符串，而且该字符串在使用该变量的给定上下文中有效，这不是个简单明了的过程。Grafana 尝试解决该问题的方式是，它会通过启用每个数据来源插件来通知模板插值引擎对多个值使用什么格式。

**注意**  
 变量上的**自定义所有值**选项必须为空，Grafana 才能将所有值格式化为单个字符串。如果将该选项留空，则 Grafana 会将查询中的所有值连接在一起（相加）。与 `value1,value2,value3` 类似。如果使用自定义 `all` 值，则该值将类似于 `*` 或 `all`。

#### Multi-value 带有 Graphite 数据源的变量
<a name="multi-value-variables-with-a-graphite-data-source"></a>

 Graphite 使用 glob 表达式。在这种情况下，如果当前变量值为 *host1*、*host2* 和 *host3*，则具有多个值的变量将插值为 `{host1,host2,host3}`。

#### Multi-value 带有 Prometheus 或 InfluxDB 数据源的变量
<a name="multi-value-variables-with-a-prometheus-or-influxdb-data-source"></a>

 InfluxDB 和 Prometheus 使用正则表达式，因此相同的变量将插值为 `(host1|host2|host3)`。每个值也将进行正则表达式转义。否则，带有正则表达式控制字符的值将中断正则表达式。

#### Multi-value 带有弹性数据源的变量
<a name="multi-value-variables-with-an-elastic-data-source"></a>

Amazon OpenSearch 使用 Lucene 查询语法，因此相同的变量格式为。`("host1" OR "host2" OR "host3")`在这种情况下，必须对每个值进行转义，以便该值仅包含 Lucene 控制词和引号。

#### 格式问题故障排除
<a name="formatting-troubles"></a>

 自动转义和格式化可能会导致问题。理解问题背后的逻辑可能会比较困难，特别是对于 InfluxDB 和 Prometheus 来说，使用正则表达式语法要求在正则表达式运算符上下文中使用变量。

 如果您不希望 Grafana 执行这种自动正则表达式转义和格式化，您必须执行以下操作之一：
+ 关闭 “**全部**Multi-value**包含” 选项**选项。
+ 使用 [原始变量格式]({{< relref "advanced-variable-format-options.md\#raw" >}})。

### 使用正则表达式过滤变量
<a name="filter-variables-with-regex"></a>

 使用 Regex Query 选项可以筛选变量查询返回的选项列表或修改返回的选项。

本节介绍如何使用正则表达式筛选和修改变量下拉列表中的值。

 通过 Regex Query 选项，您可以筛选变量查询返回的选项列表或修改返回的选项。有关详细信息，请参阅[正则表达式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions)。

 对以下选项列表进行筛选的示例：

```
backend_01
backend_02
backend_03
backend_04
```

#### 筛选以仅返回以 `01` 或 `02` 结尾的选项
<a name="filter-so-that-only-the-options-that-end-with-01-or-02-are-returned"></a>

 正则表达式：

```
/.*[01|02]/
```

 结果：

```
backend_01
backend_02
```

#### 使用正则表达式捕获组筛选和修改选项以返回部分文本
<a name="filter-and-modify-the-options-using-a-regex-capture-group-to-return-part-of-the-text"></a>

 正则表达式：

```
/.*(01|02)/
```

 结果：

```
01
02
```

#### 筛选和修改 – Prometheus 示例
<a name="filter-and-modify---prometheus-example"></a>

 选项列表：

```
up{instance="demo.robustperception.io:9090",job="prometheus"} 1 1521630638000
up{instance="demo.robustperception.io:9093",job="alertmanager"} 1 1521630638000
up{instance="demo.robustperception.io:9100",job="node"} 1 1521630638000
```

 正则表达式：

```
/.*instance="([^"]*).*/
```

 结果：

```
demo.robustperception.io:9090
demo.robustperception.io:9093
demo.robustperception.io:9100
```

#### 使用命名文本和值捕获组进行筛选和修改
<a name="filter-and-modify-using-named-text-and-value-capture-groups"></a>

使用命名的捕获组可以从变量查询返回的选项中捕获单独的“文本”和“值”部分。变量下拉列表可以包含每个可选择值的友好名称。

 例如，在查询 `node_hwmon_chip_names` Prometheus 指标时，`chip_name` 比 `chip` 值更容易被记住。从以下变量查询结果开始。

```
node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_0",chip_name="enp216s0f0np0"} 1
node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_1",chip_name="enp216s0f0np1"} 1
node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_2",chip_name="enp216s0f0np2"} 1
node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_3",chip_name="enp216s0f0np3"} 1
```

 通过以下正则表达式传递。

```
/chip_name="(?<text>[^"]+)|chip="(?<value>[^"]+)/g
```

 生成了以下下拉列表。

```
Display Name          Value
------------          -------------------------
enp216s0f0np0         0000:d7:00_0_0000:d8:00_0
enp216s0f0np1         0000:d7:00_0_0000:d8:00_1
enp216s0f0np2         0000:d7:00_0_0000:d8:00_2
enp216s0f0np3         0000:d7:00_0_0000:d8:00_3
```

 **注意：**仅支持 `text` 和 `value` 捕获组名称。

### 重复面板或行
<a name="repeat-panels-or-rows"></a>

 您可以使用*模板变量*创建动态控制面板。在将查询发送到数据库之前，查询中的所有变量都会扩展为变量的当前值。使用变量，您可以为所有服务重复使用单个控制面板。

 模板变量对于在整个控制面板上动态地更改查询非常有用。如果您希望 Grafana 根据您选择的值动态地创建新的面板或行，则可以使用*重复*功能。

#### 重复面板
<a name="repeating-panels"></a>

 如果您开启了 `Multi-value` 或 `Include all value` 选项的变量，您可以选择一个面板，让 Grafana 为每个选定的值重复该面板。在面板编辑模式下，您可以在*常规选项卡*下找到*重复*功能。

 `direction` 控制面板的排列方式。

如果您选择`horizontal`，面板将并排排列。Grafana 会自动调整每个重复面板的宽度，以便填充整行。当前，您不能将一行中的其他面板与重复的面板混合使用。

 设置`Max per row`以告诉 Grafana 每行最多想要多少个面板。其默认值为 *4*。

如果您选择`vertical`，面板将从上到下排列成一列。重复面板的宽度与正在重复的第一个面板（原始模板）的宽度相同。

仅对第一个面板（原始模板）进行更改。要使更改在所有面板上生效，您需要开始动态重新构建控制面板。您可以通过更改变量值（即重复的基础）或重新加载控制面板来实现此目的。

**注意**  
重复面板要求变量选择一个或多个项目。您不能将面板重复零次以将其隐藏。

#### 重复行
<a name="repeating-rows"></a>

 如以上面板的示例中所示，如果使用 `Multi-value` 或 `Include all value` 选择选项设置了变量，则也可以重复行。

 要开启此功能，必须先使用*添加面板*菜单添加新*行*。然后，将鼠标悬停在行标题上并选择齿轮按钮以访问`Row Options`配置面板。然后，您可以选择要为其重复该行的变量。

 最佳做法是在行标题中也使用变量。