詳解MongoDB?Go?Driver如何記錄日志
引言
如果你有這些問題:
- golang 官方的 mongo driver 怎么執(zhí)行了沒有日志輸出啊
- golang mongo driver 如何記錄sql,如何打印執(zhí)行的命令
- 想通過日志來檢查 golang mongo 調(diào)用API是否符合預(yù)期
那么這篇文章可以繼續(xù)看下去。
背景
在這之前我使用 MySQL 是比較多的,后來遇到有記錄用戶操作日志需求,隨著數(shù)據(jù)量越來越大,MySQL 有些扛不?。?,就換成了 Mongo,在使用Mongo過程中,發(fā)現(xiàn)沒法記錄日志,就是無法將打印代碼發(fā)起的sql,之前使用gorm打印execute sql是很方便的。
在網(wǎng)上查了好久也沒查到相關(guān)資料,就開始翻官方文檔,和源碼。
終于在不懈~ 打住,其實(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.ConnStringClientOptions.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>}
# 下面是斷開 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
通過以上日志可以看到,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é)),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
go 判斷兩個(gè) slice/struct/map 是否相等的實(shí)例
這篇文章主要介紹了go 判斷兩個(gè) slice/struct/map 是否相等的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-12-12
golang解析json數(shù)據(jù)的4種方法總結(jié)
在日常工作中每一名開發(fā)者,不管是前端還是后端,都經(jīng)常使用 JSON,下面這篇文章主要給大家介紹了關(guān)于golang解析json數(shù)據(jù)的4種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
Go基于GORM 獲取當(dāng)前請(qǐng)求所執(zhí)行的 SQL 信息(思路詳解)
這篇文章主要介紹了Go基于GORM 獲取當(dāng)前請(qǐng)求所執(zhí)行的 SQL 信息(思路詳解),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
golang使用net/rpc庫實(shí)現(xiàn)rpc
這篇文章主要為大家詳細(xì)介紹了golang如何使用net/rpc庫實(shí)現(xiàn)rpc,文章的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的小伙伴可以參考一下2024-01-01
Golang學(xué)習(xí)之反射機(jī)制的用法詳解
反射的本質(zhì)就是在程序運(yùn)行的時(shí)候,獲取對(duì)象的類型信息和內(nèi)存結(jié)語構(gòu),反射是把雙刃劍,功能強(qiáng)大但可讀性差。本文將詳細(xì)講講Golang中的反射機(jī)制,感興趣的可以了解一下2022-06-06
用Go語言標(biāo)準(zhǔn)庫實(shí)現(xiàn)Web服務(wù)之項(xiàng)目介紹
從本節(jié)開始將從后端到前端一步一步實(shí)現(xiàn)一個(gè)Go語言Web服務(wù),后端除了MySQL驅(qū)動(dòng),全部使用Go語言標(biāo)準(zhǔn)庫來實(shí)現(xiàn)一個(gè)小型項(xiàng)目,本篇將簡(jiǎn)單的介紹一下項(xiàng)目開發(fā)要準(zhǔn)備的流程,感興趣的同學(xué)可以閱讀一下2023-05-05
Go語言同步與異步執(zhí)行多個(gè)任務(wù)封裝詳解(Runner和RunnerAsync)
這篇文章主要給大家介紹了關(guān)于Go語言同步與異步執(zhí)行多個(gè)任務(wù)封裝(Runner和RunnerAsync)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2018-01-01

