This is a machine translation based on the English version of the article. It might or might not have already been subject to text preparation. If you find errors, please file a GitHub issue that states the paragraph that has to be improved. |
1. はじめに
ここでは、データソース プログラムとスペシャルエージェントの基本についてすでに理解しており、その基本的な仕組みを理解していることを前提としています。 スペシャルエージェントは、データソースプログラムに簡単な設定機能を追加します。 この設定には、セットアップのルールが使用されます。 設定は、取得されるデータの範囲やタイプ、およびエージェント出力として次の処理チェーンに転送される前の前処理に影響します。
各スペシャルエージェントは、Checkmk プログラミングインターフェースに依存しない、独立して実行可能なプログラムです。 データソースプログラムと同様に、スペシャルエージェントも通常のチェック間隔(デフォルトでは通常 1 分)で呼び出されます。 プロセスはスペシャルエージェントによって開始され、エージェントの出力は標準出力に転送されます。 その後、スペシャルエージェントは終了します。 これにより、任意のプログラミング言語でスペシャルエージェントを実装することができます。 ただし、実行時間が短いプロセスでは、Java などのジャストインタイムコンパイル言語は、コンパイル言語や起動の速いインタプリタ言語よりも適していません。
トリガーされるプロセスは、スペシャルエージェントが呼び出されたときにコマンドラインパラメータで設定されます。 そのためには、テキスト入力フィールドやチェックボックスなどの GUI エレメントを特定のパラメータにどのようにマッピングするかを決定します。
この記事のために作成されたコード例は、GitHub リポジトリで入手できます。また、完成した Open-Meteo スペシャルエージェントは、Checkmk Exchange で MKP として入手できます。
2. 「最小限の」スペシャルエージェントの作成
スペシャルエージェントを開発する際には、ファイル作成にそれぞれのサイトユーザーを使用していることを確認する必要があります。 所有者や許可が正しく定義されていないと、問題や非互換性が発生する可能性があります。 |
データソースプログラムとは異なり、スペシャルエージェントはファイルシステムのどこにでも配置することはできません。
Checkmk のディレクトリ階層内に特定の場所があります。
また、ファイル名はagent_ で始まる必要があります。
さらに、スペシャルエージェントは常に Checkmk サイトに登録する必要があります。
したがって、最小限の実行可能なスペシャルエージェントには、スペシャルエージェント、ルール設定、および呼び出し設定の 3 つのファイルが必要です。
2.1. 環境の準備
準備として、~/local/lib/python3/cmk_addons/plugins/<plug-in_family> の下に 3 つのディレクトリを作成してください。
以下の例に示す 4 番目のディレクトリはオプションです。エージェントベースのチェックに使用できます。
OMD[mysite]:~$ mkdir -p local/lib/python3/cmk_addons/plugins/hellospecial/libexec
OMD[mysite]:~$ mkdir -p local/lib/python3/cmk_addons/plugins/hellospecial/rulesets
OMD[mysite]:~$ mkdir -p local/lib/python3/cmk_addons/plugins/hellospecial/server_side_calls
OMD[mysite]:~$ mkdir -p local/lib/python3/cmk_addons/plugins/hellospecial/agent_based2.2. スペシャルエージェント
最小限のスペシャルエージェントとして、「Hello World!」サービスを提供するローカルチェックほど適したものは他にありません。 2 行の出力を作成する単純なシェルスクリプトでも、この目的を果たすことができます。
#!/bin/bash
echo '<<<local>>>'
echo '0 "Hello special" - This static service is always OK'このスクリプトにはファイル拡張子は付けないでください。 |
忘れないでください: ファイルは実行可能にする必要があります:
OMD[mysite]:~$ chmod 755 local/lib/python3/cmk_addons/plugins/hellospecial/libexec/agent_hellospecialこれにより、必要な許可が割り当てられます。
ファイルの所有者(読み取り、書き込み、実行)
ファイルに関連付けられたグループ(読み取り、実行)
その他のユーザー(読み取り、実行)。
2.3. ルールを設定する
これで、最低限必要なルールが作成されました。
タイトルとカテゴリが定義されます。
設定用の GUI フォームは空のままにしておきます。
#!/usr/bin/env python3
# Shebang needed only for editors
from cmk.rulesets.v1.form_specs import Dictionary
from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic, Help, Title
def _formspec():
return Dictionary(
title=Title("Hello special!"),
help_text=Help("This rule is to demonstrate the minimum special agent."),
elements={}
)
rule_spec_hellospecial = SpecialAgent(
topic=Topic.GENERAL,
name="hellospecial",
title=Title("Hello special!"),
parameter_form=_formspec
)name は、プレフィックスagent_ が付いたスペシャルエージェントの名前を参照します。
この方法で設定されたエージェントは、Other integrations で利用可能になります。
ただし、elements={} が空であるため、その設定テンプレートにはエントリは含まれていません。
2.4. 呼び出し設定
この設定では、実行するスペシャルエージェントを、GUI から取得した設定およびデフォルト設定と組み合わせています。
これらの設定は、呼び出しパラメータになります。name は、再び、プレフィックスagent_ が付いたスペシャルエージェントの名前を指します。
#!/usr/bin/env python3
# Shebang needed only for editors
from cmk.server_side_calls.v1 import noop_parser, SpecialAgentConfig, SpecialAgentCommand
def _agent_arguments(params, host_config):
yield SpecialAgentCommand(command_arguments=[])
special_agent_hellospecial = SpecialAgentConfig(
name="hellospecial",
parameter_parser=noop_parser,
commands_function=_agent_arguments
)これにより、スペシャルエージェントの基本的な要件が満たされます。 もちろん、これらの情報にはいつでもさらに情報を追加することができます。
2.5. 最初のテスト
ファイルを作成したら、サイトの web サーバーを再起動します。
OMD[mysite]:~$ omd restart apacheここでSetup > Agents > Other integrations を開くと、Custom integrations セクションに新しいエントリHello special! が表示されます。
これが表示されない場合は、まず、すべてのファイルが指定の場所に保存されているかどうかを確認してください。 その他のエラーの原因を探したい場合は、商業版では、Checkmk 拡張パッケージの管理機能を使用して、簡単に確認することができます。 また、トラブルシューティングの章では、最も重要なエラーの原因と解決策をリストアップしています。
3. より複雑な例:完全な天気サービス
状態が決して変化しないチェックは、まあ、かなり予測可能です。 そこで、web または REST API をクエリし、応答として JSON または XML 構造のオブジェクトを受信する「本物の」スペシャルエージェントへの一歩を踏み出してみましょう。 これらは、SAN デバイスなどのネットワークデバイスの API にアクセスする場合にも、典型的なデータ形式です。
この演習では、特定のハードウェアを必要としないよう、Open-Meteo.com の無料 API を使用します。
目標は、緯度と経度で設定される完全なスペシャルエージェントを作成することです。
演習を簡単にするため、スペシャルエージェントはデータを直接解釈します。
たとえば、スペシャルエージェントは、気温が 5 ℃未満の場合は「WARN 」、0 ℃未満の場合は「CRIT 」の状態であると想定します。
チェックは「ometemp 」、スペシャルエージェントは「agent_ometemp 」などと略します。
Open-Meteo は、非営利目的での使用は無料で、リクエストが多すぎる場合は IP アドレスをブロックする権利を有します。 API の 1 分ごとのクエリは、まだ許容範囲内です。 ただし、サービスを過度に使用しないでください。また、テストが成功したら、このサービスを使用するスペシャルエージェントのルールを削除してください。 テスト用に作成したスペシャルエージェントの割り当てルールが、1 台のホストにのみ適用され、数十台や数百台には適用されないように、特に注意してください。 |
3.2. スペシャルエージェント
実際のデータを処理することになったので、プログラミング言語や前処理などについても検討する必要があります。
この演習では、公開 API をクエリして JSON データを受信します。
これは、シェルでcurl コマンドを使用して実行できます。
ただし、Checkmk には充実した Python が付属しているため、これを使用するのが理にかなっています。
次の決定は、データの処理に関するものです。 たとえば、JSON データをエージェント出力にそのまま渡すか、スペシャルエージェントでテーブル形式に変換することができます。 実際には、通常、作業環境に応じて決定します。 チェックの開発時に「分業」が考慮されていますか? 準備したデータは、関連するエージェントベースのチェックプラグインの開発を簡略化しますか? あるいは、それを不要にしますか? 後者の場合は、既存のチェックプラグインで解析できる形でデータを準備することができます。
この例では、JSON 応答を単に転送しています。
解析は、エージェントベースのチェックプラグインで行われます。
経度と緯度は、コマンドライン引数--latitude および--longitude を使用して入力します。
コマンドライン引数をより読みやすくするために、argparse ライブラリを使用しています。
Open-Meteo は URL にエンコードされた緯度と経度をサポートしているため、プレースホルダーを含む URL で十分です。
ブラウザで以下の URLに自分の緯度と経度を入力して試してみてください。
#!/usr/bin/env python3
# Shebang needed this time to find the interpreter!
import requests
import argparse
url = "https://api.open-meteo.com/v1/forecast?latitude={lat:.4f}&longitude={long:.4f}¤t=temperature_2m"
parser = argparse.ArgumentParser("agent_ometemp")
parser.add_argument(
"--latitude",
help="Specify the latitude in degrees (decimal notation).",
type=float,
default=0.0)
parser.add_argument(
"--longitude",
help="Specify the longitude in degrees (decimal notation).",
type=float,
default=0.0)
args = parser.parse_args()
# print(url.format(lat=args.latitude, long=args.longitude))
response = requests.get(url.format(lat=args.latitude, long=args.longitude))
print('<<<ometemp:sep(0)>>>')
print(response.json())注意:このスクリプトにはファイル拡張子は付けないでください。 |
ometemp エージェントセクションには、受信した JSON オブジェクトのみが含まれます。
コマンドラインで呼び出して、スペシャルエージェントをテストします。
OMD[mysite]:~$ ~/local/lib/python3/cmk_addons/plugins/ometemp/libexec/agent_ometemp --latitude 48.1305 --longitude 11.5953コマンドラインの出力は、次のようなものになるはずです。
<<<ometemp:sep(0)>>>
{'latitude': 48.14, 'longitude': 11.6, 'generationtime_ms': 0.01728534698486328, 'utc_offset_seconds': 0, 'timezone': 'GMT', 'timezone_abbreviation': 'GMT', 'elevation': 536.0, 'current_units': {'time': 'iso8601', 'interval': 'seconds', 'temperature_2m': '°C'}, 'current': {'time': '2025-01-09T12:45', 'interval': 900, 'temperature_2m': 9.8}}3.3. ルール設定
次のステップは、エージェントのルール設定です。 設定が完了すると、このルールはSetup > Agents > Other integrations の「Environmental 」グループに表示されます。
Setup > Agents > Other integrations のグループ分けの見出しは、動的に表示されます。 つまり、Environmental グループに分類された最初のスペシャルエージェントが利用可能になった時点で、そのグループが表示されます。 使用可能なグループ分けの概要(すべては網羅していません)は、この記事の最後にある「ファイルとディレクトリ」に記載されています。 |
#!/usr/bin/env python3
# Shebang needed only for editors
from cmk.rulesets.v1.form_specs import Dictionary, DictElement, Float
from cmk.rulesets.v1.rule_specs import SpecialAgent, Topic, Help, Title
def _formspec():
return Dictionary(
title=Title("Open-Meteo temperature"),
help_text=Help("This rule is used to showcase a special agent with configuration."),
elements={
"latitude": DictElement(
required=True,
parameter_form=Float(
title=Title("Latitude in degrees (decimal notation)"),
),
),
"longitude": DictElement(
required=True,
parameter_form=Float(
title=Title("Longitude in degrees (decimal notation)"),
),
),
}
)
rule_spec_ometemp = SpecialAgent(
topic=Topic.ENVIRONMENTAL,
name="ometemp",
title=Title("Open-Meteo temperature"),
parameter_form=_formspec
)これで、スペシャルエージェントも作成されました。 次に、サイトの web サーバーを再起動します。
OMD[mysite]:~$ omd restart apacheこれで、このスペシャルエージェントに基づいて、Add rule: Open-Meteo temperature でルールを作成できるようになりました。 ただし、このルールには現在、経度と緯度を入力するための 2 つのフィールドしか含まれていないため、まだあまり機能はありません。
拡張機能:パスワードの使用
多くの場合、データにアクセスするにはユーザー名とパスワード、または API キーが必要です。
パスワードを管理するために、formspec に個別のエレメントが用意されています。
これらを使用すると、パスワードをその場限りで定義したり、パスワードストアにアクセスしたりすることができます。
この例では、上記の スクリプトに以下の拡張を追加して、この目的で使用することができます。
最初の行に追加の変数を追加し、新しいプログラムセクションを挿入します。
from cmk.rulesets.v1.form_specs import Dictionary, DictElement, Float, String, Password, migrate_to_password
def _formspec():
return Dictionary(
# ...
elements={
# ...
"user": DictElement(
required=True,
parameter_form=String(
title=Title("User ID for login"),
prefill=DefaultValue("monitoring"),
),
),
"password": DictElement(
required=True,
parameter_form=Password(
title=Title("Password for this user"),
migrate=migrate_to_password,
),
),
}
)スクリプトを編集(この場合は拡張)した後は、サイトの web サーバーを再起動することを忘れないでください。
Open-Meteo の例ではパスワードは必要ないため、ここではパスワードの基本的な処理について説明しますが、API 呼び出しにはパスワードは含めていません。
3.4. 呼び出し構成
次に、新しいスペシャルエージェントを拡張して、経度と緯度を含むだけでなく、これらもプロセスするようにします。 最終的な目標は、現在の位置の気温値を取得することです。 したがって、以下の設定では、実行するスペシャルエージェントと、GUI(つまり、既存のルールセクション)から取得した設定、および標準の設定を組み合わせています。
通常指定できる経度と緯度の値は、params という名前の辞書に転送されます。
同時に、host_config オブジェクトには、ここで使用するホスト固有の設定がすべて含まれます。
たとえば、host_config.primary_ip_config.address により、プライマリ IP アドレスにアクセスでき、host_config.name にはホスト名が含まれます。
スペシャルエージェントに転送する場合、呼び出しはシェル経由で行われることに注意してください。
そのため、呼び出しパラメータのリストには文字列のみを含めることができます。
設定は、command_arguments リストに格納される呼び出しパラメータになります。
#!/usr/bin/env python3
# Shebang needed only for editors
from cmk.server_side_calls.v1 import noop_parser, SpecialAgentConfig, SpecialAgentCommand
def _agent_arguments(params, host_config):
args = [ "--latitude", str(params['latitude']), "--longitude", str(params['longitude']) ]
yield SpecialAgentCommand(command_arguments=args)
special_agent_ometemp = SpecialAgentConfig(
name="ometemp",
parameter_parser=noop_parser,
commands_function=_agent_arguments
)パスワードの使用
この例では、パスワードをコマンドライン引数としてプレーンテキストで渡しています。
追加のセキュリティ対策がない場合、これらのパスワードは、たとえばプロセステーブルから読み取られる可能性があります。
この脆弱性は、プログラムの起動時にプロセステーブルのエントリを変更することで最小限に抑えることができます。
Python では、たとえば、 |
パスワードはオブジェクトとして保存されるため、そのオブジェクトのunsafe() 関数を使用してアクセスします。
def _agent_arguments(params, host_config):
args = [
"--latitude", str(params['latitude']),
"--longitude", str(params['longitude']),
"--user", params['user'],
"--password", params['password'].unsafe()
]
yield SpecialAgentCommand(command_arguments=args)3.5. チェックプラグイン
完全を期すために、エージェントベースのチェックプラグインもここに掲載します。 これらのプラグインの開発については、エージェントベースのチェックプラグインに関する記事で詳しく説明しています。
この記事で紹介した例との違いは、REST API から返された JSON の転送方法です。
チェックプラグインは、エージェントセクションを常に 2 次元リスト(「リストのリスト」)の文字列として受け取ります。
まず、itertools を使用して、この2次元リストを1次元リストに変換します。
次に、この結果の配列をスペースで連結し、エージェントセクション全体を1つの文字列に変換します。
最後に、json.loads() で文字列をオブジェクトとして直接ロードできるように、単一引用符を二重引用符に置き換えます。
#!/usr/bin/env python3
from cmk.agent_based.v2 import AgentSection, CheckPlugin, Service, Result, State, Metric, check_levels
import itertools
import json
def parse_ometemp(string_table):
flatlist = list(itertools.chain.from_iterable(string_table))
parsed = json.loads(" ".join(flatlist).replace("'", "\""))
return parsed
def discover_ometemp(section):
yield Service()
def check_ometemp(section):
t = section['current']['temperature_2m']
if t < 0.0:
yield Result(state=State.CRIT, summary="Brrrrrr!")
elif t < 5.0:
yield Result(state=State.WARN, summary="It's getting cold...")
else:
yield Result(state=State.OK, summary="Nice here.")
return
agent_section_ometemp = AgentSection(
name = "ometemp",
parse_function = parse_ometemp,
)
check_plugin_ometemp = CheckPlugin(
name = "ometemp",
service_name = "Open Meteo temperature (2m)",
discovery_function = discover_ometemp,
check_function = check_ometemp,
)このチェックプラグインと組み合わせることで、この記事で説明したスペシャルエージェント、ルール設定、およびコール設定に関するスクリプトが、Checkmk で機能するサービスを提供するようになります。

