首頁 > 後端開發 > Golang > 主體

golang實作日誌審計

WBOY
發布: 2023-05-15 10:39:37
原創
1040 人瀏覽過

隨著業務的不斷發展,系統日誌和稽核日誌的重要性也越來越高。日誌記錄系統的長遠發展需要一個高效可靠的技術,同時也需要足夠的靈活性和可擴展性。近年來,golang作為一門高效率的程式語言,其在日誌稽核方面也展現了獨特的優勢,本文就來介紹一下golang實現日誌稽核的方法。

一、golang在日誌審計中的優勢

1.協程

golang擁有協程(goroutine)的特性,能夠輕鬆地創建大量的並發執行程序,這使得其能夠保證高並發流量下的資料安全和完整性,避免了多執行緒下的各種繁瑣和危險因素。

2.垃圾回收機制

golang擁有自己的垃圾回收機制,能夠自動管理記憶體。這個機制不僅解決了記憶體洩漏的問題,同時也減少了程式設計師對記憶體的管理和處理,提高了程式設計的效率。

3.跨平台性

golang的程式碼能夠跨平台編譯,十分方便。同時golang也支援多種作業系統,包括Windows、Linux、macOS等主流作業系統,能夠滿足不同平台下的需求。

4.效能最佳化

golang的效能非常優秀,它的速度和執行效率比其他語言都要高。這意味著可以在高並發下不降低系統效能,確保介面的反應速度,提高系統的可用性和穩定性。

二、golang實作日誌稽核具體方法

1.日誌系統的設計

golang實作日誌稽核一般需要考慮以下幾個面向:

  • 日誌記錄格式化:日誌系統需要能夠解析日誌記錄,並根據指定的格式進行轉換並儲存。
  • 資料庫操作:透過使用golang的ORM框架,我們能夠很方便地操作資料庫,方便地儲存和讀取資料。
  • 身份驗證:在日誌審計系統中,需要進行身份驗證,才能對某些操作進行審計。
  • 日誌查詢:針對日誌系統的查詢需求,需要考慮如何設計合理的查詢條件和查詢方式。
  • 日誌儲存:需要選擇合適的儲存方式,從而確保日誌資料的完整性和安全性。

2.使用logrus庫實作日誌

在golang中,logrus是一款非常流行的日誌框架,支援多種日誌輸出方式,並提供了豐富的API接口。簡單來說,logrus 是一個日誌庫,能夠提供高度可自訂的日誌方案。

logrus支援以下幾種等級的日誌輸出:

  • trace
  • #debug
  • info
  • warn
  • error
  • fatal
  • panic

使用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中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板