我想以自己的格式记录来自net / http的错误。在net / http包中,我发现了Server结构:
type Server struct {
//...
ErrorLog *log.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格式写入。我希望以与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
io.Writer来传递log.Logger
吗?该怎么做?答案 0 :(得分:1)
这很容易实现,因为log.Logger
类型可以确保通过单个Writer.Write()
调用将每条日志消息传递到目标io.Writer
:
每个日志记录操作都会调用Writer的Write方法。一个Logger可以同时从多个goroutines中使用。它保证序列化对Writer的访问。
因此,基本上,您只需要创建一个实现io.Writer
的类型,并且该类型的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
上“安装”该编写器:
server := &http.Server{
Addr: addr,
Handler: handler,
ErrorLog: logger.New(&fwdToZapWriter{logger}, "", 0),
}
上面的示例中的 logger
来自您的示例:logger, err := cfg.Build()
如果需要,您可以轻松地转发到AppLogger
而不是logger
。
看到类似的问题:Go: Create io.Writer inteface for logging to mongodb database
答案 1 :(得分:0)
您可以使用zap.NewStdLog()
来获取*log.Logger
的新实例。
https://godoc.org/go.uber.org/zap#NewStdLog
logger := zap.NewExample()
defer logger.Sync()
std := zap.NewStdLog(logger)
std.Print("standard logger wrapper")
// Output:
// {"level":"info","msg":"standard logger wrapper"}