Documentation
¶
Overview ¶
Package chainmw 提供 transport 感知的框架无关中间件(基于 core/chain)。
与根包 mw(Hertz app.HandlerFunc 栈)互补:本包中间件面向 core/chain 的 Handler 形态,经 core/transport 读写协议无关的传输信息(Kind/Operation/ Header),可在 hertz、kitex、nns-endpoint 等形态间经桥接复用。根包 mw 的 RecoveryMiddleware/AccessLogMiddleware 亦复用本包内核(#14,一份逻辑两端 跑):Hertz 栈为薄壳,kitex 经 ToKitex 桥接同步获得同等能力。
用法:
h := chain.Finalize(terminal,
chainmw.Recovery(chainmw.WithRecoveryReporter(reportPanic)),
chainmw.AccessLog(),
chainmw.MetadataPropagate("x-tenant-id"),
)
Index ¶
- func AccessLog(opts ...AccessLogOption) chain.Middleware
- func MetadataPropagate(keys ...string) chain.Middleware
- func Recovery(opts ...RecoveryOption) chain.Middleware
- func RedactPath(path string, prefixes []string) string
- type AccessLogOption
- func WithLogFields(fn func(ctx context.Context, req any, rec AccessRecord) []any) AccessLogOption
- func WithLogMessage(msg string) AccessLogOption
- func WithLogger(l logx.Logger) AccessLogOption
- func WithRedactPathPrefixes(prefixes ...string) AccessLogOption
- func WithSilent() AccessLogOption
- func WithSink(sink AccessSink) AccessLogOption
- func WithSkipPaths(patterns ...string) AccessLogOption
- type AccessRecord
- type AccessSink
- type RecoveryOption
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AccessLog ¶
func AccessLog(opts ...AccessLogOption) chain.Middleware
AccessLog 返回访问日志中间件:从 transport 上下文读取 Kind/Operation, 记录耗时、错误与 panic。无 transport 上下文时相应字段记 "-"。日志写出后 依次调用 WithSink 注册的旁路消费者(隔离执行,不影响返回值)。
panic 请求同样产出记录(#20) ¶
下游 panic 时本中间件在恢复点产出 AccessRecord{Panic: true, Err: panic 摘要} ——记日志、喂 sink——随后按原值重新抛出,交由外层 Recovery(或框架自身的 recover 机制)处理。此前 panic 请求零访问记录,故障时段 access log 完全失明。 日志级别 Warn、字段经 WithLogFields 构建(Hertz 薄壳按 Recovery 缺省 500 记 状态码)。
静默模式(#38) ¶
WithSilent 开启「只采不写」:不写任何日志(访问日志与 sink 告警都不写), 采集行为完全不变(SkipPaths / 脱敏 / sink / panic 记录与重抛照常)。 宿主自带 logger 输出同一份记录时用它避免双写。
func MetadataPropagate ¶
func MetadataPropagate(keys ...string) chain.Middleware
MetadataPropagate 返回 header 透传中间件:把服务端请求头中指定的键 复制到响应头(req → resp 方向),供网关/调用方透传租户、灰度标记等 元数据。无 transport 服务端上下文时为 no-op。
func Recovery ¶ added in v0.9.0
func Recovery(opts ...RecoveryOption) chain.Middleware
Recovery 返回 panic 恢复中间件(transport 无关内核)。
行为:下游 panic 被捕获为 *chain.PanicError → 记 Error 日志 → 经 panic 隔离的监控钩子上报 → 以错误返回(链不中断)。响应转换由调用方的错误 出口负责(hertz/chainmw.Wrap 的 WithOnError/默认 mw.Fail、kitex 侧透传 给 kitex 错误处理)。
与 core/chain.Recovery 的关系:捕获/转换语义一致;本实现叠加 logx 日志 与上报 panic 隔离,为「一份逻辑两端跑」的内核(根包 mw 的 Hertz 栈与 kitex 经 ToKitex 桥接均复用本实现)。
用法:
h := chain.Finalize(terminal,
chainmw.Recovery(chainmw.WithRecoveryReporter(reportPanic)),
chainmw.AccessLog(),
)
无 transport 上下文时 kind/op 记 "-"。
func RedactPath ¶ added in v0.9.0
RedactPath 命中任一前缀则保留前缀、其余替换为 "/***";未命中原样返回。 前缀按字节匹配("/alert" 也会命中 "/alert-x",多脱敏无副作用);前缀 恰好等于完整路径(len 相等)视为无敏感尾段,原样返回。
Types ¶
type AccessLogOption ¶
type AccessLogOption func(*accessLogConfig)
AccessLogOption 配置 AccessLog 中间件。
func WithLogFields ¶ added in v0.9.0
func WithLogFields(fn func(ctx context.Context, req any, rec AccessRecord) []any) AccessLogOption
WithLogFields 自定义日志字段构建器(返回键值对序列,顺序即输出顺序; 默认字段 kind/op/cost)。框架桥接层用此注入框架特有字段——如根包 mw 薄壳注入 method/status/latency_ms/ip 保持既有日志格式。
func WithLogMessage ¶ added in v0.9.0
func WithLogMessage(msg string) AccessLogOption
WithLogMessage 自定义日志消息(默认 "access")。
func WithLogger ¶
func WithLogger(l logx.Logger) AccessLogOption
WithLogger 注入 logger(默认 logx.Delegating("chainmw-accesslog"))。 日志经 Ctx* 方法输出,自动携带 trace_id。
func WithRedactPathPrefixes ¶ added in v0.9.0
func WithRedactPathPrefixes(prefixes ...string) AccessLogOption
WithRedactPathPrefixes 设置需要脱敏的 Operation 前缀列表。命中前缀的 Operation 在日志中只保留前缀、其余替换为 "/***"(webhook/{token} 类 「URL 路径即凭证」路由的 token 不落日志,见根包 mw #12)。SkipPaths 判定不受脱敏影响。
func WithSilent ¶ added in v0.13.0
func WithSilent() AccessLogOption
WithSilent 开启「只采不写」模式(#38)。
静默时本中间件不写任何日志:访问日志本身、以及 sink 失败/panic 的告警 日志都不写。采集行为完全不变——SkipPaths 判定、路径脱敏、耗时采集、 sink 调用(时机与顺序不变)、panic 请求的记录产出与按原值重抛都照常。
适用于宿主自带 logger 输出同一份记录的场景:记录由 sink 或宿主自己的 采集逻辑产出,本中间件不再额外写一行,避免双写。与 WithLogger 注入的 logger 叠加时静默优先(logger 仅用于 sink 告警,静默下也不写)。
func WithSink ¶ added in v0.11.0
func WithSink(sink AccessSink) AccessLogOption
WithSink 追加访问记录旁路消费者(可多次调用,按注册顺序同步调用; 多个 sink 彼此隔离——前一个 panic 不影响后一个)。需要异步落库时在 sink 内自行入队:rec 是纯值可安全跨 goroutine 持有,req 则随框架生命周期 (如 Hertz RequestContext 池化复用)不得逸出本次调用。
func WithSkipPaths ¶ added in v0.9.0
func WithSkipPaths(patterns ...string) AccessLogOption
WithSkipPaths 设置跳过记录的 Operation 模式列表(支持 glob,按原始值 匹配、不受脱敏影响;http 侧即请求 PATH,如 "/metrics"、"/internal/*")。 命中时下游照常执行、仅不记访问日志。无 transport 上下文时不判定。
type AccessRecord ¶ added in v0.9.0
type AccessRecord struct {
// Kind 传输类型(http/grpc);无 transport 上下文时 "-"。
Kind string
// Operation 操作标识(http 为请求 PATH),已脱敏。
Operation string
// Latency 下游处理耗时。
Latency time.Duration
// Err 下游返回的错误;Panic 为 true 时携带 panic 摘要("panic: ...")。
Err error
// Panic 为 true 表示本记录来自 panic 恢复点(#20):中间件已记日志/喂 sink
// 并向原 panic 重新抛出,交由外层 Recovery 处理。响应状态码在记录时点尚未
// 写出——Hertz 薄壳按 Recovery 缺省 500 记(自定义 ErrorHandler 时以
// Recovery 自身日志为准)。
Panic bool
}
AccessRecord 是 AccessLog 单次请求的采集结果,供 WithLogFields 构建 自定义日志字段。Operation 已按脱敏前缀处理(SkipPaths 判定用原始值, 不受脱敏影响)。
type AccessSink ¶ added in v0.11.0
type AccessSink func(ctx context.Context, req any, rec AccessRecord) error
AccessSink 是访问记录的旁路消费者(落库 / 上报 / 统计),每条记录产出后 按注册顺序同步调用;SkipPaths 命中的请求不触发(跳过 = 不记录,日志与 sink 口径一致)。返回 error 或 panic 都只记 Warn 日志、绝不影响主链路—— 访问记录是旁路,落库失败不能把请求拖垮。
type RecoveryOption ¶ added in v0.9.0
type RecoveryOption func(*recoveryConfig)
RecoveryOption 配置 Recovery 中间件。
func WithRecoveryLogFields ¶ added in v0.9.0
func WithRecoveryLogFields(fn func(ctx context.Context, req any, pv *chain.PanicError) []any) RecoveryOption
WithRecoveryLogFields 自定义 panic 日志字段构建器(返回键值对序列,顺序 即输出顺序;默认字段 panic/stack/kind/op)。框架桥接层用此注入框架特有 字段——如根包 mw 薄壳注入 method/path 保持既有日志格式。
func WithRecoveryLogger ¶ added in v0.9.0
func WithRecoveryLogger(l logx.Logger) RecoveryOption
WithRecoveryLogger 注入 logger(默认 logx.Delegating("chainmw-recovery"))。 日志经 Ctx* 方法输出,自动携带 trace_id。
func WithRecoveryReporter ¶ added in v0.9.0
func WithRecoveryReporter(fn func(ctx context.Context, req any, pv *chain.PanicError)) RecoveryOption
WithRecoveryReporter 注入监控上报钩子(sentry/datadog 等业务适配器)。
钩子在 panic 隔离下调用:钩子内部 panic 被捕获并记 Error 日志 (reporter_panic/original_panic 字段)、本次上报被丢弃,不影响原始 panic 的日志与错误返回——第三方监控 SDK 恰是最可能 panic 的代码 (先例:根包 mw.RecoveryMiddleware 的 safeReport,2026-09-05 复审修复)。
与 core/chain.WithPanicReporter 的差异:本钩子带 logx 日志与 panic 隔离, 且参数为 *chain.PanicError(与 Recovery 的错误返回类型一致)。