net/http设置自定义记录器 [英] net/http set custom logger

查看:78
本文介绍了net/http设置自定义记录器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想以自己的格式记录来自net/http的错误.在net/http包中,我找到了服务器结构:

I would like to log errors from net/http in my own format. In net/http package I have found Server struct:

type Server struct {
        //...
        ErrorLog *log.Logger
}

我想用自己的实现替代记录器:

I would like to substitute logger with my own implementation:

type AppLogger struct {
    log *zap.SugaredLogger
}

func (l *AppLogger) Error(message string, keyAndValues ...interface{}) {
    l.log.Errorw(message, keyAndValues...)
}

实现此目标的正确方法是什么?

What is the correct way of implementing this?

更新:

我有 zap 记录器,其配置如下:

I have zap logger with following config:

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中的错误.我创建以下内容:

It configured to write in json format. I would like errors from net/http be written in the same way as zap. I create following:

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"}}
}

问题:

  1. serverJsonWriter方法的主体应该是什么?
  2. 我应该检索zap io.Writer以便将其传递给log.Logger吗?该怎么做?
  1. What should be the body of serverJsonWriter method?
  2. Should I retrieve zap io.Writer in order to pass it log.Logger? How to do this?

推荐答案

这很容易实现,因为 log.Logger 类型保证将每个日志消息传递到目标 io.Writer 和一个Writer.Write()调用:

This is easily doable, because the log.Logger type guarantees that each log message is delivered to the destination io.Writer with a single Writer.Write() call:

每个日志记录操作都会调用Writer的Write方法.一个Logger可以从多个goroutines中同时使用.它保证序列化对Writer的访问.

Each logging operation makes a single call to the Writer's Write method. A Logger can be used simultaneously from multiple goroutines; it guarantees to serialize access to the Writer.

因此,基本上,您只需要创建一个实现io.Writer的类型,并且该类型的Write()方法仅调用记录器即可.

So basically you just need to create a type which implements io.Writer, and whose Write() method simply calls your logger.

这是一个简单的实现,可以实现:

Here's a simple implementation which does that:

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上安装"该编写器:

And that's all. You can "install" this writer at your http.Server like this:

server := &http.Server{
    Addr:     addr,
    Handler:  handler,
    ErrorLog: logger.New(&fwdToZapWriter{logger}, "", 0),
}

上面的示例中的

logger来自您的示例:logger, err := cfg.Build()

logger in the above example is from your example: logger, err := cfg.Build()

如果需要,您可以轻松地转发到AppLogger而不是logger.

If you want, you can just as easily forward to your AppLogger instead of logger.

看到类似的问题:转到:创建io.Writer接口以登录到mongodb数据库

这篇关于net/http设置自定义记录器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