首頁 後端開發 Golang golang實作日誌審計

golang實作日誌審計

May 15, 2023 am 10:39 AM

隨著業務的不斷發展,系統日誌和稽核日誌的重要性也越來越高。日誌記錄系統的長遠發展需要一個高效可靠的技術,同時也需要足夠的靈活性和可擴展性。近年來,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中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Debian OpenSSL有哪些漏洞 Debian OpenSSL有哪些漏洞 Apr 02, 2025 am 07:30 AM

OpenSSL,作為廣泛應用於安全通信的開源庫,提供了加密算法、密鑰和證書管理等功能。然而,其歷史版本中存在一些已知安全漏洞,其中一些危害極大。本文將重點介紹Debian系統中OpenSSL的常見漏洞及應對措施。 DebianOpenSSL已知漏洞:OpenSSL曾出現過多個嚴重漏洞,例如:心臟出血漏洞(CVE-2014-0160):該漏洞影響OpenSSL1.0.1至1.0.1f以及1.0.2至1.0.2beta版本。攻擊者可利用此漏洞未經授權讀取服務器上的敏感信息,包括加密密鑰等。

從前端轉型後端開發,學習Java還是Golang更有前景? 從前端轉型後端開發,學習Java還是Golang更有前景? Apr 02, 2025 am 09:12 AM

後端學習路徑:從前端轉型到後端的探索之旅作為一名從前端開發轉型的後端初學者,你已經有了nodejs的基礎,...

Beego ORM中如何指定模型關聯的數據庫? Beego ORM中如何指定模型關聯的數據庫? Apr 02, 2025 pm 03:54 PM

在BeegoORM框架下,如何指定模型關聯的數據庫?許多Beego項目需要同時操作多個數據庫。當使用Beego...

Go語言中用於浮點數運算的庫有哪些? Go語言中用於浮點數運算的庫有哪些? Apr 02, 2025 pm 02:06 PM

Go語言中用於浮點數運算的庫介紹在Go語言(也稱為Golang)中,進行浮點數的加減乘除運算時,如何確保精度是�...

Go的爬蟲Colly中Queue線程的問題是什麼? Go的爬蟲Colly中Queue線程的問題是什麼? Apr 02, 2025 pm 02:09 PM

Go爬蟲Colly中的Queue線程問題探討在使用Go語言的Colly爬蟲庫時,開發者常常會遇到關於線程和請求隊列的問題。 �...

在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? 在Go語言中使用Redis Stream實現消息隊列時,如何解決user_id類型轉換問題? Apr 02, 2025 pm 04:54 PM

Go語言中使用RedisStream實現消息隊列時類型轉換問題在使用Go語言與Redis...

GoLand中自定義結構體標籤不顯示怎麼辦? GoLand中自定義結構體標籤不顯示怎麼辦? Apr 02, 2025 pm 05:09 PM

GoLand中自定義結構體標籤不顯示怎麼辦?在使用GoLand進行Go語言開發時,很多開發者會遇到自定義結構體標籤在�...

在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? 在 Go 語言中,為什麼使用 Println 和 string() 函數打印字符串會出現不同的效果? Apr 02, 2025 pm 02:03 PM

Go語言中字符串打印的區別:使用Println與string()函數的效果差異在Go...

See all articles