はじめに
ServiceNow のインスタンス性能(JVM メモリ、セマフォ、応答時間)を確認する定番といえば Performance ホームページ(stats.do のグラフ群) でした。
しかしダッシュボードは Platform Analytics(PA)への移行が進んでおり、従来の Performance ダッシュボードは今後使えなくなっていきます。
「じゃあ AI に聞けるようにすればいいのでは?」ということで、自作の ServiceNow MCP サーバーに性能診断ツールを2本追加しました。
あなた「いまインスタンスのメモリとセマフォ、大丈夫?」
Claude「ヒープは最大 1,820MB 中 497MB 使用(空き 35%)で余裕があります。
セマフォは Default プールが 16 本中 1 本使用、キュー滞留 0、
rejected 0 なので詰まりはありません。ノードは online/primary です」
あなた「昨日の応答時間の推移をグラフにして」
Claude「過去24時間を1時間ごとに集計しました。07:01 UTC に平均応答が
9.8 秒まで跳ねています。同じ時間帯に SQL 時間も 3 秒超えなので
DB 起因、おそらく夜間ジョブと重なっています」(グラフ付き)
この記事では、どうやって実現したかと、調査の過程で分かった ServiceNow の性能データの裏側(xmlstats.do、JRobin、Aggregate API)を紹介します。
- リポジトリ: https://github.com/tedorigawa001/ServiceNow-MCP
- npm: https://www.npmjs.com/package/@tedorigawa001/servicenow-mcp
ServiceNow の性能データはどこにあるのか
調査して分かったデータソースは3つです。
1. /xmlstats.do — 現在値の宝庫(REST の OAuth トークンがそのまま使える)
Performance ホームページの「いまの状態」は /xmlstats.do という UI プロセッサから XML で取れます。意外だったのは、REST API 用の OAuth Bearer トークンがそのまま通ることです。
curl -H "Authorization: Bearer $TOKEN" \
"https://<instance>.service-now.com/xmlstats.do?include=memory,semaphores"
返ってくる XML(抜粋):
<xmlstats created="..." includes="memory,semaphores" version="2">
<system.memory.max>1820.0</system.memory.max>
<system.memory.in.use>697.0</system.memory.in.use>
<system.memory.pct.free>19.0</system.memory.pct.free>
<semaphores available="15" maximum_concurrency="16" name="Default"
queue_depth="0" max_queue_depth="5" rejected_executions="0">
<semaphore age="25" processor="Default-thread-35">... /xmlstats.do</semaphore>
</semaphores>
...
</xmlstats>
セマフォプールごとの同時実行数・キュー深度・rejected 数が全部入っています。
「セマフォ詰まってない?」の答えはここにあります。
include には transactions や dbpool なども指定できます。
2. JRobin(RRD)— 履歴グラフの本体。ただし API からは取れない
Performance ホームページのグラフの履歴データは JRobin という Java 版 RRD(ラウンドロビンデータベース)に入っています。
テーブルも存在します(jrobin_graph、jrobin_datasource、jrobin_shard など)。
……が、REST の Table API で叩くと ACL でフィールド値がほぼすべて隠されます(sys_id しか返ってこない)。実データは jrobin_shard のバイナリ断片なので、仮に読めてもデコードが必要です。ここは素直に諦めました。
結論: メモリ・セマフォの「過去履歴」は API からは取得できないと思われます。 どうしても欲しければ現在値を定期取得して自前で蓄積するしかありません。
3. syslog_transaction + Aggregate API — 応答時間の履歴はこれで作れる
一方、トランザクション性能の履歴は作れます。全トランザクションが記録される syslog_transaction テーブルを Aggregate API(/api/now/stats/)で時間バケットごとに集計すれば、ダッシュボードの Response Time / Transactions グラフ相当が得られます。
GET /api/now/stats/syslog_transaction
?sysparm_query=sys_created_on>=2026-07-04 03:00:00^sys_created_on<2026-07-04 04:00:00
&sysparm_count=true
&sysparm_avg_fields=response_time,sql_time,business_rule_time
&sysparm_max_fields=response_time
小ネタ: 日時リテラルは UTC で比較される
エンコードクエリの日時リテラルがユーザータイムゾーンで解釈されるのか UTC なのかは情報が錯綜しがちです。gs.minutesAgoStart(60) と「UTC の1時間前リテラル」で件数を突き合わせたところ、208 件 vs 206 件(数秒のずれ分のみ)でほぼ一致。Table/Aggregate API の日時リテラルは UTC 解釈でした。バケット境界は安心して UTC で組み立てられます。
作ったツール
get_instance_diagnostics(現在値)
/xmlstats.do の XML を正規表現でパースして構造化 JSON にし、sys_cluster_state のノード状態も添えて返します。
{
"memory_mb": { "system.memory.max": 1820, "system.memory.in.use": 497, "system.memory.pct.free": 35 },
"semaphores": [
{ "name": "Default", "max_concurrency": 16, "in_use": 1, "queue_depth": 0, "rejected_executions": 0 },
{ "name": "API_INT", "max_concurrency": 4, "in_use": 0, ... }
],
"cluster_nodes": [ { "system_id": "app...:dev...", "status": "online", "participation": "primary" } ]
}
get_performance_history(履歴)
指定期間(最大7日)を最大48バケットに分割し、バケットごとに Aggregate API を叩いて時系列を返します。48 リクエストを直列で投げると遅いので、同時実行 6 に絞って並列化しています。
{
"bucket_minutes": 60,
"series": [
{ "start_utc": "2026-07-04 07:01:25", "count": 312,
"avg_response_ms": 9801, "max_response_ms": 692945, "avg_sql_ms": 3084 },
...
]
}
query 引数で urlLIKE/api/(REST だけ)や sys_created_by=admin のような絞り込みもできます。
グラフ化は誰がやるのか
MCP サーバーはデータを返すだけです。
グラフ化は AI クライアント側(Claude Desktop / Claude Code のアーティファクトやチャート描画)が担当します。
実際に PDI の過去24時間データを取らせたところ、07:01 UTC の平均応答 9.8 秒のスパイクと、同時間帯の SQL 時間の跳ね(3 秒超)がひと目で分かるグラフが返ってきました。
「このスパイクの原因は?」と続けて聞けば、AI が同時間帯の syslog_transaction を深掘りしてくれます。ダッシュボードとの一番の違いはここで、グラフを見た後の「なぜ?」までシームレスに続けられることです。
利用例
まとめ
| 知りたいこと | データソース | 取れる? |
|---|---|---|
| メモリ・セマフォの現在値 | /xmlstats.do(OAuth Bearer 可) | ○ |
| メモリ・セマフォの履歴 | JRobin(jrobin_shard) | ×(ACL で不可視) |
| 応答時間・スループットの履歴 | syslog_transaction + Aggregate API | ○ |
Performance ダッシュボードがなくなっても、データ自体は今も API 越しに生きています。MCP で AI につないでおけば、「見る」だけでなく「聞ける」性能監視になります。

