WordPress 调试日志位置:debug.log 在哪,以及怎么把它挪走
在 wp-content 里找到 debug.log,把它移到 Web 根目录之外让访客拿不到,并修好那些让日志一直是空的 WP_DEBUG 配置。
发布于
WordPress 默认把调试日志写到 wp-content/debug.log,在磁盘上的绝对路径就是 /path/to/your/site/wp-content/debug.log。这个文件在真的有东西被记录之前并不存在,而且只有当 wp-config.php 里 WP_DEBUG 为 true 且 WP_DEBUG_LOG 已启用时,它才会被写入。这个默认位置本身也是一个实实在在的安全问题,因为在大多数主机上,任何人都能用浏览器把它取走。
三个常量,各自负责什么
三个都要写进 wp-config.php,位置在 /* That's all, stop editing! Happy blogging. */ 这一行的上方。写在那行下面的任何内容,都是在 WordPress 启动完成之后才执行的,会被忽略。
| 常量 | 默认值 | 作用 |
|---|---|---|
WP_DEBUG | false | 总开关。提高 PHP 的错误报告级别,显示 notice、warning 和弃用提示。没有它,下面两个都不起作用。 |
WP_DEBUG_LOG | false | 把错误写进文件。true 表示写入 wp-content/debug.log。如果给的是字符串,则被当作要写入的文件路径。 |
WP_DEBUG_DISPLAY | true | 把错误打印进页面 HTML,每个访客都看得见。 |
最容易被搞错的是它们之间的依赖关系。WP_DEBUG_LOG 是在 WordPress 启动代码中 WP_DEBUG 那个分支里被读取的。如果 WP_DEBUG 是 false,把 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 位于 Web 根目录之内。原生的 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 登录的那个往往不是同一个。
如果你的主机把你限制在 Web 根目录里,上面没有任何地方可写,那就保留默认路径,改成在服务器层面禁止访问。Apache:
<Files "debug.log">
Require all denied
</Files>
这段要放进 wp-content 里的 .htaccess,不是根目录那个——你保存固定链接时 WordPress 会重写根目录的 .htaccess,可能把你加的内容抹掉。在 nginx 上,.htaccess 完全不起作用,你需要在服务器配置里加一个 location 块,而在托管主机上这通常意味着去找客服。
也要如实看待”禁止访问”能带来什么:文件仍然躺在一个 Web 服务器会去读取的目录里。任何插件里的一个路径穿越漏洞,照样能把它读出来。把它移出 Web 根目录才是更强的解法。
阅读和实时跟踪这个文件
有 SSH 的话,一边复现 bug 一边实时看:
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 里的插件——那等于把一个装满服务器内部信息的文件的读取权交给了它。
用完就关掉
WordPress 核心不会轮转或截断 debug.log。在一个每次加载页面都抛 notice 的站点上,它会无限增长,最后塞满磁盘——那比你原本在追的那个 bug 把站点搞得更惨。开启日志,复现问题,读日志,然后把 WP_DEBUG 改回 false。
不删除文件、只清空内容:
: > wp-content/debug.log
日志一直是空的怎么办
按顺序逐条排查。WP_DEBUG 是 false —— 最常见的单一原因,而且它会悄悄让其他一切都失效。常量被写在了”stop editing”那一行下面(在 wp-config.php 里)。文件权限 —— 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 位于 Web 根目录之内,默认没有任何访问规则保护它,所以浏览器直接请求那个网址往往就能把文件拿走。调试日志里常常有服务器绝对路径、数据库错误和查询片段。请把日志移到 Web 根目录之外,或者在服务器配置里禁止访问它。
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 并塞满磁盘,直接把站点搞挂。用法是:打开它,复现 bug,读日志,然后关掉。WordPress 核心不会替你轮转或截断这个文件。