Zabbixサーバーまたはプロキシにデータを送信する
zabbix_utils を使用すると、Zabbixサーバーまたはプロキシ上のトラッパーアイテムにアイテムの値を送信できます(Zabbix sender と同様)。
単一の値、複数の値、さらには複数のZabbixクラスターを対象に送信することもできます。
データは同期モードまたは非同期モードで送信できます。
- 同期モードでは、Pythonスクリプトは値を送信し、応答を待ってから処理を続行します。これは、シンプルで順次的かつ予測可能な処理に適しています。
- 非同期モードでは、スクリプトは各応答を待たずに値を送信するため、他の処理を並行して進めることができます。これは、応答の遅いリクエストや大量のデータのバッチ処理により効率的です。
このページの例は同期モードに重点を置いていますが、非同期モード も同様のパターンに従います。 追加の例は、GitHubリポジトリの zabbix_utils で利用できます。
インポート
アイテムの値を送信するために zabbix_utils を使用するには、スクリプトで Sender クラスをインポートします。
from zabbix_utils import Sender
複数の値を送信する場合は、ItemValue クラスもインポートできます。
from zabbix_utils import Sender, ItemValue
単一の値を送信
アイテムの値を送信するには、次のようにします。
Senderインスタンスを作成し、ZabbixサーバーまたはプロキシのIPアドレスとポートを指定します。- 次の形式で、
Senderインスタンスのsend_value()メソッドを呼び出します。
sender_instance.send_value('host', 'item.key', 'value', optional_timestamp, optional_nanoseconds)
たとえば、Linux server ホストの service.status トラッパーアイテムに 1 を送信するには、次のようにします。
sender = Sender(server='127.0.0.1', port=10051)
response = sender.send_value('Linux server', 'service.status', 1)
デフォルト以外のIPを使用する
スクリプトを実行しているサーバーが複数のIPアドレスを持つ場合、Zabbixサーバーまたはプロキシに値を送信する際に、Sender が使用する source_ip を指定できます。
sender = Sender(
server='127.0.0.1',
port=10051,
source_ip='10.10.7.1'
)
タイムアウトの使用
応答 timeout を Sender に設定することで、スクリプトが Zabbixサーバーまたはプロキシからの応答をあきらめるまでに待機する時間を制御できます。
sender = Sender(
server='127.0.0.1',
port=10051,
timeout=30
)
エージェント設定ファイルの使用
ローカルのZabbixエージェントまたはエージェント 2 の設定ファイルから、zabbix_utils に Server または ServerActive パラメータを読み取らせることができます。
この場合、Sender インスタンスの作成時に接続パラメータを指定する必要はありません。
sender = Sender(
use_config=True,
config_path='/etc/zabbix/zabbix_agent2.conf'
)
ServerActive に複数のサーバーインスタンスを持つ1つ以上のZabbixクラスタが含まれている場合、Sender は各クラスタ内で最初に利用可能なサーバーにデータを送信します。
ServerActive が設定されていない場合は、Server のアドレスにデフォルトポート (10051) を付けて使用します。
暗号化の使用
Sender には組み込みの暗号化サポートは含まれていませんが、サードパーティライブラリを使用してラッパーを作成することで対応できます。
def psk_wrapper(sock, tls):
# ...
# ソケット用のTLS PSKラッパーの実装
# ...
sender = Sender(
server='127.0.0.1',
port=10051,
socket_wrapper=psk_wrapper
)
単一の値に対するレスポンス
Zabbixサーバーまたはプロキシから返されたレスポンスはライブラリによって処理され、TrapperResponse オブジェクトとして返されます。
print(response)
# {"processed": 1, "failed": 0, "total": 1, "time": "0.000123", "chunk": 1}
print(response.processed)
# 1
print(response.failed)
# 0
print(response.total)
# 1
非同期モード
非同期モードでは、PythonスクリプトはZabbixサーバーまたはプロキシからの応答を待たずに値を送信できます。
これにより、多数の値を送信する必要がある場合や、一部の値の送信に長い時間がかかる場合に、スクリプトの効率を高めることができます。
非同期モードを使用する場合、同期モードと比べていくつか重要な違いがあります。
- Pythonの
asyncioモジュールをインポートします(最初に必要な依存関係をinstallする必要があります)。 Senderの代わりにAsyncSenderをインポートします。- コードを
async関数の中に記述します。 send_value()メソッドを呼び出す際にawaitを使用します。
たとえば、非同期モードを使用して単一の値を送信するには、次のようにします。
# 1. 非同期モード用にasyncioと、zabbix_utilsからAsyncSenderをインポートします:
import asyncio
from zabbix_utils import AsyncSender
# 2. すべてのデータ送信処理(awaitが必要)が実行されるメインのasync関数を定義します:
async def main():
sender = AsyncSender(server='127.0.0.1', port=10051)
response = await sender.send_value('Linux server', 'service.status', 1)
# 3. Zabbixサーバーまたはプロキシから返された応答を表示します:
print(response)
# 4. asyncioのイベントループを使用してasync main()関数を実行します:
asyncio.run(main())
複数の値を送信する
複数の値を送信するには、次の手順を実行します。
ItemValueオブジェクトの配列を準備します。各オブジェクトは、send_value()メソッドと同じ形式を使用します。Senderインスタンスを作成し、ZabbixサーバーまたはプロキシのIPアドレスとポートを指定します。Senderインスタンスでsend_value()の代わりにsend()メソッドを呼び出し、送信する値を含むオブジェクトの配列を指定します。
たとえば、5つの値を異なるホストに送信するには、次のようにします。
items = [
ItemValue('server-de', 'service.status', 'up', 1770887205, 100),
ItemValue('server-fr', 'service.status', 'up', 1770887205, 100),
ItemValue('server-uk', 'service.status', 'up', 1770887205, 100),
ItemValue('server-nl', 'service.status', 'up', 1770887205, 100),
ItemValue('server-pl', 'service.status', 'up', 1770887205, 100),
]
sender = Sender(server='127.0.0.1', port=10051)
response = sender.send(items)
カスタムチャンクサイズの使用
1回のリクエストでトラッパーアイテムが受け付けられる数より多くの値を送信する必要がある場合は、それらをチャンクに分割できます。
デフォルトでは、チャンクサイズは250個の値です。
Sender インスタンスの作成時に chunk_size パラメータを設定することで変更できます。
例えば、5個の値を3つのチャンク(2-2-1)で送信するには、chunk_size パラメータを 2 に設定します。
items = [
ItemValue('server-de', 'service.status', 'up'),
ItemValue('server-fr', 'service.status', 'up'),
ItemValue('server-uk', 'service.status', 'up'),
ItemValue('server-nl', 'service.status', 'up'),
ItemValue('server-pl', 'service.status', 'up'),
]
sender = Sender(server='127.0.0.1', port=10051, chunk_size=2)
response = sender.send(items)
複数のZabbixクラスターに値を送信する
複数のZabbixクラスターに値を送信するには、次の手順を実行します。
- Zabbixクラスターの配列を準備します。クラスターに複数のノードがある場合、値は各クラスターの最初の利用可能なノードに送信されます。
- Zabbixクラスターの配列を指定して、
Senderを作成します。 send_value()メソッドと同じ形式で、Senderインスタンスの `send_value()`` メソッドを呼び出します。
たとえば、各クラスターの最初の利用可能なノードに値を送信するには、次のようにします。
zabbix_clusters = [
['zabbix.cluster1.node1', 'zabbix.cluster1.node2:10051'],
['zabbix.cluster2.node1:10051', 'zabbix.cluster2.node2', 'zabbix.cluster2.node3']
]
sender = Sender(clusters=zabbix_clusters)
response = sender.send_value('Linux server', 'service.status', 1)
複数の値に対するレスポンス
デフォルトでは、Sender はすべてのホストまたはクラスターにまたがる値の送信結果を集約して返します。
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}
より詳細な情報が必要な場合は、response.details 属性を使用して、各クラスターおよび各チャンクの結果を確認できます。
print(response)
# {"processed": 2, "failed": 0, "total": 2, "time": "0.000108", "chunk": 2}
if response.failed == 0:
print(f"Value sent successfully in {response.time}")
else:
print(response.details)
# {
# 127.0.0.1:10051: [
# {
# "processed": 1,
# "failed": 0,
# "total": 1,
# "time": "0.000051",
# "chunk": 1
# }
# ],
# zabbix.example.local:10051: [
# {
# "processed": 1,
# "failed": 0,
# "total": 1,
# "time": "0.000057",
# "chunk": 1
# }
# ]
# }
for node, chunks in response.details.items():
for resp in chunks:
print(f"Processed {resp.processed} of {resp.total} at {node.address}:{node.port}")
# Processed 1 of 1 at 127.0.0.1:10051
# Processed 1 of 1 at zabbix.example.local:10051