Hyperf 默认静默处理协程异常,需配置 file 日志驱动、注册全局异常钩子、启用调试日志及组件错误追踪,并通过主动触发错误验证日志有效性。

Hyperf 默认使用 Swoole 协程服务器,错误不会像传统 PHP-FPM 那样直接输出到 Web 页面或标准错误流,很多异常(如协程内未捕获的 Throwable、定时任务崩溃、WebSocket 连接异常中断)默认被静默吞掉,导致问题难以定位。开启并配置好日志文件记录,是排查这类“隐藏错误”的关键一步。
确认日志驱动已启用 file
Hyperf 默认日志配置在 config/autoload/logger.php 中。需确保 'default' => 'file',且 'channels' 下的 'file' 配置存在并启用:
- 检查
handler是否为Monolog\Handler\StreamHandler或Hyperf\Logger\Handler\FileHandler - 确认
constructor中的filename路径可写(如runtime/logs/hyperf.log) - 推荐启用
daily滚动('max_files' => 7),避免单文件过大
捕获协程内未处理的异常和错误
Hyperf 的协程上下文独立,try/catch 无法跨协程捕获。必须通过全局钩子记录:
- 在 config/autoload/processes.php 中注册
Hyperf\Process\ProcessManager::setOnWorkerErrorCallback()回调,记录$throwable - 为
Swoole\Coroutine\run外层添加Co::set(['hook_flags' => SWOOLE_HOOK_ALL])并配合Co::setExceptionHandler()捕获协程内未捕获异常 - 在 bin/hyperf.php 启动前注册
set_exception_handler和set_error_handler,兜底记录致命错误
开启调试级日志与组件错误追踪
部分组件(如数据库、Redis、HTTP 客户端)默认不打详细错误。需显式调整其日志级别:
- 将 config/autoload/logger.php 中
'level'设为'debug'(上线环境建议'warning') - 在 config/autoload/database.php 中开启
'options' => [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION],确保 DB 错误抛出并被日志捕获 - 为
Hyperf\HttpServer\Server和Hyperf\WebSocketServer\Server添加'onOpen'/'onMessage'/'onClose'日志埋点,排查连接生命周期异常
验证日志是否真正生效
不要只看日志文件是否存在,要主动触发错误并观察记录:
- 在任意 Command 或 Controller 中写
throw new RuntimeException('test hidden error');,查看日志中是否出现完整堆栈 - 用
co::sleep(1); throw new Exception();测试协程内异常是否被捕获 - 执行
php bin/hyperf.php start后,用tail -f runtime/logs/hyperf.log实时监控 - 检查日志中是否有
[error]、[critical]、[exception]等关键词及对应 trace


















