Golang 日誌實時告警實現方案(Windows-Linux-Debian)
在 Golang 中實現跨平臺的日誌實時告警,可以通過以下幾種方式實現:
通用實現方案
1. 使用日誌監控庫
package main
import(
"log"
"os"
"time"
"github.com/hpcloud/tail"// 跨平臺文件跟蹤
"github.com/robfig/cron"// 定時任務
)
funcsetupLogMonitor(logPath string){
t, err := tail.TailFile(logPath, tail.Config{
Follow:true,
ReOpen:true,
Location:&tail.SeekInfo{Offset:0, Whence: os.SEEK_END},
})
if err !=nil{
log.Fatal(err)
}
for line :=range t.Lines {
ifshouldAlert(line.Text){
sendAlert(line.Text)
}
}
}
funcshouldAlert(logLine string)bool{
// 實現你的告警邏輯,如匹配錯誤關鍵詞
return strings.Contains(logLine,"ERROR")||
strings.Contains(logLine,"FATAL")
}
funcsendAlert(message string){
// 實現告警發送邏輯,如:
// - 發送郵件
// - 調用Webhook
// - 發送Slack/Teams消息
log.Println("ALERT:", message)
}
2. 使用系統日誌服務
Linux/Debian (syslog)
package main
import(
"log"
"log/syslog"
)
funcsetupSyslogAlert(){
sysLog, err := syslog.New(syslog.LOG_ALERT,"myapp")
if err !=nil{
log.Fatal(err)
}
// 重定向標準日誌
log.SetOutput(sysLog)
// 自定義告警
log.Println("Application started")// 普通日誌
sysLog.Alert("Critical error detected!")// 告警級別日誌
}
Windows (Event Log)
package main
import(
"golang.org/x/sys/windows/svc/eventlog"
"log"
)
funcsetupWindowsEventLog(){
el, err := eventlog.Open("MyApplication")
if err !=nil{
log.Fatal(err)
}
defer el.Close()
el.Info(1,"Application started")
el.Error(2,"Critical error detected!")
}
平臺特定實現
Linux/Debian 方案
使用 inotify (Linux 特有)
package main
import(
"github.com/fsnotify/fsnotify"
"log"
)
funcinotifyLogMonitor(logPath string){
watcher, err := fsnotify.NewWatcher()
if err !=nil{
log.Fatal(err)
}
defer watcher.Close()
err = watcher.Add(logPath)
if err !=nil{
log.Fatal(err)
}
for{
select{
case event :=<-watcher.Events:
if event.Op&fsnotify.Write == fsnotify.Write {
// 讀取新增內容並檢查是否需要告警
}
case err :=<-watcher.Errors:
log.Println("Watcher error:", err)
}
}
}
使用 logrotate + 自定義腳本
Windows 方案
使用 Windows 事件日誌過濾器
// 結合前面的Windows事件日誌代碼
// 可以配置Windows任務計劃程序對特定事件ID觸發告警
使用 Windows 性能計數器
高級集成方案
1. 與監控系統集成
// 使用Prometheus客戶端
import(
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/push"
)
var errorCounter = prometheus.NewCounter(
prometheus.CounterOpts{
Name:"app_errors_total",
Help:"Total number of application errors",
},
)
funcinit(){
prometheus.MustRegister(errorCounter)
}
funcsendPrometheusAlert(){
// 當檢測到錯誤時
errorCounter.Inc()
// 推送到Prometheus Pushgateway
err := push.New("http://pushgateway:9091","myapp_job").
Collector(errorCounter).
Push()
if err !=nil{
log.Println("Could not push to Pushgateway:", err)
}
}
2. 使用 ELK Stack 或類似方案
// 使用Elasticsearch Go客戶端
import(
"context"
"github.com/elastic/go-elasticsearch/v8"
)
funcsendToElasticsearch(logData string){
cfg := elasticsearch.Config{
Addresses:[]string{"http://localhost:9200"},
}
es, err := elasticsearch.NewClient(cfg)
if err !=nil{
log.Fatal(err)
}
_, err = es.Index(
"app-logs",
strings.NewReader(logData),
es.Index.WithContext(context.Background()),
)
if err !=nil{
log.Println("Elasticsearch indexing error:", err)
}
}
部署建議
Linux/Debian
-
使用 systemd 服務單元文件配置日誌監控
-
結合 syslog-ng 或 rsyslog 進行高級日誌處理
-
考慮使用 fail2ban 對特定日誌模式觸發動作
Windows
-
創建 Windows 服務來運行監控程序
-
使用任務計劃程序對特定事件觸發告警
-
考慮使用 Windows 性能警報
注意事項
跨平臺兼容性考慮:
-
文件路徑分隔符 (
/
vs\
) -
行尾符 (
\n
vs\r\n
) -
文件鎖定機制差異
性能考慮:
-
對於高吞吐量日誌,考慮批處理告警
-
使用緩衝通道處理日誌行
安全性:
-
確保日誌文件權限適當
-
對敏感日誌信息進行脫敏處理
以上方案可以根據實際需求組合使用,構建適合您環境的實時日誌告警系統。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/Kcyt1hhIs2y_iQllEQoOug