[comment]: # ({03437da9-5508ac64})

# 4 自动发现SNMP OIDs

[comment]: # ({/03437da9-5508ac64})

[comment]: # ({b8212a1d-3680a9fa})
#### 概述

在本节中，我们将对一个 SNMP 设备执行[低级别发现](/manual/discovery/low_level_discovery)。

自 Zabbix 服务器/proxy 6.4 起，已支持这种基于 SNMP OID 的发现方法。

[comment]: # ({/b8212a1d-3680a9fa})

[comment]: # ({3e67054c-bff9418f})
#### 示例配置

1\. 创建一个 SNMP agent 监控项，使用如下键值：

```bash
walk[.1.3.6.1.4.1.9999.1.1.1.1]
```

![](../../../../../assets/en/manual/discovery/low_level_discovery/snmp_walk_item.png)

该监控项执行一次 SNMP 表 walk，并在一次请求中返回表中的所有条目，返回格式与 `snmpwalk` 工具在使用格式化选项 `-Oe -Ot -On` 时的输出一致。

它将返回如下多行文本值：

```ini
.1.3.6.1.4.1.9999.1.1.1.1.1.1 = STRING: "Temperature Sensor"
.1.3.6.1.4.1.9999.1.1.1.1.2.1 = STRING: "temp"
.1.3.6.1.4.1.9999.1.1.1.1.3.1 = 100
.1.3.6.1.4.1.9999.1.1.1.1.1.2 = STRING: "Humidity Sensor"
.1.3.6.1.4.1.9999.1.1.1.1.2.2 = STRING: "humidity"
.1.3.6.1.4.1.9999.1.1.1.1.3.2 = 200
```

2\. 创建一个发现规则：

-   在 *Name* 字段中，输入一个描述性的发现规则名称（例如，“Discover sensors”）。
-   在 *Type* 字段中，选择“Dependent item”。
-   在 *Key* 字段中，输入一个描述性的键值（例如，“net.if.discovery”）。
-   在 *Master item* 字段中，选择“SNMP walk item”。

![](../../../../../assets/en/manual/discovery/low_level_discovery/snmp_discovery_dep_item.png)

3\. 在 *Preprocessing* 选项卡中，添加一个预处理步骤，在 *Name* 下拉框中选择 “SNMP walk to JSON”，并配置 3 个参数：

