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などの外部監視サービス連携で構築します。問題を早期発見・通知する仕組みが重要です。

お気軽にご相談ください

お見積りへ お問い合わせへ
▲