2026年11月5日
2026年11月5日
WordPressのパフォーマンスをリアルタイムで監視する方法
はじめに
WordPressサイトが遅くなっても原因が分からない、突然のエラーに気づくのが遅れる、こうした問題を防ぐためにはリアルタイムのパフォーマンス監視が不可欠です。適切な監視ツールと仕組みを整備することで、問題を早期発見できます。
症状・原因
パフォーマンス監視が必要になる状況:
- サイトが突然遅くなるがタイミングが分からない
- 特定のページだけ応答が遅い
- DBクエリ数が増加しているが原因不明
- エラーが発生しているが管理者が気づいていない
解決手順
ステップ1:Query Monitorで詳細なプロファイリングを行う
# Query Monitorをインストール
wp plugin install query-monitor --activate
// wp-config.php でデバッグを有効化
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('SAVEQUERIES', true); // クエリを全保存(本番では無効化)
// カスタムログ関数
function wp_perf_log(string $message, array $context = []): void {
if (!WP_DEBUG_LOG) return;
$timestamp = date('Y-m-d H:i:s');
$ctx_str = empty($context) ? '' : ' ' . json_encode($context, JSON_UNESCAPED_UNICODE);
error_log("[PERF {$timestamp}] {$message}{$ctx_str}");
}
// ページロード時間を計測してログ
add_action('shutdown', function() {
$load_time = timer_stop(0, 3);
$memory = memory_get_peak_usage(true) / 1024 / 1024;
$queries = get_num_queries();
$url = $_SERVER['REQUEST_URI'] ?? '';
if ((float)$load_time > 2.0) { // 2秒以上を警告
wp_perf_log("SLOW PAGE", [
'url' => $url,
'time' => $load_time . 's',
'memory' => round($memory, 2) . 'MB',
'queries' => $queries,
]);
}
});
ステップ2:カスタムパフォーマンスメトリクスを収集する
// クエリ実行時間を監視する
class WP_Performance_Monitor {
private static array $metrics = [];
private static float $start_time;
public static function init(): void {
self::$start_time = microtime(true);
add_action('wp_footer', [self::class, 'inject_metrics'], 999);
add_action('admin_footer', [self::class, 'inject_metrics'], 999);
}
// 処理時間を記録するユーティリティ
public static function start_timer(string $key): void {
self::$metrics[$key] = ['start' => microtime(true)];
}
public static function stop_timer(string $key, array $meta = []): float {
if (!isset(self::$metrics[$key])) return 0;
$elapsed = microtime(true) - self::$metrics[$key]['start'];
self::$metrics[$key] = array_merge($meta, ['elapsed' => round($elapsed * 1000, 2)]);
return $elapsed;
}
// 遅いクエリを検出する
public static function get_slow_queries(float $threshold_ms = 100): array {
global $wpdb;
if (!defined('SAVEQUERIES') || !SAVEQUERIES) return [];
return array_filter($wpdb->queries, function($q) use ($threshold_ms) {
return ($q[1] * 1000) >= $threshold_ms;
});
}
// フッターにデバッグ情報を出力(管理者のみ)
public static function inject_metrics(): void {
if (!current_user_can('manage_options') || !WP_DEBUG) return;
$total = round((microtime(true) - self::$start_time) * 1000, 2);
$memory = round(memory_get_peak_usage(true) / 1024 / 1024, 2);
$queries = get_num_queries();
$slow = self::get_slow_queries(100);
echo "<!-- WP Perf: {$total}ms | {$memory}MB | {$queries} queries";
if (!empty($slow)) {
echo " | " . count($slow) . " slow queries";
}
echo " -->\n";
}
}
add_action('init', ['WP_Performance_Monitor', 'init']);
ステップ3:定期的な自動ヘルスチェックを実装する
// WP-Cronで定期ヘルスチェック
add_filter('cron_schedules', function($schedules) {
$schedules['every_5_minutes'] = [
'interval' => 300,
'display' => '5分ごと',
];
return $schedules;
});
// ヘルスチェックをスケジュール
if (!wp_next_scheduled('wp_site_health_check')) {
wp_schedule_event(time(), 'every_5_minutes', 'wp_site_health_check');
}
add_action('wp_site_health_check', 'run_site_health_check');
function run_site_health_check(): void {
global $wpdb;
$issues = [];
// DB接続チェック
$db_ok = $wpdb->get_var('SELECT 1');
if ($db_ok !== '1') {
$issues[] = 'DB接続エラー';
}
// ディスク使用量チェック
$disk_free = disk_free_space(ABSPATH);
$disk_total = disk_total_space(ABSPATH);
$disk_pct = round((1 - $disk_free / $disk_total) * 100);
if ($disk_pct > 90) {
$issues[] = "ディスク使用量が{$disk_pct}%に達しています";
}
// メモリチェック
$memory_limit = ini_get('memory_limit');
$memory_used = memory_get_usage(true);
// エラーログサイズチェック
$log_file = WP_CONTENT_DIR . '/debug.log';
if (file_exists($log_file) && filesize($log_file) > 50 * 1024 * 1024) {
$issues[] = 'エラーログが50MBを超えています';
}
// 問題があれば管理者にメール通知
if (!empty($issues)) {
$subject = '[緊急] サイトに問題が検出されました: ' . get_bloginfo('name');
$message = "以下の問題が検出されました:\n\n";
$message .= implode("\n", array_map(fn($i) => "・{$i}", $issues));
$message .= "\n\n" . admin_url('site-health.php');
wp_mail(get_option('admin_email'), $subject, $message);
}
// オプションにステータスを保存
update_option('site_health_last_check', [
'time' => current_time('mysql'),
'status' => empty($issues) ? 'ok' : 'error',
'issues' => $issues,
]);
}
ステップ4:外部監視サービスと連携する
# Uptime Kuma(自己ホスト型監視)をDockerで起動
docker run -d --restart=always \
-p 3001:3001 \
-v uptime-kuma:/app/data \
louislam/uptime-kuma:1
# WordPressのヘルスチェックエンドポイント
# https://example.com/wp-json/myplugin/v1/health
// カスタムヘルスチェックエンドポイント(外部監視サービス用)
add_action('rest_api_init', function() {
register_rest_route('myplugin/v1', '/health', [
'methods' => 'GET',
'callback' => function() {
global $wpdb;
// DB応答時間を計測
$start = microtime(true);
$db_ok = $wpdb->get_var('SELECT 1') === '1';
$db_ms = round((microtime(true) - $start) * 1000, 2);
$status = [
'status' => $db_ok ? 'ok' : 'error',
'database' => ['ok' => $db_ok, 'response_ms' => $db_ms],
'php' => PHP_VERSION,
'wordpress' => get_bloginfo('version'),
'timestamp' => current_time('c'),
];
$http_code = $db_ok ? 200 : 503;
return new WP_REST_Response($status, $http_code);
},
'permission_callback' => '__return_true',
]);
});
ステップ5:パフォーマンスデータをダッシュボードに表示する
# WP-CLIでパフォーマンス情報を取得
wp db query "SELECT option_name, option_value FROM wp_options WHERE option_name = 'site_health_last_check'"
# ページロード時間をサーバーログから分析
awk '{print $NF, $7}' /var/log/nginx/access.log | sort -n | tail -20
# PHPスローログを確認
grep "slow script" /var/log/php-fpm/slow.log | tail -10
注意事項
SAVEQUERIESは本番環境では無効にしてください(メモリ使用量が増加します)- ヘルスチェックのメール通知が多すぎる場合は、連続エラー時のみ送信するようにしてください
- 外部監視サービスのIPアドレスは適切にホワイトリストに登録してください
まとめ
WordPressのパフォーマンス監視は、①Query MonitorとSAVEQUERIESによる詳細プロファイリング、②カスタムメトリクス収集クラス、③WP-Cron定期ヘルスチェック、④REST APIヘルスエンドポイント、⑤Uptime Kumaなどの外部監視サービス連携で構築します。問題を早期発見・通知する仕組みが重要です。