本内容はInterop Tokyo 2025-zabbixブースにて展示したpleasanterの内容を含みます。
はじめに
みなさんこんにちは。Pleasanter使ってますか?
Pleasanterはノーコードでだれでも業務アプリを作成することが可能ですが、少しでもコードを書くことができればさらに世界が広がります。
例えば、サーバー監視ツールからのアラートをAPIでPleasanterに起票し、Pleasanter上で管理する...など。
会社ではシステム管理者(以降情シス)と現場のユーザが同じ環境で密に連絡を取れるのが理想ですが、お互い使っているツールが違うなどの理由により、リアルタイムに連携できない、会話に齟齬が生まれるといったことが往々にしてあります。
そんな時、上記のようにサーバー監視はあくまで監視ツールを使いつつ、実際の管理運用はPleasanterで共通して行うようにすれば情シスとユーザの認識を統一しやすく今まで以上に連携しやすくなると思いませんか?
今回はPleasanterとZabbixという2つのOSSを使ってサーバーの監視から運用管理、棚卸等の業務までを一元管理する方法について解説していきたいと思います。
やること
PleasanterとZabbixはどちらも通知機能を有していますが、今回は運用面ではPleasanterを利用するため、Zabbixからの通知は行いません。
準備
Pleasanter側
必要に応じて以下のテーブルを作成します。
- アラートを監視するテーブル
ZabbixからAPIで作成されるレコードを表示するためのテーブルです。
ステータス(状況項目)は100が停止、200が復旧です。
↑後で使います。
正常時はレコードの作成や更新は行いませんが、アラート発報時や復旧時などにレコードが作成されます。
- 障害対応の報告や管理を行うテーブル
上記アラート監視テーブルにレコードが作成されたタイミングで、アラートに対する障害対応用のテーブルを作成します。
後述しますが、各項目にはZabbixから渡された情報が格納されています。
if(model.Status == 100){
let data = {
Keys: ["ClassA"],
Title: `${model.DateA}に発生した障害対応`,
Status: 200,
Body: model.DescriptionA,
ClassHash: {
ClassA: model.ResultId,
ClassB: model.ClassC,
ClassC: model.ClassD,
}
};
items.Upsert(381, JSON.stringify(data));//ID直指定ではなくgetClosestSiteを使用する方法も可
}
- 資産情報テーブル
本筋とは関係ないテーブルなので作成は任意ですが、監視しているサーバーの情報を管理するテーブルです。
上記アラートや障害対応のテーブルとリンクしておくことで棚卸時の管理がよりスマートになります。
Zabbix側
Zabbixではメディアタイプwebhookを利用してPleasanterとAPI連携を行います。
今回、Pleasanterと連携するためのWebhookを作成しました。
以下パラメータはメッセージ出力やAPI連携に使用します。必要に応じて編集してください。
| パラメーター | 値 |
|---|---|
| ALERT_SEVERITY | {EVENT.SERVERITY} |
| BaseUrl | PleasanterのBaseURLを記載1 |
| EVENT_DATE | {EVENT.DATE} |
| EVENT_RECIVERY_STATUS | {EVENT.RECIVERY.STATUS} |
| EVENT_STATUS | {EVENT.STATUS} |
| EVENT_TIME | {EVENT.TIME} |
| HOST | {HOST.NAME} |
| HOST_IP | {HOST.IP} |
| ID | {EVENT.ID} |
| MESSAGE | {ALERT.MESSAGE} |
| OPDATA | {EVENT.OPDATA} |
| RECOVERY_DATE | {RECOVERY.DATE} |
| RECOVERY_NAME | {RECOVERY.NAME} |
| RECOVERY_TIME | {RECOVERY.TIME} |
| SUBJECT | {ALERT.SUBJECT} |
| To | {ALERT.SENDTO} |
| TOKEN | PleasanterのAPIキーを記載 |
| TRIGGER_URL | {TRIGGER.URL} |
| URL | api連携するURLを記載2 |
パラメータの設定が終わったら、次にスクリプトを記述していきます。
以下のスクリプトは事前に準備したPleasanterに対してAPIでレコードを作成し返ってきたレスポンスからタグ付けを行っています。
こちらも必要に応じて修正してください。
■タイムアウト
30s
■メニュー項目名
Pleasanter:RecordId{EVENT.TAGS.__zbx_pleasanter_recordId}
■メニュー項目URL
{EVENT.TAGS/__zbx_pleasanter_recordLink}
■スクリプト
try {
var params = JSON.parse(value);
// Validate required parameters
if (!params.URL || !params.TOKEN) {
throw 'Missing required parameters URL or TOKEN';
}
// Create the HTTP request
var req = new HttpRequest();
req.addHeader('Authorization', 'Bearer ' + params.TOKEN);
req.addHeader('Content-Type: application/json');
if(params.EVENT_RECOVERY_STATUS === "RESOLVED"){
// Create the data to send to Pleasanter
const data = {
"ApiVersion": 1.1,
"ApiKey": params.TOKEN,
"Title": params.SUBJECT,
"Status": "200",
"ClassHash": {
"ClassA": "200",
"ClassB": params.ALERT_SEVERITY,
"ClassC": params.HOST,
"ClassD": params.HOST_IP
},
"DateHash": {
"DateA": params.RECOVERY_TIME
},
"DescriptionHash": {
"DescriptionA": params.MESSAGE
}
}
} else if(params.EVENT_STATUS === "PROBLEM") {
// Create the data to send to Pleasanter
const data = {
"ApiVersion": 1.1,
"ApiKey": params.TOKEN,
"Title": params.SUBJECT,
"Status": "100",
"ClassHash": {
"ClassA": "100",
"ClassB": params.ALERT_SEVERITY,
"ClassC": params.HOST,
"ClassD": params.HOST_IP
},
"DateHash": {
"DateA": params.EVENT_TIME
},
"DescriptionHash": {
"DescriptionA": params.MESSAGE
}
}
}
// Send the HTTP POST request
var rawResponse = req.post(params.URL, JSON.stringify(data));
if (req.getStatus() != 200) {
throw 'Failed to send data to Pleasanter: ' + req.getStatus();
}
var response = JSON.parse(rawResponse);
result = {tags:{}};
result.tags.__zbx_pleasanter_recordId = response.Id;
result.tags.__zbx_pleasanter_recordLink = params.BaseUrl + (params.BaseUrl.endsWith("/") ? "" : "/") + response.Id;
return JSON.stringify(result);
} catch (error) {
Zabbix.log(4, '[ Pleasanter ] Error: ' + error);
throw 'Pleasanter Webhook failed: ' + error;
}
実際にうごかしてみる
実際には各環境の細かい閾値などに応じて複数のアラートを設定するような運用を想定していますが、今回はデモなのでサーバの死活監視を行います。
Zabbixのシンプルチェックを活用します。
1. 監視対象のサーバーを停止
2. Zabbix側のダッシュボードで監視対象(今回の場合monitor)に障害が発生
3. ZabbixからPleasanterへAPIで障害レコードを作成

