centos

CentOS上Golang日志如何优化

小樊
38
2025-12-13 16:44:18
栏目: 编程语言

CentOS 上 Golang 日志优化实践

一 核心优化策略

二 库与方案选型对比

维度 slog(标准库) zap(Uber) zerolog logrus
结构化 原生 key=value 结构化强,支持 Sugared 强制结构化(链式 API) 支持 Fields
性能 中等 极高 极高(零分配倾向) 中等
依赖 第三方 第三方 第三方
动态级别 需自定义 Handler 原生 AtomicLevel 支持 Level 接口 支持 SetLevel
适用场景 新项目、少依赖 高并发/性能敏感 极致性能/内存敏感 旧项目兼容

选型建议:新项目优先 slogzap;极致性能选 zerolog;存量项目可在保留 logrus 的同时逐步迁移到 zap/slog

三 落地配置示例

package main

import (
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
	"os"
)

func NewZapLogger(logPath string, level zapcore.Level) *zap.Logger {
	encCfg := zapcore.EncoderConfig{
		TimeKey:    "ts",
		LevelKey:   "level",
		CallerKey:  "caller",
		MessageKey: "msg",
		EncodeLevel: zapcore.CapitalLevelEncoder,
		EncodeTime: zapcore.ISO8601TimeEncoder,
		EncodeCaller: zapcore.ShortCallerEncoder,
	}
	core := zapcore.NewCore(
		zapcore.NewJSONEncoder(encCfg),
		zapcore.AddSync(&lumberjack.Logger{
			Filename:   logPath,
			MaxSize:    100,     // MB
			MaxBackups: 7,       // 保留个数
			MaxAge:     28,      // 天
			Compress:   true,    // 压缩旧日志
		}),
		level,
	)
	return zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel))
}

func main() {
	logger := NewZapLogger("./logs/app.log", zap.InfoLevel)
	defer logger.Sync()

	logger.Info("service started", zap.String("version", "1.2.3"))
}
// 级别控制:AtomicLevel 可在运行时调整
level := zap.NewAtomicLevelAt(zap.InfoLevel)

// 多输出:控制台(开发友好)+ 文件(生产归档)
consoleEnc := zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig())
fileEnc := zapcore.NewJSONEncoder(zap.NewProductionEncoderConfig())

console := zapcore.Lock(os.Stdout)
file := zapcore.AddSync(&lumberjack.Logger{
	Filename: "./logs/app.log", MaxSize: 100, MaxBackups: 7, MaxAge: 28, Compress: true,
})

core := zapcore.NewTee(
	zapcore.NewCore(consoleEnc, console, level),
	zapcore.NewCore(fileEnc, file, level),
)

logger := zap.New(core, zap.AddCaller())
defer logger.Sync()
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    missingok
    notifempty
    copytruncate
    dateext
}
# 建议:systemd 服务使用 StandardOutput=null; StandardError=journal+console
# 以避免与文件写入竞争

提示:在容器中优先让进程直接写文件并使用 lumberjack;在虚拟机/物理机上可叠加 logrotate 做合规归档。

四 系统层面优化

五 排查与优化清单

0
看了该问题的人还看了