使用 ODBC SQL 查询进行发现

概述

这种类型的低级发现是使用 SQL 查询完成的,其结果会自动转换为适用于低级发现的 JSON 对象。

监控项键值

SQL 查询通过 "Database monitor" 监控项类型执行。
因此,为了使 "Database monitor" 发现规则正常工作,ODBC 监控 页面上的大多数说明都适用。

在 "Database monitor" 发现规则中可以使用两个监控项键值:

  • db.odbc.discovery[<unique short description>,<dsn>,<connection string>] - 此监控项会将 SQL 查询结果转换为 JSON 数组,把查询结果中的列名转换为低级别发现宏名称,并与发现到的字段值配对。
    这些宏可用于创建监控项、触发器等原型。
    另请参见:使用 db.odbc.discovery

  • db.odbc.get[<unique short description>,<dsn>,<connection string>] - 此监控项会将 SQL 查询结果转换为 JSON 数组,同时保留查询结果中的原始列名作为 JSON 中的字段名,并与发现到的值配对。
    db.odbc.discovery[] 相比,此监控项不会在返回的 JSON 中创建低级别发现宏,因此无需检查列名是否可以作为有效的宏名称。
    如有需要,可以使用 自定义 LLD 宏 功能作为额外步骤定义低级别发现宏,并通过 JSONPath 指向返回的 JSON 中已发现的值。
    另请参见:使用 db.odbc.get

使用 db.odbc.discovery

以下示例演示如何基于对 Zabbix 数据库的 ODBC 查询,使用 Zabbix proxy 的低级别发现将 SQL 查询转换为 JSON。 这对于自动创建 zabbix[proxy,<name>,lastaccess] 内部监控项 很有用,可用于监控哪些 proxy 仍然在线。

先从发现规则配置开始:

lld\_rule\_odbc.png

所有必填输入字段都用红色星号标记。

这里使用以下直接查询 Zabbix 数据库的语句来选择所有 Zabbix proxy,以及它们正在监控的主机数量。 例如,主机数量可用于过滤掉空的 proxy:

mysql> SELECT h1.host, COUNT(h2.host) AS count FROM hosts h1 LEFT JOIN hosts h2 ON h1.hostid = h2.proxyid WHERE h1.status IN (5, 6) GROUP BY h1.host;
+---------+-------+
| host    | count |
+---------+-------+
| Japan 1 |     5 |
| Japan 2 |    12 |
| Latvia  |     3 |
+---------+-------+
3 rows in set (0.01 sec)

根据 db.odbc.discovery[,{$DSN}] 监控项的内部工作机制,该查询结果会自动转换为以下 JSON:

[
    {
        "{#HOST}": "Japan 1",
        "{#COUNT}": "5"
    },
    {
        "{#HOST}": "Japan 2",
        "{#COUNT}": "12"
    },
    {
        "{#HOST}": "Latvia",
        "{#COUNT}": "3"
    }
]

可以看到,列名会变成宏名,而选中的行会变成这些宏的值。

如果列名如何转换为宏名并不明显,建议像上面的示例那样使用列别名,例如 COUNT(h2.host) AS count

如果某个列名无法转换为有效的宏名,发现规则将变为不受支持,并显示错误信息,详细说明出错的列编号。 如果需要更多帮助,可在 Zabbix 服务器日志文件中将 DebugLevel=4 后查看获取到的列名:

$ grep db.odbc.discovery /tmp/zabbix_server.log
 ...
 23876:20150114:153410.856 In db_odbc_discovery() query:'SELECT h1.host, COUNT(h2.host) FROM hosts h1 LEFT JOIN hosts h2 ON h1.hostid = h2.proxy_hostid WHERE h1.status IN (5, 6) GROUP BY h1.host;'
 23876:20150114:153410.860 db_odbc_discovery() column[1]:'host'
 23876:20150114:153410.860 db_odbc_discovery() column[2]:'COUNT(h2.host)'
 23876:20150114:153410.860 End of db_odbc_discovery():NOTSUPPORTED
 23876:20150114:153410.860 Item [Zabbix server:db.odbc.discovery[proxies,{$DSN}]] error: Cannot convert column #2 name to macro.

现在我们已经了解 SQL 查询如何转换为 JSON 对象,就可以在监控项原型中使用 {#HOST} 宏:

item\_prototype\_odbc.png

完成发现后,将为每个 proxy 创建一个监控项:

discovered\_items\_odbc1.png

使用 db.odbc.get

使用 db.odbc.get[,{$DSN}] 和以下 SQL 示例:

mysql> SELECT h1.host, COUNT(h2.host) AS count FROM hosts h1 LEFT JOIN hosts h2 ON h1.hostid = h2.proxyid WHERE h1.status IN (5, 6) GROUP BY h1.host;
+---------+-------+
| host    | count |
+---------+-------+
| Japan 1 |     5 |
| Japan 2 |    12 |
| Latvia  |     3 |
+---------+-------+
3 rows in set (0.01 sec)

将返回以下 JSON:

[
    {
        "host": "Japan 1",
        "count": "5"
    },
    {
        "host": "Japan 2",
        "count": "12"
    },
    {
        "host": "Latvia",
        "count": "3"
    }
]

如你所见,其中没有低级别发现宏。 不过,可以在发现规则的 LLD macros 选项卡中使用 JSONPath 创建自定义低级别发现宏,例如:

{#HOST} → $.host

现在,这个 {#HOST} 宏可以在监控项原型中使用:

item\_prototype\_odbc.png