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日志處理的基礎到高級場景,可根據應用規模(簡單/復雜)、性能需求(低延遲/高吞吐)、管理需求(單機/集中式)選擇合適的方案。