webman 集成 sentry 必须手动初始化官方 sdk 并在 onworkerstart 中调用 sentry\init(), onrequest 中 configurescope 注入请求上下文,cli 脚本末尾需 flush,否则易漏报 parseerror、500 错误及任务异常。

Webman 默认不集成 Sentry,必须手动初始化 SDK 并确保它在请求生命周期早期生效;否则 500 错误、ParseError 或 CLI 任务异常大概率漏报。
为什么 Webman 不能直接用 sentry/sentry-laravel?
Webman 不是 Laravel,没有 Service Provider、report() 方法或自动异常钩子。装 sentry/sentry-laravel 会报类找不到或初始化失败,且 php artisan sentry:publish 命令根本不存在。
- 必须用官方基础 SDK:
composer require sentry/sentry - 不能依赖框架适配器,所有异常捕获、上下文注入、flush 清理都得自己写
- Webman 的
onWorkerStart和onRequest是唯一可控入口,SDK 初始化必须放在onWorkerStart里
Sentry\init() 必须在 onWorkerStart 中调用
Webman 是常驻内存模型,worker 启动后长期运行,Sentry\init() 只需执行一次。若放到 onRequest 或中间件里,每次请求都新建 Client,内存泄漏且上报重复。
- 在
start.php或bootstrap/app.php的Worker::onWorkerStart回调中初始化:
use Sentry\State\Hub;
use Sentry\Options;
Worker::onWorkerStart = function () {
$options = new Options();
$options->setDsn($_ENV['SENTRY_DSN'] ?? '');
$options->setEnvironment($_ENV['APP_ENV'] ?? 'production');
$options->setRelease($_ENV['APP_VERSION'] ?? 'dev');
$options->setErrorTypes(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);
// 关键:启用错误处理器(否则 E_WARNING/E_NOTICE 不上报)
$options->setEnableErrorHandler(true);
// 关键:启用异常处理器(捕获未 catch 的 Throwable)
$options->setEnableExceptionHandler(true);
Hub::setCurrent(new \Sentry\Client($options));
};
- DSN 必须带完整协议和路径,例如
https://xxx@o123.ingest.sentry.io/456,只填域名或 ID 会导致静默失效 - CLI 场景(如定时任务)需额外在脚本末尾调用
\Sentry\flush(2),否则进程退出时队列未发完就丢数据
如何给每个请求注入用户 ID、trace_id 等上下文?
Webman 没有 Laravel 的 request scope 自动绑定机制,必须在 onRequest 中手动 setScope —— 且不能复用全局 Hub,否则并发请求会污染彼此的 context。
- 在
onRequest回调开头,为当前请求创建新 Scope:
Worker::onRequest = function ($connection, $request) {
// 清空上一个请求残留的 scope
\Sentry\configureScope(function (\Sentry\State\Scope $scope) use ($request) {
$scope->clear();
// 注入请求级上下文
$scope->setTag('route', $request->path());
$scope->setTag('method', $request->method());
$scope->setUser(['id' => $request->header('x-user-id', 'anonymous')]);
$scope->setExtra('request_id', $request->header('x-request-id', uniqid('req_')));
});
// 后续业务逻辑...
};
- 不要在中间件里调用
\Sentry\configureScope(),Webman 中间件执行顺序不可控,且 scope 是静态单例,易被覆盖 - 如果用了自定义日志通道(如 Monolog),想让
Log::error()也触发 Sentry 上报,必须显式调用\Sentry\captureMessage(),Sentry 不会自动监听日志
常见漏报场景与修复点
Webman 下 Sentry 漏报不是 SDK 问题,而是生命周期错位或配置缺失导致的“静默跳过”。最典型的是 ParseError(语法错误)和 CLI 任务失败。
-
ParseError:PHP 解析阶段崩溃,连onWorkerStart都没执行。必须在start.php最顶部加set_error_handler()捕获并转成Throwable再交由 Sentry 处理 - CLI 脚本(如
php task.php):必须在脚本末尾加\Sentry\flush(2),否则上报线程可能被强制终止 - 忽略 404/403 异常:Webman 不抛出标准
NotFoundHttpException,需在路由层手动判断状态码,并在before_send中过滤$event['level'] === 'error' && strpos($event['message'], '404') !== false - 环境开关没生效:检查
config/app.php是否把'sentry' => env('SENTRY_ENABLED', false)当成布尔值读取,字符串'false'在 PHP 里是 true
Webman 的轻量带来灵活性,也意味着 Sentry 集成没有“默认正确”的路径——每个 hook 点、每处 scope、每次 flush 都得亲手确认是否在对的时间做了对的事。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











