Help us shape the future of Go! Take the 2026 Go Developer Survey

chainmw

package
v0.13.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 31, 2026 License: MIT Imports: 9 Imported by: 0

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

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

func RedactPath(path string, prefixes []string) string

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 的错误返回类型一致)。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL