为什么

如果你有这些问题:

  1. golang 官网的 mongo driver 怎么执行了没有日志输入啊
  2. golang mongo driver 如何记录sql,如何打印之行的命令
    那么这篇文章能够持续看上来。

    背景

在这之前我应用 MySQL是比拟多的,起初遇到有记录用户日志需要,随着数据量越来越大,MySQL越来越扛不住,就降级为了Mongo,在应用 Mongo过程中,发现没法记录日志,就是无奈将打印代码发动的sql,之前应用gorm打印execute sql 是很不便的。

在网上查了良久也没查到相干材料,就开始翻官网文档,和源码。

终于在不懈~ 打住,其实很简略,就在 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 // 执行的命令监视器(日志)    ServerMonitor            *event.ServerMonitor    ...    err error    uri string    cs  *connstring.ConnString

github 代码地址

是的—— ClientOptions.Monitor 字段。

应用办法如下:

package mongolearnimport (    "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 monitorfunc 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)    }}

输入后果

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 ns2023/08/20 13:22:43 mongo update one re &{MatchedCount:0 ModifiedCount:0 UpsertedCount:0 UpsertedID:<nil>}# 上面是断开 mongo 时触发的命令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 程序记录,最初才会执行函数外的 日志 。

完结

我看网上材料少,很多小伙伴都不晓得,特此写一篇小文记录下。