Golang HTTP日志工具 - 基于Gorilla Handlers的可组合HTTP记录器
Golang HTTP日志工具 - 基于Gorilla Handlers的可组合HTTP记录器
GitHub: https://github.com/lassik/go-httplog
GoDoc: https://godoc.org/github.com/lassik/go-httplog
这是一个可组合的 HTTP 日志记录库。它不会强制规定你应如何记录日志,而是提供一套工具集来帮助你构建自己的日志记录器。你可以使用喜欢的部分,忽略其余部分。
- 它基于包含 HTTP 请求解析信息的
LogRequest结构体。 LogHandler中间件允许你记录任何 HTTP 请求。你只需提供一个接收LogRequest的函数,该函数可以按任意方式格式化和写入日志条目。- 要格式化日志条目,你可以使用
CommonLogLine或CombinedLogLine函数。自定义格式化也很容易:LogRequest应包含你需要的所有信息。
该库的核心部分提取自 Gorilla Handlers 包。此日志记录库与框架无关,不依赖 Gorilla 或 Go 标准库之外的任何其他组件。
更多关于Golang HTTP日志工具 - 基于Gorilla Handlers的可组合HTTP记录器的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于Golang HTTP日志工具 - 基于Gorilla Handlers的可组合HTTP记录器的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个非常实用的HTTP日志记录库,它基于Gorilla Handlers的设计理念,提供了灵活的可组合性。让我通过示例代码来展示如何使用它:
package main
import (
"log"
"net/http"
"os"
"github.com/lassik/go-httplog"
)
// 自定义日志格式函数
func customLogger(req httplog.LogRequest) {
log.Printf("[%s] %s %s %d %d",
req.StartTime.Format("2006-01-02 15:04:05"),
req.Method,
req.URL.Path,
req.StatusCode,
req.Size)
}
func main() {
// 创建基础handler
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello, World!"))
})
// 使用Common Log Format
commonLogHandler := httplog.LogHandler(handler, func(req httplog.LogRequest) {
log.Println(httplog.CommonLogLine(req))
})
// 使用Combined Log Format
combinedLogHandler := httplog.LogHandler(handler, func(req httplog.LogRequest) {
log.Println(httplog.CombinedLogLine(req))
})
// 使用自定义日志格式
customLogHandler := httplog.LogHandler(handler, customLogger)
// 启动多个服务器演示不同格式
go func() {
log.Println("Common Log Format server starting on :8080")
http.ListenAndServe(":8080", commonLogHandler)
}()
go func() {
log.Println("Combined Log Format server starting on :8081")
http.ListenAndServe(":8081", combinedLogHandler)
}()
log.Println("Custom Format server starting on :8082")
http.ListenAndServe(":8082", customLogHandler)
}
更复杂的自定义日志记录示例:
package main
import (
"encoding/json"
"net/http"
"time"
"github.com/lassik/go-httplog"
)
type JSONLogEntry struct {
Timestamp string `json:"timestamp"`
Method string `json:"method"`
Path string `json:"path"`
Status int `json:"status"`
Duration int64 `json:"duration_ms"`
UserAgent string `json:"user_agent"`
RemoteAddr string `json:"remote_addr"`
}
func jsonLogger(req httplog.LogRequest) {
entry := JSONLogEntry{
Timestamp: req.StartTime.Format(time.RFC3339),
Method: req.Method,
Path: req.URL.Path,
Status: req.StatusCode,
Duration: req.Duration.Nanoseconds() / 1e6,
UserAgent: req.UserAgent(),
RemoteAddr: req.RemoteAddr,
}
if jsonData, err := json.Marshal(entry); err == nil {
println(string(jsonData))
}
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte(`{"message": "success"}`))
})
mux.HandleFunc("/api/users", func(w http.ResponseWriter, r *http.Request) {
time.Sleep(100 * time.Millisecond) // 模拟处理时间
w.WriteHeader(http.StatusCreated)
w.Write([]byte(`{"id": 123}`))
})
// 包装handler进行JSON格式日志记录
loggedHandler := httplog.LogHandler(mux, jsonLogger)
http.ListenAndServe(":3000", loggedHandler)
}
与现有日志库集成示例:
package main
import (
"net/http"
"github.com/lassik/go-httplog"
"github.com/sirupsen/logrus"
)
func setupLogrusLogger() func(httplog.LogRequest) {
logger := logrus.New()
logger.SetFormatter(&logrus.JSONFormatter{})
return func(req httplog.LogRequest) {
logger.WithFields(logrus.Fields{
"method": req.Method,
"path": req.URL.Path,
"status": req.StatusCode,
"duration_ms": req.Duration.Seconds() * 1000,
"user_agent": req.UserAgent(),
"remote_addr": req.RemoteAddr,
}).Info("http_request")
}
}
func main() {
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Logged with Logrus!"))
})
logrusLogger := setupLogrusLogger()
loggedHandler := httplog.LogHandler(handler, logrusLogger)
http.ListenAndServe(":8080", loggedHandler)
}
这个库的核心优势在于其可组合性,你可以轻松地集成到任何现有的HTTP服务器中,并使用任何你喜欢的日志格式或日志库。LogRequest结构体提供了完整的请求上下文信息,使得自定义日志格式变得非常简单直接。