障害レコードの中身は以下のような内容です
必要に応じて設定して下さい。

同時に障害対応用のレコードや、資産情報ともレコードがリンクされます。

4. 監視対象のサーバーを再起動
再起動後は以下のようにZabbix側では「解決済み」表示となります。

5. Pleasanter側に復旧レコードを作成
Pleasanterのアラートテーブルにも同様に復旧レコードが作成されます。

6. 棚卸
棚卸時は以下のように資産情報テーブルから該当のサーバを選択するとサーバーに対して発生したアラートを一覧として確認することが可能です。


応用のために
今回はデモとして簡単なシンプルチェックを行いましたが、例えばCPU使用率やメモリ使用率を特定の閾値を設けてアラート設定をすることで資産情報にはより詳細な原因やアラート情報が蓄積されていきます。
これをもって棚卸の際に「このサーバーはメモリのアラートが頻発しているから増設しよう」といった判断が容易に可能となります。
また、Pleasanterは自動で画面を更新する機能はなく手動でリフレッシュする必要がありますが、
アラート確認用テーブルをダッシュボードのように使う場合不便です。
その際は、以下のスクリプトを設定することで10秒おきに画面が自動更新されるためよりダッシュボード的な使い方をすることが可能になります。
$p.events.on_grid_load = function () {
// 10秒後に画面を再読み込み
setTimeout(function () {
location.reload();
}, 10000);
};
さいごに
今回はZabbixとPleasanterを連携させ、アラートの監視から棚卸までをPleasanterで行うことで、意思疎通を改善しスムーズに障害対応までの判断や増設などの判断ができるようなシステムを目指しました。
肝はAPIで連携するWebhookであり、Pleasanter側のテーブルや設定は皆様の自由です。
必要に応じて、すでにあるシステムと連携させたり、新たにシステム網を構築するなど自由に設計が可能です。
最初に書きましが、このようなシステムは少しコードを書くことができれば(マニュアルにサンプルコードもありますし、chatGPTに書いてもらうこともできるはずなので読めるだけでもいいです。)Pleasanterの世界は大きく広がります。
ぜひ、積極的にシステム構築をお試しください。


