はじめに
複数のクライアントサイトをエックスサーバーで運用していると、「どのサーバーのディスクがどれくらい使われているか」を把握するのが意外と手間になる。管理画面を開いてサーバーごとに確認し、スプレッドシートに転記して…というのを毎回やるのは非効率だ。
エックスサーバーには REST API(XServer API)が用意されており、ディスク使用量などのサーバー情報をプログラムから取得できる。これを使って、1台の管理サーバーから複数のエックスサーバーアカウントを集中監視し、閾値超過をメールで通知する仕組みを PHP で構築した。
この記事ではその設計と実装を紹介する。
XServer API の概要
エックスサーバーのサーバー API(XServer API)のベース URL は https://api.xserver.ne.jp/v1 で、ドメイン・メール・DB・SSL・cron などをプログラムから操作できる。
認証
すべてのリクエストで Bearer トークンを付与する。
curl -H "Authorization: Bearer xs_xxxxxxxxxx" \
"https://api.xserver.ne.jp/v1/me"
正常に認証できると、以下のようなレスポンスが返る。
{
"service_type": "server",
"expires_at": null,
"servername": "your-server.xsrv.jp",
"permission_type": "full"
}
ディスク使用量の取得
curl -H "Authorization: Bearer xs_xxxxxxxxxx" \
"https://api.xserver.ne.jp/v1/server/your-server.xsrv.jp/server-info/usage"
{
"disk": {
"quota_gb": 500,
"used_gb": 239.43,
"file_limit": 0,
"file_count": 10886589
},
"counts": {
"domains": 10,
"subdomains": 87,
"mail_accounts": 3,
"mysql_databases": 102
}
}
ディスク容量・使用量・ファイル数のほか、ドメイン数や DB 数まで一度に取得できる。
アーキテクチャ:集中管理方式
各サーバーにスクリプトを置く方式だと、サーバーが増えるたびに設置・更新が必要になる。今回は1台の管理サーバーが全監視対象の API を呼び出す集中管理方式を採用した。
管理サーバー(monitor.xsrv.jp)
│
├─ cron(毎時)─── disk_check.php ─── server-a.xsrv.jp の API
│ ─── server-b.xsrv.jp の API
│ ─── server-c.xsrv.jp の API
│
└─ cron(毎日)─── disk_report.php ── 同上
メリットは次の通り。
- スクリプトの設置・更新が1か所で済む
- 監視対象サーバーの追加は設定ファイルへの追記だけ
- ログ(CSV)も一元管理できる
実装
ファイル構成
xserver_monitor/
├── .env # 認証情報(Git 管理外)
├── .env.example # .env のテンプレート
├── config.php # 監視対象・閾値・通知設定
├── disk_check.php # 毎時実行:閾値チェック
├── disk_report.php # 日次実行:サマリーレポート
├── deploy.sh # デプロイスクリプト
└── lib/
├── Env.php # .env ローダー
├── XServerApi.php # API クライアント
├── CsvLogger.php # CSV 記録
└── Notifier.php # 通知(メール / Chatwork / Slack / Discord)
XServerApi — API クライアント
class XServerApi
{
private const BASE_URL = 'https://api.xserver.ne.jp/v1';
public function __construct(
private string $servername,
private string $apiKey
) {}
public function getUsage(): array
{
return $this->get("/server/{$this->servername}/server-info/usage");
}
private function get(string $path): array
{
$ch = curl_init(self::BASE_URL . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer {$this->apiKey}",
'Accept: application/json',
],
]);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
if ($httpCode !== 200 || $data === null) {
throw new RuntimeException("API error [{$this->servername}] HTTP {$httpCode}");
}
return $data;
}
}
CsvLogger — 時系列ログの記録
取得したデータをサーバーごとの CSV ファイルへ追記する。
datetime,quota_gb,used_gb,free_gb,usage_pct,file_count,domains,subdomains,mysql_databases
2024-01-15 10:00:00,500,239.43,260.57,47.9,10886589,10,87,102
2024-01-15 11:00:00,500,239.51,260.49,48.0,10886750,10,87,102
ファイルが存在しない場合はヘッダー行を自動で書き込む。これにより、CSV をそのまま Excel や BI ツールに読み込んで推移を可視化できる。
Notifier — 拡張可能な通知クラス
メール・Chatwork・Slack・Discord に対応し、config.php の enabled フラグで有効化する。
class Notifier
{
public function send(string $subject, string $body): void
{
if (!empty($this->config['email']['enabled'])) $this->sendEmail($subject, $body);
if (!empty($this->config['chatwork']['enabled'])) $this->sendChatwork($subject, $body);
if (!empty($this->config['slack']['enabled'])) $this->sendSlack($subject, $body);
if (!empty($this->config['discord']['enabled'])) $this->sendDiscord($subject, $body);
}
}
各チャネルは send() を呼ぶだけで一括送信される。新しいチャネルを追加するときも sendXxx() メソッドを追加して send() に組み込むだけでよい。
disk_check.php — 毎時チェック
閾値を超えたときだけ通知する。正常時はサイレント。
foreach ($config['servers'] as $server) {
$api = new XServerApi($server['servername'], $server['api_key']);
$usage = $api->getUsage();
$row = $logger->append($server['servername'], $usage);
if ((float)$row['usage_pct'] >= $server['thresholds']['disk_usage_pct']) {
$alerts[] = sprintf(
'[%s] 使用率 %s%% (%sGB / %sGB) ※閾値 %d%% 超過',
$server['label'], $row['usage_pct'],
$row['used_gb'], $row['quota_gb'],
$server['thresholds']['disk_usage_pct']
);
}
}
if (!empty($alerts)) {
$notifier->send('[XServer監視] アラート', implode("\n", $alerts));
}
認証情報の管理:.env パターン
API キーを config.php にハードコードするのは、Git 管理を始めると危険になる。.env ファイルに切り出して Git の管理外に置く方法を採用した。
.env ファイル
XSERVER_API_KEY_MONITOR=xs_xxxxxxxxxx
XSERVER_API_KEY_SERVER_A=xs_xxxxxxxxxx
XSERVER_API_KEY_SERVER_B=xs_xxxxxxxxxx
NOTIFY_SLACK_WEBHOOK_URL=
NOTIFY_DISCORD_WEBHOOK_URL=
.gitignore で除外する。
.env
data/*.csv
Composer 不要の .env ローダー
共有ホスティングでは Composer が使えない場合もある。シンプルな自前実装で対応した。
class Env
{
public static function load(string $path): void
{
foreach (file($path, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES) as $line) {
$line = trim($line);
if ($line === '' || $line[0] === '#' || !str_contains($line, '=')) continue;
[$key, $value] = explode('=', $line, 2);
$value = trim($value, " \"'");
if (getenv(trim($key)) === false) {
putenv(trim($key) . '=' . $value);
}
}
}
public static function require(string $key): string
{
$v = getenv($key);
if ($v === false || $v === '') {
throw new RuntimeException(".env の必須項目が未設定: {$key}");
}
return $v;
}
}
ポイントは2点。
- 既存の環境変数は上書きしない — サーバーの環境変数で上書きできる
require()で必須チェック — APIキーが未設定なら起動時に即エラーになる
config.php 側は以下のように使う。
Env::load(__DIR__ . '/.env');
return [
'servers' => [
[
'servername' => 'your-server.xsrv.jp',
'api_key' => Env::require('XSERVER_API_KEY_MONITOR'),
// ...
],
],
];
デプロイ:rsync で差分転送
サーバーへの配置は rsync を使う deploy.sh で行う。
rsync -avz --delete \
--exclude='.env' \
--exclude='.env.example' \
--exclude='data/' \
--exclude='deploy.sh' \
--exclude='SPEC.md' \
-e ssh \
./ monitor-server:~/shell/xserver_monitor/
--delete でサーバー上の不要ファイルを削除しつつ、.env と data/ はサーバー上のものを保持する。
--dry-run オプションで事前確認もできる。
./deploy.sh --dry-run # 転送内容を確認するだけ
./deploy.sh # 本番デプロイ
デプロイ後はリモートで PHP の構文チェックを自動実行し、問題があればすぐに気づける。
ssh monitor-server "php -l ~/shell/xserver_monitor/disk_check.php"
cron の設定:XServer API 経由で自動化
エックスサーバーの cron 設定も XServer API から行える。管理画面を開かずにスクリプトから登録できるのは便利だ。
curl -X POST \
-H "Authorization: Bearer xs_xxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"minute": "0",
"hour": "*",
"day": "*",
"month": "*",
"weekday": "*",
"command": "/opt/php-8.3/bin/php $HOME/shell/xserver_monitor/disk_check.php",
"comment": "XServerディスク監視:閾値チェック(毎時)"
}' \
"https://api.xserver.ne.jp/v1/server/your-server.xsrv.jp/cron"
登録後は cron ID が返り、PUT / DELETE で変更・削除も API から操作できる。
ドキュメントの整備
運用ツールは「動けばいい」で終わりにしがちだが、後から読み返すとき・引き継ぐときのためにドキュメントを整えた。
クラス仕様・CSV フォーマット・通知メッセージの例・手順書など、実装の根拠となる情報を SPEC.md にまとめた。コードを読まなくても全体像が把握できることを目指した。主な記載内容は以下の通り。
- 各クラスのメソッド一覧と引数・戻り値
- CSV カラム定義
- 通知メッセージのサンプル(件名・本文)
- サーバー追加・通知チャネル追加の手順
- 初回セットアップ手順
まとめ
今回構築したシステムの要点を整理する。
| 項目 | 採用した方法 |
|---|---|
| 監視方式 | 管理サーバーから全対象の XServer API を呼ぶ集中管理 |
| 認証情報 | .env に分離・Git 管理外 |
| ログ保存 | サーバーごとの CSV(将来 JSON 変換も想定) |
| 通知 | メール / Chatwork / Slack / Discord(有効化切り替え式) |
| デプロイ | rsync で差分転送・ドキュメントは除外 |
| cron 設定 | XServer API 経由 |
| ドキュメント | SPEC.md に仕様・手順を集約 |
XServer API は cron・メール・ドメイン・DNS など広い範囲をカバーしており、今回のディスク監視以外にも応用できる。SSL 証明書の期限監視やドメインの管理自動化など、運用の自動化に活用できそうだ。
今後はディスク使用量の推移グラフ化や、JSON 変換による他システム連携なども検討している。


コメント