この記事では、CheckmkでNEC製のルーター「UNIVERGE IX-R2530」を監視する方法を紹介します。
※本記事に掲載されている商品名・サービス名などは、各社の商標または登録商標です。
はじめに
CheckmkではSNMPを利用してネットワーク機器を監視できます。
標準MIBに対応したインターフェース情報などは、Checkmkの自動検出により簡単に監視を開始できます。一方で、ベンダ―固有の情報や、標準の監視項目として認識されない情報を監視したいケースもあります。
そこで今回は、NECのルーター「UNIVERGE IX-R2530」を例に、標準の監視項目に加えて、監視を拡張する方法を2パターン紹介します。
標準MIBで監視できる項目例
Checkmkに登録すると、図1の一覧の通り、インターフェイス情報、機器情報、起動時間が自動で取得できます。

サービス名をクリックすると、それぞれの詳細な監視結果を確認できます。
インターフェイス(Interface GigaEthernet2.0 など)
インターフェイス(ポート)ごとの情報をまとめて取得しています。ポートの状態、マックアドレス、IN/OUTの帯域幅、エラーパケット、などを確認しています。それぞれの値に対してグラフで確認することも可能で、しきい値を設定することで状態に応じてアラートメールを発報します。

インベントリ情報(Check_MK HW/SW Inventory)
インベントリのサービスでは、機器のハードウェア情報、またインターフェイスのそれぞれの名前、ステータス、使用(空き)状況、MACアドレスなどを一覧で確認することができます。

機器情報(SNMP Info)

起動時間(Uptime)

ベンダーMIBで監視できる項目例
NEC独自のMIB(各ベンダー固有のMIB情報)も監視することが可能です。
今回監視を追加したのは以下の5つです。監視の設定方法は次の章で紹介します。
CPU(CPU Util ZP10-SMI zp10sched)
CPU使用率(%)を監視しています。

ヒープメモリ(Heap Memory Util ZP10-SMI zp10heap)
ヒープメモリの使用率(%)を監視しています。

電圧(Voltage ZP10-SMI zp10system)
電圧を監視しています。単位はmVです。

温度(Temp ZP10-SMI zp10temperature)
温度を監視しています。単位は摂氏(℃)および華氏(℉)です。

ファン(Fan zp10fan rpm/index/status)
ファンを監視しています。rpmやステータス異常を監視しています。

ベンダーMIBの監視設定
独自のベンダーMIBを監視したい場合の作成方法を2種類紹介します。WebGUI上で1つずつOIDを指定し作成する方法と、Pythonスクリプトを作成しCheckmkに読み込ませる方法です。状況に合わせて使いわけることをお勧めします。
WebGUIからOIDを指定する方法
単一のOIDを指定する
先ほどの監視項目例のCPU(図6)を例にとって説明します。まずは対象のOIDを確認してください。
- CPU Util ZP10-SMI zp10sched
- zp10sched rt utl : 1.3.6.1.4.1.119.2.3.293.2.5.5.0 (単位%)
OIDが確認できたら、「Nagiosプラグイン統合」の機能を使用して、コマンドを記載していきます。Checkmkには予めいくつかのNagiosプラグインが既に組み込まれており、WebGUIで簡単に対象のプラグインを呼び出すことが可能です。今回は、OIDの値を指定して取得できる「check_snmp」というプラグインを使用します。
セットアップ>”サービス”>他のサービス から「Nagiosプラグイン統合」をクリックし、ルールを以下のとおり追加します。

- サービス名(必須):CPU Util ZP10-SMI zp10sched ※Checkmk画面の表示名になります
- コマンドライン:チェックを入れ以下のコマンドを入力
コマンドライン記載内容例
check_snmp -H $HOSTADDRESS$ -C public -P 2c -o 1.3.6.1.4.1.119.2.3.293.2.5.5.0 -w 80 -c 90 -u % -l "zp10sched rt utl" -D "; "
<引数の解説>
-H 対象ホスト("$HOSTADDRESS$"はcheckmkで使用できる変数です。実行時に監視対象のIPアドレスが入ります。)、
-C SNMPコミュニティ名、-P SNMPプロトコルのバージョン、
-o 取得するSNMP OID、-w Warning(警告)のしきい値、-c Critical(重大)のしきい値、
-u 取得値の単位、-l 監視項目の詳細表示名、-D 複数値を取得指定した場合の区切り文字(";")
今回はNECルーター独自の情報を監視するため、-o オプションでベンダー固有のOIDを直接指定しています。また、-w, -c でWarning/Criticalのしきい値を設定することで、取得した値に応じてCheckmk上で状態を判断できます。
条件欄で、対象のホストに一致するよう指定し、左上の保存ボタンクリックでルール作成は完了です。変更のアクティベートを実行すると、自動的に監視項目が検出され、監視が開始します。

