詳解MongoDB?Go?Driver如何記錄日志
引言
如果你有這些問(wèn)題:
- golang 官方的 mongo driver 怎么執(zhí)行了沒(méi)有日志輸出啊
- golang mongo driver 如何記錄sql,如何打印執(zhí)行的命令
- 想通過(guò)日志來(lái)檢查 golang mongo 調(diào)用API是否符合預(yù)期
那么這篇文章可以繼續(xù)看下去。
背景
在這之前我使用 MySQL
是比較多的,后來(lái)遇到有記錄用戶操作日志需求,隨著數(shù)據(jù)量越來(lái)越大,MySQL
有些扛不?。?,就換成了 Mongo
,在使用Mongo
過(guò)程中,發(fā)現(xiàn)沒(méi)法記錄日志,就是無(wú)法將打印代碼發(fā)起的sql
,之前使用gorm
打印execute sql
是很方便的。
在網(wǎng)上查了好久也沒(méi)查到相關(guān)資料,就開(kāi)始翻官方文檔,和源碼。
終于在不懈~ 打住,其實(shí)很簡(jiǎn)單,就在 ClientOptions
字段里:
// ClientOptions contains options to configure a Client instance. Each option can be set through setter functions. See // documentation for each setter function for an explanation of the option. type ClientOptions struct { AppName *string Auth *Credential AutoEncryptionOptions *AutoEncryptionOptions ... MaxConnecting *uint64 PoolMonitor *event.PoolMonitor Monitor *event.CommandMonitor // 執(zhí)行的命令監(jiān)視器(日志) ServerMonitor *event.ServerMonitor ... err error uri string cs *connstring.ConnString
ClientOptions.Monitor字段
使用方法如下:
package mongolearn import ( "context" "fmt" "log" "time" "go.mongodb.org/mongo-driver/bson" "go.mongodb.org/mongo-driver/event" "go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo/options" ) var ( mongoDsn = "mongodb://admin:123456@127.0.0.1:27017" ) // TestConnUseDb sql monitor func TestConnWithMonitor() { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() // client option var clientOpt = options.Client().ApplyURI(mongoDsn) // log monitor var logMonitor = event.CommandMonitor{ Started: func(ctx context.Context, startedEvent *event.CommandStartedEvent) { log.Printf("mongo reqId:%d start on db:%s cmd:%s sql:%+v", startedEvent.RequestID, startedEvent.DatabaseName, startedEvent.CommandName, startedEvent.Command) }, Succeeded: func(ctx context.Context, succeededEvent *event.CommandSucceededEvent) { log.Printf("mongo reqId:%d exec cmd:%s success duration %d ns", succeededEvent.RequestID, succeededEvent.CommandName, succeededEvent.DurationNanos) }, Failed: func(ctx context.Context, failedEvent *event.CommandFailedEvent) { log.Printf("mongo reqId:%d exec cmd:%s failed duration %d ns", failedEvent.RequestID, failedEvent.CommandName, failedEvent.DurationNanos) }, } // cmd monitor set clientOpt.SetMonitor(&logMonitor) client, err := mongo.Connect(ctx, clientOpt) if nil != err { fmt.Printf("mongo connect err %v\n", err) } else { fmt.Printf("mongo connect success~\n") defer func() { if err = client.Disconnect(ctx); err != nil { panic(err) } }() } // update test if re, err := client.Database("test").Collection("test").UpdateOne(ctx, bson.M{"name": "cc"}, bson.M{"$set": bson.M{"age": 12}}); err != nil { log.Printf("%v", err) } else { log.Printf("mongo update one re %+v", re) } }
輸出結(jié)果
mongo connect success~
2023/08/20 13:22:43 mongo reqId:6 start on db:test cmd:update sql:{"update": "test","ordered": true,"lsid": {"id": {"$binary":{"base64":"qfrrzSt7SkCN5ChY04/T5A==","subType":"04"}}},"$db": "test","updates": [{"q": {"name": "cc"},"u": {"$set": {"age": {"$numberInt":"12"}}}}]}
2023/08/20 13:22:43 mongo reqId:6 exec cmd:update success duration 44489114 ns
2023/08/20 13:22:43 mongo update one re &{MatchedCount:0 ModifiedCount:0 UpsertedCount:0 UpsertedID:<nil>}
# 下面是斷開(kāi) mongo 時(shí)觸發(fā)的命令
2023/08/20 13:22:43 mongo reqId:7 start on db:admin cmd:endSessions sql:{"endSessions": [{"id": {"$binary":{"base64":"qfrrzSt7SkCN5ChY04/T5A==","subType":"04"}}}],"$db": "admin"}
2023/08/20 13:22:43 mongo reqId:7 exec cmd:endSessions success duration 58037162 ns
通過(guò)以上日志可以看到,mongo
的 monitor
按照 Started
, Succeeded
順序記錄,最后才會(huì)執(zhí)行函數(shù)外的 日志 。
以上就是詳解MongoDB Go Driver如何記錄日志的詳細(xì)內(nèi)容,更多關(guān)于MongoDB Go Driver記錄日志的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Golang實(shí)現(xiàn)請(qǐng)求限流的幾種辦法(小結(jié))
這篇文章主要介紹了Golang實(shí)現(xiàn)請(qǐng)求限流的幾種辦法(小結(jié)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10go 判斷兩個(gè) slice/struct/map 是否相等的實(shí)例
這篇文章主要介紹了go 判斷兩個(gè) slice/struct/map 是否相等的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12golang解析json數(shù)據(jù)的4種方法總結(jié)
在日常工作中每一名開(kāi)發(fā)者,不管是前端還是后端,都經(jīng)常使用 JSON,下面這篇文章主要給大家介紹了關(guān)于golang解析json數(shù)據(jù)的4種方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06Go基于GORM 獲取當(dāng)前請(qǐng)求所執(zhí)行的 SQL 信息(思路詳解)
這篇文章主要介紹了Go基于GORM 獲取當(dāng)前請(qǐng)求所執(zhí)行的 SQL 信息(思路詳解),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01golang使用net/rpc庫(kù)實(shí)現(xiàn)rpc
這篇文章主要為大家詳細(xì)介紹了golang如何使用net/rpc庫(kù)實(shí)現(xiàn)rpc,文章的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考一下2024-01-01Golang學(xué)習(xí)之反射機(jī)制的用法詳解
反射的本質(zhì)就是在程序運(yùn)行的時(shí)候,獲取對(duì)象的類(lèi)型信息和內(nèi)存結(jié)語(yǔ)構(gòu),反射是把雙刃劍,功能強(qiáng)大但可讀性差。本文將詳細(xì)講講Golang中的反射機(jī)制,感興趣的可以了解一下2022-06-06用Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)Web服務(wù)之項(xiàng)目介紹
從本節(jié)開(kāi)始將從后端到前端一步一步實(shí)現(xiàn)一個(gè)Go語(yǔ)言Web服務(wù),后端除了MySQL驅(qū)動(dòng),全部使用Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)來(lái)實(shí)現(xiàn)一個(gè)小型項(xiàng)目,本篇將簡(jiǎn)單的介紹一下項(xiàng)目開(kāi)發(fā)要準(zhǔn)備的流程,感興趣的同學(xué)可以閱讀一下2023-05-05Go語(yǔ)言同步與異步執(zhí)行多個(gè)任務(wù)封裝詳解(Runner和RunnerAsync)
這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言同步與異步執(zhí)行多個(gè)任務(wù)封裝(Runner和RunnerAsync)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01