日志不生成的主因是write_path权限不足或路径配置错误,以及ENVIRONMENT为production导致log_threshold=0。需确保app/Writeable/可写、.env设CI_ENV=development、Logger.php中threshold≥1,且log_message()参数正确。

write_path 权限不足或路径未正确配置是日志不生成的最常见原因
CodeIgniter 的日志写入依赖于 WRITEPATH 常量指向的目录(默认为 app/Writeable/)。如果该目录不存在、不可写,或被 .htaccess / Nginx 规则屏蔽,log_message() 就会静默失败,不报错也不落盘。
- 确保
app/Writeable/目录存在且 PHP 进程有写权限(Linux 下常用chmod 755 app/Writeable或更宽松的775,视部署环境而定) - 检查
app/Config/Paths.php中$paths['writablePath']是否被手动修改过,且路径真实可写(建议用is_writable()临时验证) - Apache 用户注意:
.htaccess若禁止访问Writeable目录,会导致日志无法写入;Nginx 用户需确认location ~ ^/app/类规则未拦截该路径 - 日志文件名格式为
log-YYYY-MM-DD.php,后缀是.php(不是.log),这是 CodeIgniter 4 的安全设计,防止直接浏览器访问内容
ENVIRONMENT 设为 development 并启用 log_threshold
日志是否生成,和环境配置强相关。CodeIgniter 默认在 production 环境下关闭所有日志(log_threshold = 0),即使 WRITEPATH 正确也无输出。
- 修改
.env文件:设置CI_ENV=development(或通过服务器环境变量覆盖) - 在
app/Config/Logger.php中确认public $threshold = 1;(1 表示 ERROR 级别及以上;2 是 DEBUG;4 是 INFO) - 不要依赖
index.php中的define('ENVIRONMENT', ...)—— CodeIgniter 4 优先读取.env,硬编码会被忽略 - 注意:日志级别阈值是“大于等于”,
threshold = 2会记录 ERROR 和 DEBUG,但不会记录 INFO(需设为 4)
log_message() 调用位置与参数错误导致“看似没日志”
log_message() 是唯一推荐的日志入口函数,但它对参数敏感,错误调用会直接跳过写入逻辑。
- 第一个参数必须是字符串级别标识:
'error'、'debug'、'info'(大小写敏感,不能是'ERROR'或'Debug') - 第二个参数是消息字符串,不支持 sprintf 占位符自动解析,需提前拼接好:
log_message('error', 'User ' . $id . ' not found'); - 不要在模型或服务类中直接用
error_log()或file_put_contents()—— 这类写法绕过框架日志系统,不受threshold和WRITEPATH控制 - 检查是否在中间件或异常处理器中提前
exit或抛出未捕获异常,导致日志写入流程被中断
Logger 实例未初始化或被覆盖时 debug 模式失效
CodeIgniter 4 使用 Services::logger() 获取单例,但如果在启动早期(如自定义 bootstrap 或 App 初始化前)就调用日志,实例可能为空。
- 避免在
app/Config/App.php构造函数或initController()外部过早调用log_message() - 不要手动 new
Logger实例并调用log()方法——这会跳过框架的通道管理与格式化 - 如果使用了自定义异常处理器(
app/Config/Exceptions.php),确保其中的log_exception()方法调用了log_message('error', ...),而不是仅打印到屏幕
日志不生成这件事,表面看是配置问题,实际常卡在「路径可写性验证缺失」和「.env 与 Logger.php 阈值不同步」这两个点上。尤其上线后切回 production 环境时,容易忘记把 log_threshold 改回 0,结果本地能打日志、线上全沉默。


















