[comment]: # ({11b68223-d30dc182})
# 2 用户宏

[comment]: # ({/11b68223-d30dc182})

[comment]: # ({9bc1f184-4f638906})
#### 概述

除了[支持](/manual/appendix/macros/supported_by_location)开箱即用的宏之外，Zabbix
还支持更灵活的用户宏。

用户宏可以在全局、模板和主机级别进行定义。这些宏具有一个特殊的语法：

    {$MACRO}

Zabbix 根据以下优先级来解析宏：

1.  主机级别的宏 (首先检查)；
2.  为主机的第一级别模板定义的宏（即直接链接到主机的模板），按照模板 ID
    来排序；
3.  为主机的第二级别模板定义的宏，按照模板 ID 来排序；
4.  为主机的第三级别模板定义的宏，按照模板ID来排序等；
5.  全局宏 (最后检查)。

换言之，如果一个主机不存在一个宏， Zabbix
将会尝试在级别递增的主机模板中找到它，如果仍然找不到，那么将会使用全局宏（如果全局宏存在的话）。

如果 Zabbix不能找到宏，那么宏将不能被解析。

用户宏可被用于：

-   监控项名称；
-   监控项键值参数；
-   触发器名称和描述；
-   触发器表达式参数和常量(详细查阅下文的 [示例](#examples))
-   许多其他位置 (详细查阅
    [位置支持的宏](/manual/appendix/macros/supported_by_location))

[comment]: # ({/9bc1f184-4f638906})

[comment]: # ({1ecd7f02-e3755145})
##### 常见的全局和主机宏

-   在几个地方使用全局宏; 然后在所涉及的地方调整或者配置值
-   充分利用内部模板的属性来使用宏：密码，端口号，文件名，正则表达式等等

[comment]: # ({/1ecd7f02-e3755145})

[comment]: # ({cfae93b1-f4946b75})
#### 配置

如果要定义用户宏，请转到Zabbix的前端页面的如下位置：

-   对于全局宏，请访问 // 管理 → 常规 → 右上角下拉菜单选择 “宏” //；
-   对于主机和模板级别的宏，请打开主机或模板属性并查看 *宏* 标签页面。

<note
tip>如果在模板的监控项或触发器使用用户宏，建议将该宏添加到模板，即使它被定义在全局级别上。这样的话，将模板导出至XML文件中，之后在其他系统中导入，那么在其他系统中使用也将会达到预期的使用效果。
:::

宏名称中允许使用以下字符：**A-Z** , **0-9** , **\_** , **.**

[comment]: # ({/cfae93b1-f4946b75})

[comment]: # ({41d324c2-4c860844})
##### 示例

[comment]: # ({/41d324c2-4c860844})

[comment]: # ({2cd1848a-b9cf8f56})
##### 示例 1

在 "Status of SSH daemon" 监控项键值中使用主机级别的宏：

`net.tcp.service[ssh,,{$SSH_PORT}]`

该监控项可以分配给多个主机，前提是在这些主机上定义了 **{$SSH\_PORT}**
的值。

[comment]: # ({/2cd1848a-b9cf8f56})

[comment]: # ({eea65717-2a8b0009})
##### 示例 2

在 "CPU load is too high" 触发器上使用主机级别的宏:

`{ca_001:system.cpu.load[,avg1].last()}>{$MAX_CPULOAD}`

这样的触发器将会在模板上创建，而不会在单个主机中编辑。

<note
tip>如果要使用数值作为函数参数（例如，**max(\#3)**），则在宏定义中要包含井号（hash
mark）例如：SOME\_PERIOD => \#3
:::

[comment]: # ({/eea65717-2a8b0009})

[comment]: # ({4523b848-c59027f2})
##### 示例 3

在"CPU load is too high"触发器中使用了两个宏：

`{ca_001:system.cpu.load[,avg1].min({$CPULOAD_PERIOD})}>{$MAX_CPULOAD}`

请注意，宏可以用作触发器函数的参数，在这个示例中为 **min()** 。

<note
important>在触发器表达式中，如果引用参数或者常量，则用户宏将会解析。如果引用主机、监控项键值、函数、操作或其他触发器表达式的话，他们将不会解析。
:::

[comment]: # ({/4523b848-c59027f2})

[comment]: # ({726e10a4-bd218e2e})
##### 示例 4

同步代理不可达情况下的更新间隔项:

-   定义宏 {$INTERVAL} 并在更新间隔项时间中使用;
-   使用 {$INTERVAL} 作为代理不可达触发器的参数:

`{ca_001:agent.ping.nodata({$INTERVAL})}=1`

[comment]: # ({/726e10a4-bd218e2e})

[comment]: # ({80a283e0-ee0008fc})
##### 示例 5

工作时间集中配置：

-   创建一个全局宏 {$WORKING\_HOURS} 例如 `1-5,09:00-18:00`;
-   在 *Administration* → *General* → *Working time* 中使用;
-   在 *User* → *Media* → *When active* 中使用;
-   在工作时间设置更多的频度的监控项中使用:

![](../../../../assets/en/manual/config/macros/usermacro_example5.png)

-   在动作的条件配置 *Time period* 中使用;
-   如果需要，在 *Administration* → *General* → *Macros*中调整工作时间。

[comment]: # ({/80a283e0-ee0008fc})

[comment]: # ({bf0b6e46-e2688eb3})
#### 用户宏上下文

可以在用户宏中使用可选上下文，允许使用特定的上下文来重写默认的值。

具有上下文的用户宏具有类似的语法：

    {$MACRO:context} 

宏上下文是一个简单的文本值。宏上下文的常见使用案例是使用自动发现[宏值](/manual/discovery/low_level_discovery#using_lld_macros_in_user_macro_contexts)作为用户宏上下文。例如，根据文件系统的挂载点或文件系统类型，可以为挂载的文件系统自动发现定义自动发现触发器原型以使用不同的可使用空间阈值。

在宏上下文中只支持自动发现的宏。任何其他宏都将被忽略，并视为纯文本。

从技术上讲，宏上下文是使用类似于[监控项键值](/manual/config/items/item/key)参数的规则来指定的，除非有一个字符“,”，否则宏上下文是不被解析为几个参数：

-   宏的内容必须引用'"',如果宏内容包含有'}'的字符或者从一个'"'字符.那在引号中的引号必须使用'\\'字符进行转义从而不改变宏的内容,这也说明宏被引用后的字符'"'没有被转义则不能使用,宏
    `{$MACRO:"a:\b\c\"}`是无效的.

```{=html}
<!-- -->
```
-   宏内容中前面的空格会被忽略,后面的空格不会忽略.例如:`{$MACRO:A}` 和
    `{$MACRO: A}` 相同, 但不同于 `{$MACRO:A }`.

```{=html}
<!-- -->
```
-   宏变量中引号外面的空格可以被忽略,但是引号里面的空格不会忽略.宏`{$MACRO:"A"}`,
    `{$MACRO: "A"}`, `{$MACRO:"A" }` 和 `{$MACRO: "A" }`
    相同,但是跟宏`{$MACRO:"A"}` 和 `{$MACRO:" A "}` 不同.

以下的宏是一样的,因为它们表示的内容一样: `{$MACRO:A}`, `{$MACRO: A}` 和
`{$MACRO:"A"}`. 这与监控项相反, `key[a]`, `key[ a]` 和 `key["a"]`
在语法上相同,但唯一性不同。

当宏在使用时,zabbix会查看宏的背景,如果宏没有在主机或者模板上关联,或者有没有在全局宏中定义,那么宏不会被使用。

请参考[使用样例](/manual/discovery/low_level_discovery#using_lld_macros_in_user_macro_contexts)章节中磁盘触发器原型关于宏变量的使用示例.

[comment]: # ({/bf0b6e46-e2688eb3})
