在Linux环境下使用Golang开发时,有效的日志管理对于应用程序的监控、调试和运维至关重要。以下是一些实用的日志管理技巧:
import "log"
func main() {
log.Println("Standard log message")
}
Zap (Uber开发,高性能)
import "go.uber.org/zap"
func main() {
logger, _ := zap.NewProduction()
defer logger.Sync()
logger.Info("Zap log message")
}
Logrus (结构化日志)
import log "github.com/sirupsen/logrus"
func main() {
log.SetFormatter(&log.JSONFormatter{})
log.WithFields(log.Fields{
"event": "test",
"topic": "logging",
}).Info("Logrus log message")
}
zerolog (零分配JSON日志)
import "github.com/rs/zerolog/log"
func main() {
log.Info().Str("event", "test").Msg("zerolog message")
}
合理使用不同日志级别: - DEBUG: 开发调试信息 - INFO: 常规运行信息 - WARN: 警告信息 - ERROR: 错误信息 - FATAL: 严重错误导致程序退出
// 使用logrus设置日志级别示例
log.SetLevel(log.DebugLevel)
使用JSON等结构化格式便于后续处理:
// logrus示例
log.SetFormatter(&log.JSONFormatter{})
log.WithFields(log.Fields{
"user": "john",
"action": "login",
"result": "success",
"latency": 150,
}).Info("User login")
import "gopkg.in/natefinch/lumberjack.v2"
func main() {
logger := &lumberjack.Logger{
Filename: "/var/log/myapp.log",
MaxSize: 100, // MB
MaxBackups: 3,
MaxAge: 28, // days
Compress: true,
}
log.SetOutput(logger)
}
创建/etc/logrotate.d/myapp配置文件:
/var/log/myapp.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0640 root root
postrotate
/bin/kill -HUP `cat /var/run/myapp.pid 2>/dev/null` 2>/dev/null || true
endscript
}
// 配置Fluentd输出
logger := &lumberjack.Logger{
Filename: "/var/log/myapp.json.log",
// 其他配置...
}
log.SetOutput(logger)
然后在Fluentd中配置输入:
<source>
@type tail
path /var/log/myapp.json.log
pos_file /var/log/myapp.json.log.pos
tag myapp
format json
</source>
在请求处理中添加请求ID等上下文信息:
func handleRequest(w http.ResponseWriter, r *http.Request) {
requestID := r.Header.Get("X-Request-ID")
if requestID == "" {
requestID = generateRequestID()
}
logger := log.WithFields(log.Fields{
"request_id": requestID,
"path": r.URL.Path,
"method": r.Method,
})
logger.Info("Request started")
// 处理请求...
logger.Info("Request completed")
}
// zerolog性能优化示例
logger := zerolog.New(os.Stdout).With().Timestamp().Logger()
logger.Info().Str("key", "value").Msg("message")
type SanitizingHook struct{}
func (h *SanitizingHook) Fire(entry *log.Entry) error {
if password, ok := entry.Data["password"]; ok {
entry.Data["password"] = "******"
}
return nil
}
func (h *SanitizingHook) Levels() []log.Level {
return log.AllLevels
}
func main() {
log.AddHook(&SanitizingHook{})
// ...
}
func main() {
file, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatal(err)
}
multiWriter := io.MultiWriter(os.Stdout, file)
log.SetOutput(multiWriter)
log.Println("This will go to both stdout and the file")
}
通过以上技巧,您可以在Linux环境下构建高效、可维护的Golang日志管理系统。