CI3与CI4日志配置核心差异在于写入时机控制与阈值生效位置:CI4需关闭调试模式且设CI_ENVIRONMENT=production才能使log_threshold生效,而CI3仅依赖config.php中log_threshold与log_path可写性;二者均需注意日志文件格式、参数序列化及高并发I/O瓶颈。

CI3 和 CI4 的日志配置逻辑完全不同,直接套用旧配置会失效甚至导致 log_message() 静默失败或写入空白文件。关键区别不在“怎么开”,而在“谁控制写入时机”和“阈值生效位置”。
CI4 必须关掉调试模式才能让日志阈值生效
CI4 的日志系统在 development 环境下会强制绕过 log_threshold 设置,所有 log_message() 调用都会写入,无论你设成 0 还是 1。这不是 bug,是设计行为。
-
.env文件里必须明确设置CI_ENVIRONMENT = production - 同时确保
app/Config/Logger.php中的$threshold属性与.env中的log_threshold一致(推荐统一设为1) - 如果仍看到大量 debug/info 日志,先检查
CI_ENVIRONMENT是否真被加载——运行php spark env查看实际生效环境
CI3 的 log_threshold 只在 config.php 里生效,但路径权限常被忽略
CI3 不依赖环境变量,$config['log_threshold'] 是唯一开关,但它的效果完全取决于 $config['log_path'] 是否可写且路径合法。
- 默认日志路径是
APPPATH . 'logs/',即application/logs/,必须确保该目录存在且 Web 进程有写权限(chmod 755或775) - 若自定义路径如
$config['log_path'] = '/var/log/ci3-app/',需确认 PHP 进程用户(如www-data)对该路径有写权限,否则日志静默丢弃 -
log_threshold = 0真的会关闭所有日志,包括log_message('error', ...)—— 这点和 CI4 不同,CI4 在 dev 模式下即使设 0 也会写
CI4 的 log_message() 不支持数组/对象直接传入
CI4 的 log_message() 内部调用 print_r($msg, true),但若传入未序列化的对象或资源(如 mysqli 实例),会触发 PHP warning 并中断日志写入,表现为日志文件突然变空或缺失某条记录。
- 始终对非字符串参数做预处理:
log_message('error', json_encode($data, JSON_UNESCAPED_UNICODE)) - 避免传入
$_POST、$this或数据库结果集,它们可能含资源或循环引用 - CI3 对此容忍度略高,但同样建议统一用
json_encode()或var_export($var, true)包裹
CI3 和 CI4 共用陷阱:日志文件名时间格式不一致
CI3 默认日志文件名是 log-2026-07-30.php,CI4 是 ci-2026-07-30.log。如果你用脚本轮转或监控日志,硬编码匹配规则会漏掉其中一方。
- CI3 的文件名由
Log.php中的$date_fmt = 'Y-m-d'和固定前缀'log-'拼接,后缀是'.php' - CI4 的文件名由
FileHandler.php控制,前缀可配置(默认'ci-'),后缀固定为'.log',且不带 PHP 标签 - 不要依赖文件扩展名判断内容格式——CI3 的
.php文件实际是纯文本,只是扩展名误导人
真正容易被忽略的是:CI4 的日志写入是同步阻塞的,而 CI3 默认是追加写入。高并发下,CI4 的单文件日志可能成为 I/O 瓶颈,这时得换用 SyslogHandler 或外接 monolog,而不是调高 log_threshold。


















