log包Go标准库的log包提供基础的日志功能,适合简单应用。可配置输出目标(如文件)、日志格式(日期、时间、文件名),但缺乏结构化日志和高级功能(如日志级别过滤)。
示例代码:
package main
import (
"log"
"os"
)
func main() {
logFile, err := os.OpenFile("app.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
if err != nil {
log.Fatal(err)
}
defer logFile.Close()
log.SetOutput(logFile) // 输出到文件
log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile) // 设置日志格式
log.Println("这是一条普通日志")
log.Fatalf("严重错误日志: %s", "错误信息") // 终止程序的错误日志
}
第三方库提供更丰富的功能(如结构化日志、高性能、灵活配置),适合复杂场景:
Logrus:功能全面,支持日志级别(Debug、Info、Warn、Error等)、结构化日志(Fields)、多种输出格式(JSON、Text)。
示例代码:
package main
import (
"github.com/sirupsen/logrus"
)
func main() {
log := logrus.New()
log.SetFormatter(&logrus.JSONFormatter{}) // 结构化输出
log.SetLevel(logrus.DebugLevel) // 设置日志级别
log.WithFields(logrus.Fields{
"animal": "walrus",
"size": 10,
}).Info("A group of walrus emerges from the ocean") // 带字段的日志
}
Zap:Uber开源的高性能日志库,支持异步日志、零分配(部分场景),适合高并发场景。
示例代码:
package main
import (
"go.uber.org/zap"
)
func main() {
logger, err := zap.NewProduction() // 生产环境配置
if err != nil {
panic(err)
}
defer logger.Sync() // 确保日志刷新到磁盘
logger.Info("这是一条普通日志", zap.String("key", "value")) // 结构化日志
logger.Error("这是一条错误日志", zap.Error(fmt.Errorf("模拟错误")))
}
Lumberjack:日志轮转库,需配合其他日志库使用,实现日志文件的自动切割、压缩、备份(如按大小、时间分割)。
示例配置(与Logrus结合):
package main
import (
"github.com/sirupsen/logrus"
"gopkg.in/natefinch/lumberjack.v2"
)
func main() {
logrus.SetOutput(&lumberjack.Logger{
Filename: "/var/log/myapp.log", // 日志文件路径
MaxSize: 10, // 单个文件最大10MB
MaxBackups: 3, // 保留3个备份
MaxAge: 28, // 保留28天
Compress: true, // 压缩备份文件
})
logrus.Info("日志轮转已启用")
}
避免日志文件过大导致磁盘空间耗尽,常用工具:
Logrotate(Debian自带):通过配置文件实现日志的自动切割、压缩、删除。
配置示例(/etc/logrotate.d/myapp):
/path/to/your/app.log {
daily # 每天轮转
rotate 7 # 保留7个备份
compress # 压缩旧日志(gzip)
missingok # 文件不存在时不报错
notifempty # 空文件不轮转
create 0640 root adm # 新日志文件的权限和所有者
}
Lumberjack库:作为代码级解决方案,适合需要更灵活控制的场景(如动态调整轮转参数)。
将Go应用作为systemd服务运行,借助systemd的日志管理功能(journalctl)统一收集、查看日志。
步骤:
/etc/systemd/system/myapp.service):[Unit]
Description=My Golang Application
After=network.target
[Service]
ExecStart=/path/to/your/app
Restart=always # 应用崩溃时自动重启
User=youruser
Group=yourgroup
StandardOutput=syslog # 标准输出重定向到syslog
StandardError=syslog # 标准错误重定向到syslog
SyslogIdentifier=myapp # 日志标识符
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl start myapp
sudo systemctl enable myapp # 开机自启
sudo journalctl -u myapp -f # 实时查看myapp服务的日志
对于分布式系统或需要集中分析的场景,使用ELK(Elasticsearch、Logstash、Kibana)堆栈实现日志的收集、存储、搜索、可视化。
步骤:
sudo apt-get install elasticsearch kibana logstash
sudo systemctl start elasticsearch kibana logstash
/etc/logstash/conf.d/myapp.conf):input {
udp { # 接收GELF格式日志(需Go库支持,如logrus-gelf)
port => 12201
type => "myapp"
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "myapp-%{+YYYY.MM.dd}" # 按日期创建索引
}
}
logrus+gelf库):package main
import (
"github.com/sirupsen/logrus"
"github.com/cespare/gelf"
)
func main() {
gelfWriter, err := gelf.NewWriter("localhost:12201", "myapp", "production", "")
if err != nil {
log.Fatal(err)
}
defer gelfWriter.Close()
logrus.SetOutput(gelfWriter) // 输出到GELF writer
logrus.SetFormatter(&logrus.JSONFormatter{}) // 结构化日志
logrus.Info("This log will be sent to Logstash")
}
以上方法覆盖了Debian系统下Go日志处理的基础到高级场景,可根据应用规模(简单/复杂)、性能需求(低延迟/高吞吐)、管理需求(单机/集中式)选择合适的方案。