12 利用ODBC SQL查询执行自动发现

概述

此类低级别自动发现 通过使用SQL查询实现,其结果自动转换成一个匹配低级别自动发现的JSON格式的JSON对象。

监控项键值

设置监控项类型为 "数据库监控" 来执行SQL查询。 因此,ODBC监控 页面中的大部分用法说明,都是为了"数据库监控"类型的自动发现规则能正常执行。

"数据库监控"类型的自动发现规则会用到两个键值:

  • db.odbc.discovery[<唯一简短描述>,<dsn(数据源名称)>,<连接字符串>] - 此监控项将SQL查询结果转换为一个JSON数组,其中表的字段名称会转换为宏的名称,宏的名称与发现的对应值成对匹配。这些宏可用于创建监控项和触发器等原型。另请参阅: 使用 db.odbc.discovery.

  • db.odbc.get[<唯一简短描述>,<dsn(数据源名称)>,<连接字符串>] - 此监控项将SQL查询结果转换为一个JSON数组,保留原始表字段名称作为输入框的名称,以JSON格式表示,并与对应的已发现的值成对匹配。相比于 db.odbc.discovery[], 此监控项不在返回的JSON数组中创建低级别自动发现的宏, 因此无需检查表字段名称是否是有效的宏名称。 根据需要,可以将低级发现宏定义作为附加步骤,针对返回的JSON值,在 自定义LLD宏中使用JSONPath方法。另请参阅: 使用 db.odbc.get.

使用 db.odbc.discovery

让我们看一个SQL查询转换为JSON数组的真实案例。我们通过在Zabbix数据库上使用ODBC查询对Zabbix proxy执行低级别自动发现。 此功能对于自动创建 "zabbix[proxy,<name>,lastaccess]" 内部监控项 并监控存活的proxy很有用。

下面开始配置自动发现规则:

lld_rule_odbc.png

所有强制输入区域均标记为红色星号。

此处Zabbix数据库上的查询用于查询所有Zabbix proxy,连同proxy所监控的主机数量. 比如,主机数量可用于过滤掉没有监控任何主机的proxy:

mysql> SELECT h1.host, COUNT(h2.host) AS count FROM hosts h1 LEFT JOIN hosts h2 ON h1.hostid = h2.proxy_hostid 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"。

如果字段名称无法转换为有效的宏名称,则自动发现规则变为unsupport(不支持的)状态,其错误消息显示不合规字段的编号. 如果需要额外帮助, debug级别DebugLevel=4的Zabbix server日志文件中可找到获取的字段名称:

$ 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.proxy_hostid 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"
           }
       ]

可以看到, 返回的JSON数组中不包含低级别自动发现的宏. 然而, 可以在自动发现规则的LLD 宏 选项卡中利用JSONPath来自定义宏, 比如:

{#HOST} → $.host

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

item_prototype_odbc.png