什么是 Context
Laravel 的 Context 功能提供了一种在请求、队列任务、命令之间跨越执行边界记录与共享信息的机制。 通过Illuminate\Support\Facades\Context 门面添加的信息,会自动附带到应用写出的所有日志条目中。
这样就能明确区分某次日志调用附带的信息与 Context 保存的共享信息。
在使用队列或分布式架构进行追踪时尤其有用。
上下文的传播流程
基本用法
最典型的用法是在中间件中设置trace_id。之后所有的日志都会自动包含它。
1
创建中间件
2
向 Context 添加追踪 ID
3
注册中间件
在
bootstrap/app.php 中作为全局中间件注册。url 和 trace_id。
写入上下文
add — 添加值
add 会覆盖已有的键。若只想在键不存在时才添加,使用 addIf。
increment / decrement — 管理计数器
用于数值增减的专用方法,可通过第二个参数指定增减量。when — 按条件添加
使用when 可以根据条件为 true 或 false 分别添加不同的数据。
push — 追加到栈
Context 支持以「栈」的形式保存列表数据。push 会按添加顺序累积数据。
读取上下文
get / all
only / except — 获取子集
pull / pop — 取出并删除
pull 在取值的同时从上下文中删除该键。
pop。
remember — 不存在则设置并返回
has / missing — 判断键是否存在
即使存的是
null,has 也会返回 true。它只判断键是否已注册。删除上下文
使用forget 删除键。
作用域上下文
使用scope 可以在闭包执行期间临时修改上下文,闭包结束后自动恢复原状态。
在测试或局部处理中希望暂时向日志中附加信息时非常方便。
Hidden Context
对于不希望输出到日志的数据(密码、API 密钥、个人识别信息等),可存放到 Hidden Context 中。 普通的get 无法读取,需通过 getHidden 等专用方法访问。
传递到队列任务
当把任务派发到队列时,当前的上下文会自动序列化并包含在任务的 payload 中。 任务执行时会恢复原上下文,因此请求中设置的trace_id 也会自动出现在队列中的日志里。
trace_id 也出现在了队列上的日志中。
Dehydrating — 任务发送时的自定义
Context::dehydrating 允许在任务发送前修改上下文。
比如,可用于把由 Accept-Language 头决定的 locale 传给队列。
Hydrated — 任务执行时的恢复
Context::hydrated 用于在任务执行前恢复上下文的时机添加处理。
比如,把此前保存的 locale 应用回配置:
小结
Context 与 Log::withContext 的区别
Context 与 Log::withContext 的区别
Dehydrate / Hydrate 的常见用法
Dehydrate / Hydrate 的常见用法
- locale 传递:
dehydrating时把app.locale存入 Hidden Context,hydrated时通过Config::set恢复。 - 认证信息传播:使队列任务也能访问请求时已认证的用户信息。
- 租户 ID:在多租户应用中跨队列共享租户标识。