- *Field name*：“{#SENSORNAME}”；*OID prefix*：“.1.3.6.1.4.1.9999.1.1.1.1.1”；*Format*：“Unchanged”。
- *Field name*：“{#SENSORTYPE}”；*OID prefix*：“.1.3.6.1.4.1.9999.1.1.1.1.2”；*Format*：“Unchanged”。
- *Field name*：“{#SENSORVALUE}”；*OID prefix*：“.1.3.6.1.4.1.9999.1.1.1.1.3”；*Format*：“Unchanged”。

预处理后，发现规则将返回一个由宏集合组成的 JSON 数组。

例如：

```json
[
    {
        "{#SNMPINDEX}": "1",
        "{#SENSORNAME}": "Temperature Sensor",
        "{#SENSORTYPE}": "temp",
        "{#SENSORVALUE}": "100"
    },
    {
        "{#SNMPINDEX}": "2",
        "{#SENSORNAME}": "Humidity Sensor",
        "{#SENSORTYPE}": "humidity",
        "{#SENSORVALUE}": "200"
    }
]
```

每个对象表示一个已发现的传感器，并提供诸如 `{#SNMPINDEX}`、`{#SENSORNAME}`、`{#SENSORTYPE}` 和 `{#SENSORVALUE}` 之类的宏。

它们按 SNMP 索引分组，该索引是每个 OID 末尾的数字后缀（例如 .1、.2）—— 该索引可唯一标识 SNMP 表中的每一行，并会自动提取为 `{#SNMPINDEX}`。

4\. 在该发现规则下，创建一个或多个监控项原型（以发现规则作为 master item）。

例如，传感器值 dependent item：

-   在 *Name* 字段中，输入 “Sensor {#SNMPINDEX}: {#SENSORNAME}”。
-   在 *Type* 字段中，选择 “Dependent item”。
-   在 *Key* 字段中，输入 “sensor.value[{#SNMPINDEX}]”。
-   在 *Master item* 字段中，选择 “SNMP walk item”。

![](../../../../../assets/en/manual/discovery/low_level_discovery/snmp_item_prototype.png)

在 *Preprocessing* 选项卡中，添加一个预处理步骤，在 *Name* 中选择 “SNMP walk value”，并在 *Parameter* 字段中填写 OID “.1.3.6.1.4.1.9999.1.1.1.1.3.{#SNMPINDEX}”。
*Format*：“Unchanged”。

将发现以下监控项：

|Name|Key|提取值的 OID|监控项值|
|----|---|---------------------------------|------------|
|Sensor 1: Temperature Sensor|sensor.value[1]|.1.3.6.1.4.1.9999.1.1.1.1.3.1|100|
|Sensor 2: Humidity Sensor|sensor.value[2]|.1.3.6.1.4.1.9999.1.1.1.1.3.2|200|

当发现规则运行时，将创建诸如 `sensor.value[1]`、`sensor.value[2]` 之类的监控项。

每个 dependent item 都通过预处理从 master item 的 SNMP walk 结果中提取其值，而无需自行执行单独的 SNMP 请求。

5\. 在触发器原型中使用与发现规则相同的宏来引用 dependent item 原型。
例如：

```default
{Template_Sensor:sensor.value[{#SNMPINDEX}].last()} > 75
```

这将为每个已发现的传感器生成一个触发器（例如，sensor.value[1]、sensor.value[2]），并在最新值（温度或湿度）超过 75 时触发。

6\. 为每个已发现的实体包含 dependent item。
图形监控项键值示例：

```default
sensor.value[{#SNMPINDEX}]
```

将为每个 `{#SNMPINDEX}` 创建一个图形，用于绘制温度和湿度随时间变化的曲线。

无论发现了多少个监控项，此配置在每个轮询周期内都只执行一次 SNMP walk 请求。
所有 dependent item 都通过预处理从 master SNMP walk 结果中提取其值，从而显著减少 SNMP 流量和负载。

[comment]: # ({/3e67054c-bff9418f})

[comment]: # ({1f7ddedc-indexes})
#### 使用 walk[] 的动态索引

动态索引（例如接口索引）可能会在硬件重新配置时发生变化。
为适应这种行为，可以创建一个主 SNMP walk 发现规则，并使用如下 key：

```bash
walk[1.3.6.1.2.1.2.2.1.10]
```

在经过 SNMP walk to JSON 预处理后，结果可能类似于：

```json
[
    {
        "{#SNMPINDEX}": "2",
        "{#VALUE}": "123456"
    },
    {
        "{#SNMPINDEX}": "3",
        "{#VALUE}": "654321"
    }
]
```

一个依赖监控项原型使用 `{#SNMPINDEX}` 宏来构造 key：

```default
net.if.in[{#SNMPINDEX}]
```

此原型的预处理包含名称为 “SNMP walk value” 的步骤，并在 *Parameter* 字段中使用 OID “1.3.6.1.2.1.2.2.1.10.{#SNMPINDEX}”。
*Format*：“Unchanged”。

在运行时，将创建实际监控项，例如 `net.if.in[2]` 和 `net.if.in[3]`。
如果某个接口索引发生变化（例如，在 SNMP 表中索引 `2` 被 `5` 替换），那么在发现规则下一次运行时：

-   旧的依赖监控项 net.if.in[2] 会被标记为“丢失”或被移除，并且不再为该监控项采集新数据。
-   将创建新的依赖监控项 net.if.in[5]，并从空历史记录开始。
-   net.if.in[2] 的历史数据不会自动迁移到 net.if.in[5]。

触发器原型示例：

```default
{Template_Interface:net.if.in[{#SNMPINDEX}].last()} > 1000000000
```

图形原型示例包含以下监控项：

```default
net.if.in[{#SNMPINDEX}]
net.if.out[{#SNMPINDEX}]
```

此配置可确保对具有动态索引的表进行可靠监控，同时尽量减少 SNMP 流量——每个轮询周期只需要执行一次 SNMP walk，而依赖监控项原型会提取所需的值。

[comment]: # ({/1f7ddedc-indexes})

[comment]: # ({1815f72a-2be94533})
#### 已发现的实体

当服务器运行时，它将根据 SNMP 发现规则返回的值创建实际的依赖监控项、触发器和图形。

[comment]: # ({/1815f72a-2be94533})
