跳至內容
設定

WordPress 除錯記錄檔位置:debug.log 放在哪,以及怎麼把它搬走

在 wp-content 裡找到 debug.log、把它移到網站根目錄之外讓訪客抓不到,並修正那些讓檔案一直空白的 WP_DEBUG 設定。

發布於

WordPress 預設把除錯記錄寫到 wp-content/debug.log,在磁碟上的絕對路徑是 /path/to/your/site/wp-content/debug.log。這個檔案要等到真的有東西被記錄時才會存在,而且只有在 wp-config.phpWP_DEBUGtrueWP_DEBUG_LOG 已啟用時才會被寫入。這個預設位置同時也是一個實實在在的資安問題,因為在多數主機上任何人都能用瀏覽器把它抓走。

三個常數各自的作用

三個都要放進 wp-config.php,並且在 /* That's all, stop editing! Happy blogging. */ 這一行的上方。加在那行下方的東西,會在 WordPress 啟動完成之後才執行,等於被忽略。

常數預設值作用
WP_DEBUGfalse總開關。把 PHP 的錯誤回報層級拉高,顯示通知、警告和棄用提示。這張表上其他項目沒有它都不會運作。
WP_DEBUG_LOGfalse把錯誤送進檔案。設為 true 代表 wp-content/debug.log。若給的是字串,則視為要寫入的檔案路徑。
WP_DEBUG_DISPLAYtrue把錯誤印進頁面 HTML,每一位訪客都看得到。

大家搞錯的是它們之間的相依關係。WP_DEBUG_LOG 是在 WordPress 啟動程式碼中 WP_DEBUG 的判斷分支「裡面」被讀取的。如果 WP_DEBUGfalse,把 WP_DEBUG_LOG 設成 true 完全不會有任何效果 —— 沒有檔案、沒有錯誤、也沒有警告。如果你加了 WP_DEBUG_LOG 卻沒看到記錄檔,先去檢查 WP_DEBUG

一組可用於正式網站的設定:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );
@ini_set( 'display_errors', 0 );

如果 WP_DEBUG 在檔案更上方已經定義過 —— 通常都有,而且被設為 false —— 請直接編輯那一行,不要再加第二個 define()。同一個常數定義兩次會丟出 PHP 警告,而在開啟顯示的網站上,那則警告會直接落在你頁面的最上方。

為什麼正式環境的 WP_DEBUG_DISPLAY 必須是 false

顯示開啟時,PHP 錯誤會被輸出進 HTML 回應裡。佈景主題送出的一則棄用通知,就足以把你伺服器的絕對檔案系統路徑印給每一位訪客看。一則資料庫錯誤會印出資料表名稱和查詢片段。更糟的是,在標頭送出之前出現的輸出會破壞轉址、破壞那些預期收到乾淨 JSON 的 REST 和 AJAX 回應,還可能造成白畫面,然後大家又把它怪到外掛頭上。

有個細節值得知道:把 WP_DEBUG_DISPLAY 設成 null 和設成 false 並不一樣。null 是告訴 WordPress 不要動 PHP 的 display_errors 設定,沿用伺服器上原本的設定。false 則是主動把它強制關閉。在正式網站上請用 false,並且加上前面那行 ini_set 作為雙重保險,因為外掛可能在請求稍後的階段又把 display_errors 打開。

預設位置是可以被公開抓取的

wp-content/debug.log 位在網站根目錄之內。原廠的 WordPress 安裝不會阻擋對它的直接請求。在典型的 Apache 或 nginx 設定上,https://yoursite.com/wp-content/debug.log 會以純文字把檔案回傳給你。除錯記錄裡有伺服器絕對路徑、外掛與佈景主題的內部細節、含有真實查詢語句的資料庫錯誤,有時候還有傳進失敗函式的參數值。對任何猜到這個網址的人來說,那是白送的偵察情報 —— 而且它是自動化掃描工具最先嘗試的網址之一。

處理方式有兩種。比較好的那一種是把記錄檔搬走。

用路徑把記錄檔搬走

自 WordPress 5.1 起,WP_DEBUG_LOG 接受字串形式的檔案路徑,而不只是布林值。把它指到文件根目錄之外的地方:

define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', '/home/youruser/logs/wp-errors.log' );
define( 'WP_DEBUG_DISPLAY', false );

那個路徑有三條規則。請使用絕對路徑 —— 相對路徑會以 PHP 的工作目錄為基準解析,而那會隨請求和伺服器而變,你會搞不清楚檔案跑到哪去了。目錄必須事先存在;PHP 不會幫你建立,而且如果它打不開檔案,會靜悄悄地失敗。還有,目錄必須是 PHP 使用者可寫入的,而在共享主機上,那跟你用 SFTP 登入的帳號並不是同一個。

如果你的主機把你限制在網站根目錄裡、上層沒有任何地方可寫,那就保留預設路徑,改在伺服器層級擋掉存取。Apache:

<Files "debug.log">
  Require all denied
</Files>

這要放進 wp-content 裡面的 .htaccess 檔案,不是根目錄那一個 —— 當你儲存永久連結設定時,WordPress 會重寫根目錄的 .htaccess,可能把你加的內容洗掉。在 nginx 上,.htaccess 完全沒有作用;你需要在伺服器設定裡加一段 location 區塊,而在代管主機上這通常意味著要去找客服。

