我想以自己的格式记录来自net / http的错误。在net / http包中,我找到了Server结构:
type Server struct { //... ErrorLog *log.Logger }
我想用自己的实现代替logger:
type AppLogger struct { log *zap.SugaredLogger } func (l *AppLogger) Error(message string, keyAndValues ...interface{}) { l.log.Errorw(message, keyAndValues...) }
实施此方法的正确方法是什么?
更新:
我有以下配置的zap记录器:
cfg := zap.Config{ Encoding: encoding, Level: zap.NewAtomicLevelAt(zap.DebugLevel), OutputPaths: []string{"stdout"}, ErrorOutputPaths: []string{"stdout"}, EncoderConfig: encCfg, } logger, err := cfg.Build()
它配置为以json格式编写。我希望net/http以与zap相同的方式编写错误。我创建以下内容:
net/http
type serverJsonWriter struct { io.Writer } // ListenAndServeTLS - with custom log Writer func ListenAndServeTLS(addr, certFile, keyFile string, handler http.Handler) error { server := &http.Server{ Addr: addr, Handler: handler, ErrorLog: logger.New(serverJsonWriter{}, "", 0), } } func (w serverJsonWriter) Write(p []byte) (n int, err error){ // {"error":{"type":"net/http error","message":"header too long"}} }
问题:
serverJsonWriter
zap
log.Logger
这很容易log.Logger做到,因为该类型可以保证每个日志消息都可以通过io.Writer一次Writer.Write()调用传递到目标:
io.Writer
Writer.Write()
每个日志记录操作都会调用Writer的Write方法。一个Logger可以同时从多个goroutine中使用;它保证序列化对Writer的访问。
因此,基本上,您只需要创建一个实现的类型io.Writer,并且该类型的Write()方法只需调用记录器即可。
Write()
这是执行此操作的简单实现:
type fwdToZapWriter struct { logger *zap.SugaredLogger } func (fw *fwdToZapWriter) Write(p []byte) (n int, err error) { fw.logger.Errorw(string(p)) return len(p), nil }
就这样。您可以http.Server像这样“安装”该编写器:
http.Server
server := &http.Server{ Addr: addr, Handler: handler, ErrorLog: logger.New(&fwdToZapWriter{logger}, "", 0), }
logger 上面的示例来自您的示例: logger, err := cfg.Build()
logger
logger, err := cfg.Build()
如果你愿意,你可以很容易地转发给你的AppLogger,而不是logger。
AppLogger