基于接触与虚拟点补偿的协作机器人与AMR高精度集成方法
2026/5/27 15:36:00
Log::build()->pushContext('tenant_id', $tenantId)->info('email.sent', $context);是 Laravel 10+ 引入的日志上下文链式构建器(Logging Context Builder),用于在单次日志调用中注入临时上下文,而不污染全局日志配置。
// ❌ 全局注入上下文(影响后续所有日志)Log::withContext(['tenant_id'=>$tenantId]);Log::info('email.sent',$context);// 后续 Log::info() 也会携带 tenant_id → 数据污染Log::build()的解决方案// ✅ 仅当前日志携带 tenant_idLog::build()->pushContext('tenant_id',$tenantId)->info('email.sent',$context);// 后续日志不受影响✅本质:创建一次性、隔离的日志实例
Log::build()Illuminate\Log\LogManager的新实例(非单例)pushContext()['tenant_id' => $tenantId]合并到当前构建器的上下文Log::build()->pushContext('tenant_id',$tenantId)->pushContext('trace_id',$traceId)->info('...');info()$context(方法参数)与构建器上下文📌关键:
上下文仅存在于本次build()链式调用中
context=构建器上下文+info($message, $context)的$contextLog::build()->pushContext('tenant_id',123)->info('email.sent',['to'=>'a@example.com']);['tenant_id'=>123,'to'=>'a@example.com']app('log')) 的上下文保持不变// 处理租户请求时$tenant=Tenant::current();Log::build()->pushContext('tenant_id',$tenant->id)->info('user.login',['user_id'=>$user->id]);tenant_id过滤$traceId=request()->header('X-Trace-Id');Log::build()->pushContext('trace_id',$traceId)->info('api.request',['path'=>$request->path()]);// app/Jobs/SendEmail.phppublicfunctionhandle(){Log::build()->pushContext('job_id',$this->job->getJobId())->info('email.processing',['to'=>$this->email]);}| 方法 | 作用域 | 适用场景 |
|---|---|---|
Log::withContext() | 全局(当前请求生命周期) | 请求级上下文(如 user_id) |
Log::build()->pushContext() | 单次日志 | 临时/任务级上下文(如 job_id) |
✅组合使用:
// 全局:当前用户Log::withContext(['user_id'=>auth()->id()]);// 临时:当前任务Log::build()->pushContext('job_id',$jobId)->info('task.start');// 日志包含 user_id + job_id
tenant_id而非tenantId// ❌ 危险Log::build()->pushContext('password',$password);// ✅ 安全Log::build()->pushContext('user_id',$user->id);build()有轻微开销(创建新实例)// config/logging.php'channels'=>['stack'=>['driver'=>'stack','channels'=>['daily'],'formatter'=>Monolog\Formatter\JsonFormatter::class,],],{"level":"info","message":"email.sent","context":{"tenant_id":123,"to":"a@example.com"}}| 问题 | 答案 |
|---|---|
Log::build()作用? | ✅创建隔离的日志实例,避免上下文污染 |
与withContext()区别? | ✅build()是单次,withContext()是全局 |
| 典型场景? | ✅多租户、链路追踪、队列任务 |
| 生产建议? | ✅仅必要时使用 + 字段规范 + JSON 格式 |
日志上下文 = 数据的维度。
Log::build()让你精确控制每个日志事件的维度,
而非用全局上下文“污染”整个请求。
这是构建高可观测性系统的关键细节。