WordPress管理画面の「ツール」からデバッグログの末尾だけを読む例です。ログを書き換えず、日別の総件数は集計しません。
ログの保存先を先に確認
WP_DEBUG_LOGに設定したローカルファイルを読みます。trueならwp-content/debug.log、文字列なら指定先です。Web公開領域外の絶対パスを使い、サーバー側で閲覧を制限してください。WP_DEBUG_DISPLAYをfalseにするだけではログファイルへの公開アクセスを防げません。既存のwp-config.php設定を重複定義しないでください。
閲覧処理を追加
子テーマfunctions.phpまたは専用プラグインのどちらか一方へ追加します。既存PHP内では開始タグを省きます。
function waza_log_tail($file, $limit = 131072) {
if (!is_string($file) || strpos($file, '://') !== false || !is_file($file) || !is_readable($file)) {
return new WP_Error('log_unavailable', 'ログファイルを読み取れません。');
}
if (!is_int($limit) || $limit < 1 || $limit > 131072) return new WP_Error('log_limit', '読み込み量が不正です。');
$handle = @fopen($file, 'rb');
if (!$handle) return new WP_Error('log_open', 'ログファイルを開けません。');
$stat = fstat($handle);
if ($stat === false || !isset($stat['size']) || $stat['size'] < 0) { fclose($handle); return new WP_Error('log_stat', 'ファイルサイズを確認できません。'); }
$start = max(0, $stat['size'] - $limit);
if (fseek($handle, $start) !== 0) { fclose($handle); return new WP_Error('log_seek', '読み取り位置を設定できません。'); }
$at_line_start = $start === 0;
if ($start > 0) {
if (fseek($handle, $start - 1) !== 0) { fclose($handle); return new WP_Error('log_seek', '読み取り位置を設定できません。'); }
$at_line_start = fread($handle, 1) === "\n";
}
$length = min($limit, $stat['size'] - $start);
$text = $length > 0 ? stream_get_contents($handle, $length) : '';
fclose($handle);
if ($text === false) return new WP_Error('log_read', '読み取りに失敗しました。');
if (!$at_line_start) {
$newline = strpos($text, "\n");
$text = $newline === false ? '' : substr($text, $newline + 1);
}
$last_newline = strrpos($text, "\n");
return $last_newline === false ? '' : substr($text, 0, $last_newline + 1);
}
function waza_log_page() {
if (!current_user_can('manage_options') || (is_multisite() && !is_super_admin())) {
wp_die('このログを閲覧する権限がありません。', '', array('response' => 403));
}
$setting = defined('WP_DEBUG_LOG') ? WP_DEBUG_LOG : false;
$file = is_string($setting) ? $setting : ($setting === true ? WP_CONTENT_DIR . '/debug.log' : '');
$text = waza_log_tail($file);
echo '<div class="wrap"><h1>デバッグログの末尾</h1><p>末尾128KiB以内の完全な行のみ表示します。全件集計ではありません。</p>';
if (is_wp_error($text)) echo '<p>' . esc_html($text->get_error_message()) . '</p>';
else echo '<pre style="white-space:pre-wrap;overflow-wrap:anywhere">' . esc_html($text) . '</pre>';
echo '</div>';
}
add_action('admin_menu', function () {
if (is_multisite() && !is_super_admin()) return;
add_management_page('デバッグログの末尾', 'デバッグログの末尾', 'manage_options', 'waza-log-tail', 'waza_log_page');
});
読める範囲と確認
1回の読み込みは末尾128KiBまでです。開始位置が行頭なら、その行も残します。開始位置が行の途中なら、その部分を捨てます。末尾に改行がない書き込み途中の行も除き、次の閲覧で改行まで書き込まれたものを表示します。読み取り開始時に確認したファイルサイズまでを上限にするため、その後の追記を読み込み量へ含めません。非常に長い1行しかない場合は空表示になることがあります。ログの全件数やエラー発生日を推定しません。ファイルが追記・ローテーションされる途中の厳密なスナップショットでもありません。
管理者権限のある利用者だけが閲覧でき、マルチサイトでは特権管理者に限定します。HTMLを含むログも文字として出力します。導入後は権限のないユーザーが閲覧できないこと、スマホ幅の長い行、独自ログパスを確認してください。実際の管理画面での操作確認は設置先で必要です。
表示内容からログの状態を切り分ける
| 表示・症状 | 確認する内容 |
|---|---|
| 「ログファイルを読み取れません。」 | WP_DEBUG_LOGの設定値、ファイルの存在、PHPからの読み取り権限 |
| 読めるのにログ欄が空 | 空ファイル、改行前の書き込み途中、末尾範囲に完全な行がない可能性 |
| 最後の追記がまだ出ない | 書き込みが改行まで完了した後に再表示する |
| 古いエラーが見つからない | 末尾128KiBの範囲外の可能性。元ファイルやローテーション済みログを調べる |
| 管理者以外から開けない | この例の権限制限による拒否。閲覧可能にするため権限を広げない |
空欄は「エラーがない」という判定ではありません。まずファイルを読めたか、次に完全な行があるかを分けて確認します。この例は書き込み途中の末尾を除外するため、追記が完了してから再表示すると行が現れることがあります。
読み取れる範囲を超えた調査は、サーバーのログ管理機能などで必要な期間を確認します。管理画面の表示をコピーして共有する前に、パス・ユーザー情報・URLのパラメーターなどを確認し、調査に不要な内容は省いてください。
画面を再読み込みして追記の確定を確認する
「ツール → デバッグログの末尾」を開き、表示されない末尾行がある場合は、まずその行の末尾に改行が書かれているかを確認してください。このコードは追記途中の行を表示しません。改行まで記録された後に画面を再読み込みすると、その行が表示されます。
隔離環境の管理画面で、日本語の完全行と、改行のない「追記途中」を同じログに用意しました。最初は完全行だけを表示し、改行を追加して再読み込みすると2行とも表示されました。ログ中のscriptタグも文字列として表示され、HTML要素として実行されませんでした。
同じ画面で空ファイルと欠損ファイルも確認しました。空ファイルでは表示欄が空になり、欠損ファイルでは「ログファイルを読み取れません」と表示されます。空表示だけでエラーがないと判断せず、ログの保存先と記録が有効な時間帯を先に照合してください。

調査を終えたら
不要になったら今回の関数とフックを停止します。コードはログを書き換えたり削除したりしません。保存期間やローテーションはサーバー側で管理します。エラー原因の調査はサイトヘルスの確認手順も参照してください。
読み取り境界の確認
専用ログで、行頭からの読み取り、途中の行の除外、日本語の保持、128KiBを超える長い行、空ファイル、HTMLの文字列表示を確認しました。権限のない利用者は管理画面のコールバックでも拒否されます。
ローカルのWordPressで、管理者・編集者・投稿者・寄稿者・購読者の権限分岐と、専用ログへの追記時の読み取りを確認しました。管理画面でも完全行・追記途中・改行確定後・空ファイル・欠損ファイルを確認済みです。マルチサイトの特権管理者判定、スマホ表示、ログのローテーションは未検証です。



