登录
首页 >  Golang >  Go问答

在 go 中如何仅记录特定的错误,如 404?

来源:stackoverflow

时间:2024-02-07 09:06:19 312浏览 收藏

来到golang学习网的大家,相信都是编程学习爱好者,希望在这里学习Golang相关编程知识。下面本篇文章就来带大家聊聊《在 go 中如何仅记录特定的错误,如 404?》,介绍一下,希望对大家的知识积累有所帮助,助力实战开发!

问题内容

我将 chi 与我们的 go web 服务一起使用。

如何配置记录器 (middleware),使其仅记录最终出现错误的请求(如 404),但不记录成功的请求(状态代码为 200)?

这是我们当前的实现(根本没有日志记录)

r := chi.NewRouter()

if DEBUG_LOGS {
    r.Use(middleware.Logger)
} else {

}

正确答案


最简单的方法是使用 chi 包中的示例自行实现日志记录功能(为简单起见,我删除了颜色)。

package main

import (
    "bytes"
    "fmt"
    "log"
    "net/http"
    "os"
    "time"

    "github.com/go-chi/chi/v5"
    "github.com/go-chi/chi/v5/middleware"
)

const DEBUG_LOGS = true

func main() {
    api := &http.Server{Addr: ":8000"}

    r := chi.NewRouter()

    if DEBUG_LOGS {
        // create default logger/zerolog/logrus
        logger := log.New(os.Stdout, "", log.LstdFlags)
        r.Use(middleware.RequestLogger(&StructuredLogger{logger}))
    }

    r.Get("/tea", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusTeapot) })
    r.Get("/ok", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })

    api.Handler = r

    err := api.ListenAndServe()
    if err != nil {
        log.Fatal(err)
    }
}

// below is the implementation of the custom logger.

type StructuredLogger struct {
    Logger middleware.LoggerInterface
}

type LogEntry struct {
    *StructuredLogger
    request  *http.Request
    buf      *bytes.Buffer
    useColor bool
}

func (l *StructuredLogger) NewLogEntry(r *http.Request) middleware.LogEntry {
    entry := &LogEntry{
        StructuredLogger: l,
        request:          r,
        buf:              &bytes.Buffer{},
        useColor:         false,
    }

    reqID := middleware.GetReqID(r.Context())
    if reqID != "" {
        fmt.Fprintf(entry.buf, "[%s] ", reqID)
    }

    fmt.Fprintf(entry.buf, "\"")
    fmt.Fprintf(entry.buf, "%s ", r.Method)

    scheme := "http"
    if r.TLS != nil {
        scheme = "https"
    }
    fmt.Fprintf(entry.buf, "%s://%s%s %s\" ", scheme, r.Host, r.RequestURI, r.Proto)

    entry.buf.WriteString("from ")
    entry.buf.WriteString(r.RemoteAddr)
    entry.buf.WriteString(" - ")

    return entry
}

func (l *LogEntry) Write(status, bytes int, header http.Header, elapsed time.Duration, extra interface{}) {
    // Do nothing if status code is 200/201/eg
    if status < 300 {
        return
    }

    fmt.Fprintf(l.buf, "%03d", status)
    fmt.Fprintf(l.buf, " %dB", bytes)

    l.buf.WriteString(" in ")
    if elapsed < 500*time.Millisecond {
        fmt.Fprintf(l.buf, "%s", elapsed)
    } else if elapsed < 5*time.Second {
        fmt.Fprintf(l.buf, "%s", elapsed)
    } else {
        fmt.Fprintf(l.buf, "%s", elapsed)
    }

    l.Logger.Print(l.buf.String())
}

func (l *LogEntry) Panic(v interface{}, stack []byte) {
    middleware.PrintPrettyStack(v)
}

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>