You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

slog中间件添加的上下文属性在使用Logger.With派生日志实例时不生效的问题咨询

slog中间件添加的上下文属性在使用Logger.With派生日志实例时不生效的问题咨询

大家好,我在使用Go 1.24.2的标准库slog时遇到了一个困扰,想请教下各位:

问题背景

我实现了一个自定义的slog处理器中间件ContextHandler,用来自动从context.Context中提取请求域的属性(比如session_id)并添加到日志记录里。这个中间件会包装基础处理器(比如slog.JSONHandler或者第三方的devslog.Handler),代码大致如下:

// ContextHandler middleware
type ContextHandler struct {
	slog.Handler
}

func NewContextHandler(handler slog.Handler) *ContextHandler {
	return &ContextHandler{Handler: handler}
}

func (h *ContextHandler) Handle(ctx context.Context, r slog.Record) error {
	// Example: Get session ID from context
	if sessionID, ok := contextkeys.GetSessionID(ctx); ok {
		r.AddAttrs(slog.String("session_id", sessionID)) // Add attribute to record
	}
	// Pass record to the next handler
	return h.Handler.Handle(ctx, r)
}

// Logger creation wraps the base handler
func NewLogger( /* ... */ ) *slog.Logger {
	var baseHandler slog.Handler
	// ... logic to create baseHandler (JSON, devslog, etc.) ...
	contextAwareHandler := NewContextHandler(baseHandler)
	logger := slog.New(contextAwareHandler)
	return logger
}

在我的gRPC处理器中,我注入了这个NewLogger创建的日志实例:

type AuthHandler struct {
	// ... other fields
	logger *slog.Logger
}

func NewAuthHandler( /* ... */ logger *slog.Logger) *AuthHandler {
	return &AuthHandler{ /* ... */ logger: logger}
}

观察到的现象

  • 正常生效的场景:直接使用注入的logger调用带上下文的方法时,中间件添加的session_id能正确出现在日志输出里:
// Inside handler method
func (h *AuthHandler) SomeMethod(ctx context.Context, /* ... */) {
	// ...
	h.logger.InfoContext(ctx, "Operation successful") 
	// Output includes "session_id=xyz"
}
  • 不生效的场景:当我用.With()派生出一个新的日志实例,再调用带上下文的方法时,中间件添加的session_id不会出现在最终日志里(或者出现得很不稳定),但通过.With()添加的属性(比如op)是正常显示的:
// Inside handler method
func (h *AuthHandler) SomeMethod(ctx context.Context, /* ... */) {
	const op = "Handler.SomeMethod"
	// Create derived logger
	log := h.logger.With(slog.String("op", op))
	// ...
	log.InfoContext(ctx, "Operation successful") 
	// Output includes "op=Handler.SomeMethod" BUT NOT "session_id=xyz"
}

我的疑问

  1. 这种行为是预期的吗?
  2. 为什么通过处理器中间件用r.AddAttrs动态添加的属性,在使用.With()派生的日志实例调用时无法正常生效?
  3. 有没有标准或者推荐的方式,能确保中间件添加的属性即使在使用.With()派生日志实例时也能可靠生效?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 11:44:35