代码之家  ›  专栏  ›  技术社区  ›  RudziankoÅ­

net/http设置自定义记录器

  •  1
  • RudziankoÅ­  · 技术社区  · 6 年前

    我想用我自己的格式记录来自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()
    

    net/http 以与zap相同的方式书写。我创建了以下内容:

    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.编写器为了通过考试 log.Logger
    1 回复  |  直到 6 年前
        1
  •  3
  •   icza    6 年前

    log.Logger io.Writer 用一个 Writer.Write() 电话:

    所以基本上你只需要创建一个实现 io.编写器 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 记录器

    见类似问题: Go: Create io.Writer inteface for logging to mongodb database

        2
  •  0
  •   Xeoncross    5 年前

    你可以用 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"}