4. トラブルシューティング
独自のスペシャルエージェントを開発する場合でも、エラーや問題が発生する可能性があります(残念ながら)。 エラーの原因を特定することは、エラーを修正することと同じくらい重要です。
4.1. ホストのサービス概要の警告
スペシャルエージェントがアクティブになった後に、Check_MK サービスのステータスが突然「WARN 」または「CRIT 」に変わった場合は、関連するSummary を確認してください。

Summary が新しいスペシャルエージェントとの接続を示している場合は、ホストのプロパティを確認してください。Checkmk agent / API integrations パラメータには、Configured API integrations and Checkmk agent を選択する必要があります。

4.2. ルールが消えた、または警告が表示される
Setup > Agents > Other integrations の Checkmk にスペシャルエージェントが表示されていない(または表示されなくなった)場合は、ルール設定(rulesets/special_agent.py )にエラーがある可能性があります。
商業版を使用している場合、ルールを編集したり、新しいルールを作成したりしようとすると、赤い警告が表示される場合があります。 クラッシュレポートページへのリンクをクリックしてください。 問題の原因がそこに表示されます。
次に、エラーの説明を表示してください。
OMD[mysite]:~$ tail -f var/log/web.log例えば、次のような出力が表示されます:
2024-12-17 10:15:51,742 [40] [cmk.web 2669118] Error converting to legacy rulespec 'ometemp' : name 'migrate_to_password' is not definedrulesets/special_agent.py ファイルの構文を確認してください。
必要なライブラリがすべて考慮されており、すべての変数がインポートされていることを確認してください。
すべてのインデントが正しいことを確認し、構文全体をチェックしてください。
ルールが Checkmk に表示されていたが、ルール設定の変更後に突然表示されなくなった場合は、既存のルールを適応させたり、新しいルールを作成したりするときにのみ、この問題に気付くことになります。 この問題は、既存のサービスの監視には影響しません。 |
4.3. 変更をアクティブにしたときのエラーメッセージ
呼び出し設定または実際のスペシャルエージェントに問題がある可能性があります。 これは、たとえば、Activate changes の実行中に黄色の警告が表示されることで確認できます。
エラーメッセージの情報に従って、server_side_calls/special_agent.py ファイルをチェックしてください。
それでもエラーが解決しない場合は、コマンドラインでエラーメッセージを再度検索してください。
OMD[mysite]:~$ cmk -d localhost --debug | lessしばらくお待ちいただくと、次のような出力(ここでは簡略化しています)が表示されます:
Traceback (most recent call last):
File "/omd/sites/devtest/bin/cmk", line 118, in <module>
exit_status = modes.call(mode_name, mode_args, opts, args)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/omd/sites/devtest/lib/python3/cmk/base/modes/__init__.py", line 70, in call
return handler(*handler_args)
^^^^^^^^^^^^^^^^^^^^^^
File "/omd/sites/devtest/lib/python3/cmk/base/modes/check_mk.py", line 562, in mode_dump_agent
for source in sources.make_sources(
^^^^^^^^^^^^^^^^^^^^^
File "/omd/sites/devtest/lib/python3/cmk/base/sources/_builder.py", line 407, in make_sources
return _Builder(
^^^^^^^^^
File "/omd/sites/devtest/lib/python3/cmk/base/sources/_builder.py", line 140, in __init__
self._initialize_agent_based()
File "/omd/sites/devtest/lib/python3/cmk/base/sources/_builder.py", line 198, in _initialize_agent_based
special_agents = tuple(make_special_agents())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/omd/sites/devtest/lib/python3/cmk/base/sources/_builder.py", line 187, in make_special_agents
for agent_data in special_agent.iter_special_agent_commands(agentname, params):
File "/omd/sites/devtest/lib/python3/cmk/base/server_side_calls/_special_agents.py", line 139, in iter_special_agent_commands
yield from self._iter_commands(special_agent, params)
File "/omd/sites/devtest/lib/python3/cmk/base/server_side_calls/_special_agents.py", line 115, in _iter_commands
for command in special_agent(processed.value, self.host_config):
File "/omd/sites/devtest/local/lib/python3/cmk_addons/plugins/ometemp/server_side_calls/special_agent.py", line 13, in _agent_arguments
"--user", params['bulla'],
~~~~~~^^^^^^^^^
KeyError: 'bulla'出力の最後の行が特に重要です。
ファイルserver_side_calls/special_agent.py で、存在しない辞書エレメントparams にアクセスしようとしています。
4.4. エージェントの出力の確認
エラーのもう 1 つの原因は、チェックプラグインがデータを出力していないことです。 これはコマンドラインでも確認できます。
OMD[mysite]:~$ cmk -d localhost --debug | less現在の測定データを含む文字列の代わりにエラーメッセージが表示された場合は、そのエラーメッセージに従って修正してください。
5. ファイルとディレクトリ
5.1. ディレクトリ
| ファイルパス | 説明 |
|---|---|
|
プラグインファイルを保存するためのベースディレクトリです。 |
|
実行可能ファイルの保存場所です。 |
|
ルールセットファイルの保存場所です。 |
|
コール構成ファイルの保存場所です。 |
|
エージェントベースのチェックプラグインの保存場所です。 |
|
標準のスペシャルエージェントはここにインストールされます。 |
|
変更したスペシャルエージェントの保存場所です。 |
|
検索パスにあり、ファイルパスを指定せずに直接実行できる、独自のプログラムまたはスクリプトの保存場所です。プログラムが |
5.2.Other integrationsで利用可能なグループ化
| 名前 | 説明 |
|---|---|
|
アプリケーションの監視 |
|
クラウドの監視 |
|
構成管理システムの監視 |
|
データベースの監視 |
|
他のカテゴリに該当しないすべての項目 |
|
環境および周辺監視 |
|
Linux オペレーティングシステムの監視 |
|
ネットワーク監視 |
|
ミドルウェアの監視 |
|
通知システムの監視 |
|
オペレーティングシステム全般の監視 |
|
周辺機器の監視 |
|
電源監視 |
|
サーバーハードウェアの監視 |
|
ストレージシステムの監視 |
|
外形監視 |
|
仮想化環境の監視 |
|
Windows オペレーティングシステムの監視 |
