12 ODBC SQLクエリを使用した検出

概要

このタイプの低レベルディスカバリはSQLクエリを使用して実行され、その結果は低レベルディスカバリに適したJSONオブジェクトに自動的に変換されます。

アイテムキー

SQLクエリは、「Database monitor」アイテムタイプを使用して実行されます。 そのため、動作する「Database monitor」ディスカバリルールを作成するには、ODBC monitoring ページの説明の大部分が適用されます。

「Database monitor」ディスカバリルールでは、2つのアイテムキーを使用できます。

  • db.odbc.discovery[<unique short description>,<dsn>,<connection string>] - このアイテムは、SQLクエリの結果をJSON配列に変換し、クエリ結果の列名を、検出されたフィールド値と対になるローレベルディスカバリマクロ名に変換します。 これらのマクロは、アイテム、トリガーなどのプロトタイプの作成に使用できます。 あわせて参照: Using db.odbc.discovery

  • db.odbc.get[<unique short description>,<dsn>,<connection string>] - このアイテムは、SQLクエリの結果をJSON配列に変換し、クエリ結果の元の列名を、検出された値と対になるJSON内のフィールド名として保持します。 db.odbc.discovery[] と比較すると、このアイテムは返されるJSON内にローレベルディスカバリマクロを作成しません。そのため、列名が有効なマクロ名として使用可能かどうかを確認する必要はありません。 ローレベルディスカバリマクロは、必要に応じて、返されるJSON内の検出値を指すJSONPathを使用した custom LLD macro 機能により、追加のステップとして定義できます。 あわせて参照: Using db.odbc.get

db.odbc.discovery の使用

SQLクエリがどのようにJSONに変換されるかを示す実用的な例として、Zabbixデータベースに対してODBCクエリを実行し、Zabbixプロキシのローレベルディスカバリを考えてみましょう。
これは、どのプロキシが稼働しているかを監視するための "zabbix\[proxy,<name>,lastaccess\]" 内部アイテム を自動作成するのに役立ちます。

まず、ディスカバリルールの設定から始めます。

lld\_rule\_odbc.png

必須の入力フィールドには、すべて赤いアスタリスクが付いています。

ここでは、Zabbixデータベースに対する次の直接クエリを使用して、すべてのZabbixプロキシと、それらが監視しているホスト数を選択します。
ホスト数は、たとえば空のプロキシを除外するためのフィルタリングに使用できます。

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

ディスカバリが実行されると、各プロキシに対して1つのアイテムが作成されます。

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"
    }
]

ご覧のとおり、ここにはローレベルディスカバリマクロはありません。
ただし、カスタムのローレベルディスカバリマクロは、JSONPath を使用してディスカバリルールの LLD macros タブで作成できます。例えば次のようになります。

{#HOST} → $.host

これで、この {#HOST} マクロをアイテムのプロトタイプで使用できます。

item\_prototype\_odbc.png