赤枠のサービス名と概要欄に、設定したサービス名、設定したコマンドラインの結果が1種類出力されていることがわかります。
複数のOIDを一度に指定する
CPUの場合はOIDが1つですが、例えばヒープメモリ(図7)のように対象のOIDが複数ある場合も、同じようにコマンドラインに指定していきます。カンマ区切りで記載することが可能です。
ヒープメモリ関連のOID
- Heap Memory Util ZP10-SMI zp10heap
- zp10heap size : 1.3.6.1.4.1.119.2.3.293.2.6.1.0 (単位無し#)
- zp10heap util : 1.3.6.1.4.1.119.2.3.293.2.6.2.0 (単位%)
- zp10kernel heap size : 1.3.6.1.4.1.119.2.3.293.2.6.3.0 (単位無し#)
- zp10kernel heap util : 1.3.6.1.4.1.119.2.3.293.2.6.4.0 (単位%)
コマンドライン記載内容例
check_snmp -H $HOSTADDRESS$ -C public -P 2c -o 1.3.6.1.4.1.119.2.3.293.2.6.1.0,1.3.6.1.4.1.119.2.3.293.2.6.2.0,1.3.6.1.4.1.119.2.3.293.2.6.3.0,1.3.6.1.4.1.119.2.3.293.2.6.4.0 -u "#,%,#,% " -l "zp10heap size,zp10heap util,zp10kernel heap size,zp10kernel heap util" -D "; "
保存して、設定のアクティベートを行うと以下図13の通り監視結果が確認できます。赤枠のサービス名と概要欄には、設定したサービス名とコマンドラインの出力結果が4種類出力されていることがわかります。

WebGUIからOIDを指定する方法の解説は以上です。図8の電圧、図9の温度も同様に単一のOID指定から監視設定が可能です。
Pythonスクリプトでテーブル情報を取得する方法
監視したい情報によっては、1つのOIDから単一の値を取得するのではなく、複数のインデックスを持つテーブル形式で情報を持っている場合があります。このように複数のインデックスが存在する場合は、OIDの単一指定ではコマンドラインが複雑になってしまい設定できないため、Pythonスクリプトの使用をお勧めします。
スクリプトで実行する内容を簡単に説明すると
- SNMPで対象のテーブル情報を取得する
- 取得したデータからインデックスを読み取る
- それぞれのインデックスを個別のサービスとしてCheckmkに認識させる
という流れになります。ではこのPythonスクリプトを実際に作成して、Checkmkサービスとして認識させる方法を解説します。
Pythonスクリプトの作成・配置
OIDの確認
まずはOIDの確認です。今回は、以下のように、複数のインデックスを持つファンを監視します。
- Fan zp10fan : 1.3.6.1.4.1.119.2.3.293.2.3
- zp10fan index :1.3.6.1.4.1.119.2.3.293.2.3.1.1
- zp10fan status :1.3.6.1.4.1.119.2.3.293.2.3.1.2
- zp10fan rpm :1.3.6.1.4.1.119.2.3.293.2.3.1.3
テーブルOIDは「Fan zp10fan : 1.3.6.1.4.1.119.2.3.293.2.3」です。「zp10fan index」からファンのインデックスを取得し、取得したインデックスの値を、status/rpmのOID末尾に追加することで、インデックスごとのファン情報を取得できます。
<ファンで取得できる値イメージ>
1.3.6.1.4.1.119.2.3.293.2.3.1.1.1 = INTEGER: 1 indexの値
1.3.6.1.4.1.119.2.3.293.2.3.1.2.1 = INTEGER: 1 statusの値
1.3.6.1.4.1.119.2.3.293.2.3.1.3.1 = INTEGER: 3994 rpmの値
1.3.6.1.4.1.119.2.3.293.2.3.1.1.2 = INTEGER: 2 indexの値
1.3.6.1.4.1.119.2.3.293.2.3.1.2.2 = INTEGER: 1 statusの値
1.3.6.1.4.1.119.2.3.293.2.3.1.3.2 = INTEGER: 3857 rpmの値
…
例えばファンが3台ある場合は、Index = 1~3となり、それぞれのIndexに応じてOIDの末尾も変わります。そして、ファンが存在する台数分の監視サービス(項目)が作成されます。
プラグインの配置
Linuxコンソールでサイトユーザーに変更してから(omd su [サイト名])、作業を実行してください。
格納ディレクトリは「~/local/lib/python3/cmk_addons/plugins/[任意の機器種別名]/agent_based」です。先に格納ディレクトリを作成し、Pythonスクリプトを作成します。
# 格納ディレクトリの作成
mkdir -p ~/local/lib/python3/cmk_addons/plugins/zp10fan/agent_based
# 格納先へ移動
cd ~/local/lib/python3/cmk_addons/plugins/zp10fan/agent_based
# ファイルを作成
vim zp10fan.py
作成したファイル「zp10fan.py」に以下をコピー&貼り付けして保存
#!/usr/bin/env python3
# CheckmkのエージェントベースAPIから必要な機能を読み込み
from cmk.agent_based.v2 import (
CheckPlugin,
DiscoveryResult,
Metric,
Result,
Service,
SimpleSNMPSection,
SNMPTree,
State,
StringTable,
exists,
)
# SNMPで取得したテーブル情報を、Checkmkで扱いやすい形式に変換
def parse_zp10fan(string_table: StringTable):
fans = {}
# 取得した各行から、Index・Status・RPMを取り出し
for row in string_table:
if len(row) != 3:
continue
index, status, rpm = row
# Indexをキーとして、ファンごとの情報を保存
fans[index] = {
"status": status,
"rpm": rpm,
}
return fans
# SNMPから「zp10fan」の情報を取得する
snmp_section_zp10fan = SimpleSNMPSection(
name="zp10fan",
detect=exists(
# 指定したOIDが存在する場合、このSNMPセクションを使用
".1.3.6.1.4.1.119.2.3.293.2.3.1.1.1"
),
# ファン情報のテーブルを取得
# 1:Index、2:Status、3:RPM
fetch=SNMPTree(
base=".1.3.6.1.4.1.119.2.3.293.2.3.1",
oids=[
"1",
"2",
"3",
],
),
# 取得したSNMPデータをparse_zp10fan()で処理し
parse_function=parse_zp10fan,
)
# SNMPから取得したIndexごとに、Checkmkのサービスを作成
def discover_zp10fan(section) -> DiscoveryResult:
for index in section:
yield Service(item=index)
#各ファン状態をチェック
def check_zp10fan(item, section):
if item not in section:
yield Result(
state=State.UNKNOWN,
summary="Fan data not found",
)
return
# 対象のファン情報を取得
fan = section[item]
status = fan["status"]
rpm = fan["rpm"]
# RPMを数値に変換します
try:
rpm_value = float(rpm)
except ValueError:
# 数値に変換できない場合はUNKNOWN
yield Result(
state=State.UNKNOWN,
summary=f"Invalid RPM value: {rpm}",
)
return
# Statusの値に応じてCheckmk上の状態を判定
if status == "1":
state = State.OK
status_text = "normal"
elif status == "2":
state = State.CRIT
status_text = "failure"
else:
state = State.UNKNOWN
status_text = f"unknown ({status})"
# Checkmkのサービス状態と表示内容を設定
yield Result(
state=state,
summary=f"Status={status_text}, RPM={rpm}",
)
# RPMをメトリックとして登録し、グラフ表示できるように
yield Metric(
name="fan_rpm",
value=rpm_value,
)
# Checkmkに監視サービスとして登録
check_plugin_zp10fan = CheckPlugin(
name="zp10fan",
sections=["zp10fan"],
# Indexごとに「Fan zp10fan: status」のサービスを作成
service_name="Fan zp10fan%s: status",
# サービス検出に使用する関数
discovery_function=discover_zp10fan,
# サービスの状態判定に使用する関数
check_function=check_zp10fan,
)
保存したら、以下コマンドを実行し、コンパイルエラーが出ないことを確認します。同時にコアの再起動がかかります。
cmk -R

図14は実行例です。出力にOKと表示されれば完了です。エラーメッセージが出力された場合は、解消して再度cmk -Rを実行してください。
WebGUIでサービス検知
WebGUIで、セットアップ>”ホスト”>ホスト から対象の機器のサービスディスカバリー(検出)を行います。
# 指定したOIDが存在する場合、このSNMPセクションを使用
".1.3.6.1.4.1.119.2.3.293.2.3.1.1.1"
スクリプト記載の上記の部分の通り、「このOIDで機器へ問合せて値が取得できる場合はサービスを作成する」という作りになっているため、今後同じベンダーMIBを使用している機器を登録した場合も、このOIDが取得できる機器であれば初回のサービス取得で確認し、自動でこのファンを監視するサービスが追加されるようになります。
自動で始まらない場合は、図15赤枠の再スキャンのボタンを押してください。

再スキャンが完了すると、正常にプラグインが読み込まれていれば、「未決定のサービス」としてファンが検出されます。(図16)

今回はIndexが1つだったため、稼働中のファン1つ分のサービス検出となりますが、ファンが3台存在した場合は3種類のサービスが作成されます。左上の「すべて受け入れる」をクリックすると、監視対象に追加されます。
図17は追加を受け入れた画面です。

図17赤枠の左側、「変更」というメニューに黄色い印が付いていると思いますので、クリックして、変更のアクティベートが完了すると、監視が開始されます。
ファン監視画面例

まとめ・お問合せ
今回は、NECルーター「UNIVERGE IX-R2530」の監視を例に、ベンダーMIB監視を拡張する方法をご紹介しました。Checkmkでは、標準MIBを利用したSNMP監視に加えて、ベンダー固有のOIDを指定することで、より細かな情報を監視することができます。
さらにPythonスクリプトを利用すれば、OIDを直接指定するだけでは難しいテーブル形式の情報も取得でき、取得した情報をCheckmkのサービスとして登録することで、普段の監視画面からまとめて状態を確認できます。「標準の監視では少し足りない」「こんな値を監視したい」という要望がある場合にも、Checkmkなら監視方法を工夫して拡張できます!
ぜひ、監視したい情報の出力にあわせてCheckmkの監視をカスタマイズしてみてください。


