ThinkPHP6.0日志不写入文件或需对接数据库/ES/Logstash,必须手动配置:默认仅启用file驱动,其他通道须通过Log::extend()在日志门面初始化前显式注册,且'default' => 'file'需保持正确,APP_DEBUG=true会绕过所有日志写入。

ThinkPHP6.0项目上线后日志不写入文件,或想把错误日志存进数据库、发到Elasticsearch、推给Logstash,必须手动配置日志驱动——框架默认只启用file驱动,其他通道哪怕在config/log.php里写了也不会自动生效。
确认当前日志驱动是否为File
打开config/log.php,检查'default' => 'file'这一行。如果值是'stdout'、'test'或空字符串,Log::error()调用将不会落盘,而是输出到控制台或直接丢弃。
执行php think run启动内置服务器,在浏览器访问任意不存在路由,观察终端是否打印404信息:若看到,则说明当前驱动是stdout;若页面报错且runtime/log/下无新文件生成,则大概率是test或close => true导致静默关闭。
【APP_DEBUG=true会强制绕过所有日志写入逻辑】,此时即使配置正确,runtime/log/目录也始终为空。
立即学习“PHP免费学习笔记(深入)”;
启用自定义日志驱动(如数据库、ES、远端HTTP)
自定义驱动不会被框架自动识别,必须通过Log::extend()显式注册,且注册动作必须在日志门面首次调用前完成。
方法一:在app/common.php末尾添加(推荐)
use thinkacadeLog;Log::extend('mysql', function($config) { return new applogdriverMysqlLogDriver($config);});
方法二:在服务提供者app/provider/AppServiceProvider.php的register()方法中注册
⚠️ 若注册写在控制器、中间件或app/event.php中,Log门面已初始化,扩展无效,后续调用Log::channel('mysql')会抛出Channel not exists异常。
配置多通道并指定日志级别
第一步:在config/log.php中定义通道
'channels' => [ 'file' => [ 'type' => 'File', 'level' => env('APP_DEBUG') ? ['debug','info','warning','error'] : ['warning','error'], 'path' => runtime_path('log') . DIRECTORY_SEPARATOR, ], 'mysql' => [ 'type' => 'app\log\driver\MysqlLogDriver', 'host' => '10.0.10.5', 'port' => 3307, 'username' => 'log_user', 'password' => 'xxx', 'database' => 'log_db', 'level' => ['error', 'critical'], ],],
第二步:确保'default' => 'file'保持不变,避免全局日志意外走错通道
第三步:在代码中按需写入指定通道:Log::channel('mysql')->error('支付回调超时');
【Log::write()永远只走default通道,不会自动分发到其他channel】,想同时写文件和数据库,必须显式调用两次。
验证驱动是否加载成功
① 在控制器中执行:Log::channel('mysql')->info('test from mysql channel');
② 查看目标数据库对应表是否有新增记录;若无,检查app/log/driver/MysqlLogDriver.php中save()方法是否返回true(ThinkPHP要求必须返回bool,返回null或未返回会被视为失败)
③ 检查运行时错误:若驱动类名拼写错误或命名空间未被composer自动加载,会直接报Class not found;此时需确认composer dump-autoload已执行,且composer.json中psr-4映射路径正确。
④ 手动触发一次错误:throw new Exception('force log test');,观察config/exception.php中'log' => true是否开启——未捕获异常是否写日志,与Log::channel()调用无关,由该配置单独控制。



















