隨著業務的不斷發展,系統日誌和稽核日誌的重要性也越來越高。日誌記錄系統的長遠發展需要一個高效可靠的技術,同時也需要足夠的靈活性和可擴展性。近年來,golang作為一門高效率的程式語言,其在日誌稽核方面也展現了獨特的優勢,本文就來介紹一下golang實現日誌稽核的方法。
一、golang在日誌審計中的優勢
1.協程
golang擁有協程(goroutine)的特性,能夠輕鬆地創建大量的並發執行程序,這使得其能夠保證高並發流量下的資料安全和完整性,避免了多執行緒下的各種繁瑣和危險因素。
2.垃圾回收機制
golang擁有自己的垃圾回收機制,能夠自動管理記憶體。這個機制不僅解決了記憶體洩漏的問題,同時也減少了程式設計師對記憶體的管理和處理,提高了程式設計的效率。
3.跨平台性
golang的程式碼能夠跨平台編譯,十分方便。同時golang也支援多種作業系統,包括Windows、Linux、macOS等主流作業系統,能夠滿足不同平台下的需求。
4.效能最佳化
golang的效能非常優秀,它的速度和執行效率比其他語言都要高。這意味著可以在高並發下不降低系統效能,確保介面的反應速度,提高系統的可用性和穩定性。
二、golang實作日誌稽核具體方法
1.日誌系統的設計
golang實作日誌稽核一般需要考慮以下幾個面向:
2.使用logrus庫實作日誌
在golang中,logrus是一款非常流行的日誌框架,支援多種日誌輸出方式,並提供了豐富的API接口。簡單來說,logrus 是一個日誌庫,能夠提供高度可自訂的日誌方案。
logrus支援以下幾種等級的日誌輸出:
使用logrus能夠方便地實現對日誌的記錄、輸出和管理,例如我們可以自訂輸出格式、輸出等級、輸出給檔案、輸出給另一台機器等等。這種靈活性使得golang成為了日誌審計的理想選擇。
3.實作稽核日誌系統
下面我們來實作一個簡單的稽核日誌系統。這個系統可以實現記錄使用者的操作日誌,並儲存在資料庫中,以便於管理員進行稽核。
首先,建構golang的web服務環境,我們可以使用gorilla/mux這個第三方函式庫來處理路由。實作路由之後,我們需要為每個介面定義不同的handler函數,如登入、登出、查詢等。
在處理完每個介面之後,我們來實作稽核日誌的記錄。我們可以使用logrus函式庫來記錄日誌,先定義一個日誌處理器,可以把日誌輸出到控制台或其它外部檔案。
logrus.SetLevel(logrus.TraceLevel)
logrus.SetOutput(os.Stdout)
然後,在處理介面的過程中,我們需要記錄每個使用者的操作,具體應該怎麼記錄呢?可以透過定義一個日誌格式範本和日誌對象,來實現使用者操作的記錄。我們在定義日誌時,將記錄使用者登入的使用者名稱和ip位址,以及存取的介面和請求方法。這樣就能非常方便地實現審計日誌的記錄了。
日誌物件定義:
type AuditLog struct {
ID uint64 Username string IPAddress string Method string Path string CreatedAt time.Time
}
日誌格式化:
func (auditLog *AuditLog) String() string {
// format the log into json format buf := bytes.NewBuffer(nil) // begin log format buf.WriteString("{") buf.WriteString(fmt.Sprintf(""id":"%d",", auditLog.ID)) buf.WriteString(fmt.Sprintf(""username":"%s",", auditLog.Username)) buf.WriteString(fmt.Sprintf(""ip_address":"%s",", auditLog.IPAddress)) buf.WriteString(fmt.Sprintf(""method":"%s",", auditLog.Method)) buf.WriteString(fmt.Sprintf(""path":"%s",", auditLog.Path)) buf.WriteString(fmt.Sprintf(""created_at":%d", auditLog.CreatedAt.Unix())) // end log format buf.WriteString("}") return buf.String()
}
#記錄稽核日誌:
func AuditingLogMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { start := time.Now() var username string var ok bool // 根据实际场景修改,这里以token作为身份认证方式 if token := r.Header.Get("Authorization"); token != "" { tokenParts := strings.Split(token, " ") if len(tokenParts) == 2 { tokenType := tokenParts[0] tokenContent := tokenParts[1] // 根据实际场景修改,这里假设发放的Token为JWT if tokenType == "Bearer" { claims, err := util.ParseJwtToken(util.JwtKey, tokenContent) if err == nil { username, ok = claims["username"].(string) } } } } // 添加审计日志 auditLog := &AuditLog{ Username: username, // 登录的用户名 IPAddress: r.RemoteAddr, // 客户端IP地址 Method: r.Method, // http请求类型(GET、POST、PUT、DELETE……) Path: r.URL.Path, // 请求的URL路径 CreatedAt: time.Now(), // 日志创建时间 } logrus.Trace(auditLog) // Call the next handler, which can be another middleware in the chain, or the final handler. next.ServeHTTP(w, r) // 审计log耗时 end := time.Now() diff := end.Sub(start) logrus.Tracef("log time to response: %dms", int64(diff/time.Millisecond)) })
}
記錄日誌之後,我們需要將日誌寫入資料庫。這裡我們假設使用了gorm作為ORM框架,對資料庫進行操作。
GORM是一個對於SQL資料庫的輕量級ORM函式庫,支援MySQL、PostgreSQL、Sqlite3等幾種資料庫。
func DatabaseUri(user, password, database, host, port string) string {
return fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local", user, password, host, port, database)
}
func SetupDB() error {
var err error dbUri := DatabaseUri("root", "", "log_audit", "localhost", "3306") db, err = gorm.Open(mysql.Open(dbUri), &gorm.Config{ Logger: &logger.Default{}, }) if err != nil { panic("failed to connect database") } // 定义migration 操作等 return nil
}
記得在main函數中先呼叫SetupDB,因為它是操作資料庫的初始化函數,你需要確保在對資料庫進行操作之前先連接上它。
呼叫AuditLogMiddleware的函數需要被註冊到服務路由中,根據需要滿足不同審核需求,判斷到業務需求需要將同步寫入的以kafka,nats,nsq等可靠訊息佇列中,以便做後續異步處理。
至此,golang實作日誌稽核就完成了。透過以上的方法,我們可以在golang中實現一個高效、可靠的日誌系統和審計模組,為我們的業務開發打下堅實的基礎,也能夠更好地保證系統的可靠性和安全性。
以上是golang實作日誌審計的詳細內容。更多資訊請關注PHP中文網其他相關文章!