也要誠實看待「擋起來」到底換到了什麼:檔案仍然躺在一個網頁伺服器會對外提供服務的目錄裡。任何外掛的路徑遍歷漏洞都還是讀得到它。把它移出網站根目錄,才是比較強的做法。

讀取與即時追蹤這個檔案

透過 SSH,在重現問題的同時即時盯著它:

tail -f wp-content/debug.log

在另一個分頁重現錯誤,新的行就會隨著被寫入而出現。如果只想看最近發生的事,或想過濾出某個外掛:

tail -n 100 wp-content/debug.log
grep -i 'plugin-slug' wp-content/debug.log | tail -n 50

PHP 是附加到檔案結尾的,所以請由下往上讀。每一筆紀錄的時間戳記都是 UTC,跟你 WordPress 的時區設定不會一致 —— 別因此以為自己在看很舊的紀錄。

用 WP-CLI 可以不用手動編輯檔案就切換這些常數:

wp config set WP_DEBUG true --raw
wp config set WP_DEBUG_LOG true --raw
wp config set WP_DEBUG_DISPLAY false --raw

--raw 這個參數很重要 —— 少了它,寫進去的值會是字串 "true",而不是布林值。若要用路徑的寫法,就把 --raw 拿掉,讓它以帶引號的字串寫入。

沒有 SSH?用 SFTP 把檔案下載下來,或在主機的檔案管理員裡打開。除非你完全信任,否則請避開那些在 wp-admin 裡直接呈現記錄內容的外掛;那等於把一個裝滿伺服器內部資訊的檔案交給外掛去讀。

如果你想直接拿到適合自己環境的 wp-config 區塊,包含一個安全的根目錄外路徑以及對應的伺服器規則,WordPress 除錯記錄產生器可以幫你生出來。

用完就關掉

WordPress 核心不會輪替或清空 debug.log。在一個每次載入頁面都丟出通知的網站上,它會無限成長,最後把磁碟塞爆 —— 那會讓網站掛得比你原本在追的那個 bug 還慘。開啟記錄、重現問題、讀完記錄,然後把 WP_DEBUG 設回 false

要清空檔案但不刪掉它:

: > wp-content/debug.log

當記錄檔一直是空的

按照這個順序逐一檢查。WP_DEBUGfalse —— 最常見的單一原因,而且它會無聲無息地讓其他設定全部失效。常數被放在 wp-config.php 裡「stop editing」那行的下方檔案權限 —— PHP 無法寫入 wp-content,或無法寫入你指定的自訂目錄。在 wp-config 載入完成之前就發生的嚴重錯誤,例如設定檔本身的語法錯誤,發生得太早,WordPress 的記錄機制來不及攔截;那些會進到伺服器自己的 PHP 錯誤記錄檔。主機覆寫了你的設定 —— 有些代管平台會把 PHP 的 error_log 設定鎖死,或把記錄導進他們自己的控制台,這種情況下你的常數其實設得沒錯,輸出只是跑到別的地方去了。在斷定自己設定壞掉之前,先去看主機的記錄檢視工具。

FAQ

常見問題

WordPress 的除錯記錄檔放在哪裡?

預設是 wp-content/debug.log,就直接放在你的 wp-content 資料夾裡。WordPress 只有在真的記錄到錯誤時才會建立這個檔案,所以 wp-content 裡沒看到它,並不代表記錄功能壞了。如果 WP_DEBUG_LOG 給的是一個檔案路徑而不是 true,記錄就會寫到那個路徑去。

為什麼 wp-content 裡沒有 debug.log 檔案?

常見的原因有三個。WP_DEBUG 是 false,這樣不管 WP_DEBUG_LOG 怎麼設,WordPress 都不會開啟記錄。還沒有任何錯誤發生,所以檔案還沒被建立。或是因為檔案權限的關係,PHP 無法寫入 wp-content。先檢查常數,再檢查權限。

別人可以下載我的 WordPress debug.log 嗎?

通常可以。wp-content/debug.log 位在網站根目錄之內,而且沒有任何存取規則保護它,所以用瀏覽器請求那個網址往往就會直接把檔案傳回來。除錯記錄裡經常包含伺服器絕對路徑、資料庫錯誤和查詢片段。請把記錄檔移到網站根目錄之外,或在伺服器設定裡擋掉它。

WP_DEBUG_LOG 和 WP_DEBUG_DISPLAY 有什麼不同?

WP_DEBUG_LOG 把錯誤寫進檔案。WP_DEBUG_DISPLAY 則把錯誤印進頁面 HTML 裡,訪客看得到。在正式網站上,你要的是開啟記錄、關閉顯示。除非 WP_DEBUG 設為 true,否則這兩個都會被完全忽略 —— 而這正是大多數人漏掉的一步。

要怎麼讀 WordPress 的除錯記錄檔?

透過 SSH,對記錄檔路徑執行 tail -f,就能在重現問題的同時即時看到新的紀錄出現。沒有 SSH 的話,用 SFTP 把檔案下載下來,或在主機的檔案管理員裡打開。請由下往上讀,因為 PHP 是把最新的紀錄附加在檔案結尾。

開啟 WP_DEBUG 會拖慢正式網站嗎?

會慢一點,但更大的風險是磁碟。在流量高的網站上大量記錄可能讓 debug.log 長到好幾 GB 並塞爆磁碟,那會讓網站直接掛掉。開啟它、重現問題、讀完記錄,然後關掉。WordPress 核心不會幫你輪替或清空那個檔案。