详解MongoDB Go Driver如何记录日志

 更新时间:2023年08月20日 14:54:56   作者:小白要生发  
这篇文章主要为大家介绍了MongoDB Go Driver如何记录日志详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

如果你有这些问题:

  • golang 官方的 mongo driver 怎么执行了没有日志输出啊
  • golang mongo driver 如何记录sql,如何打印执行的命令
  • 想通过日志来检查 golang mongo 调用API是否符合预期

那么这篇文章可以继续看下去。

背景

在这之前我使用 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 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)
    }
}

输出结果

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 时触发的命令
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 按照 StartedSucceeded 顺序记录,最后才会执行函数外的 日志 。

以上就是详解MongoDB Go Driver如何记录日志的详细内容,更多关于MongoDB Go Driver记录日志的资料请关注脚本之家其它相关文章!

相关文章

  • Go数组的具体使用

    Go数组的具体使用

    Go语言中的数组是一种固定长度的数据结构,它包含一组按顺序排列的元素,每个元素都具有相同的类型,本文主要介绍了Go数组的具体使用,包括声明数组、初始化数组、访问数组元素等,感兴趣的可以了解下
    2023-11-11
  • Go中RPC远程过程调用的实现

    Go中RPC远程过程调用的实现

    本文主要介绍了Go中RPC远程过程调用的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-07-07
  • 浅谈Golang Slice切片如何扩容的实现

    浅谈Golang Slice切片如何扩容的实现

    本文主要介绍了浅谈Golang Slice切片如何扩容的实现,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • goland 导入github包报红问题解决

    goland 导入github包报红问题解决

    本文主要介绍了Go项目在GoLand中导入依赖标红问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-08-08
  • golang连接redis库及基本操作示例过程

    golang连接redis库及基本操作示例过程

    这篇文章主要介绍了golang连接redis库及基本操作示例过程,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04
  • Go语言实现读取文件的方式总结

    Go语言实现读取文件的方式总结

    这篇文章主要为大家详细介绍了Go语言实现读取文件的几个方式,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,感兴趣的小伙伴可以收藏一下
    2023-04-04
  • Go语言实现运算符重载的方法详解

    Go语言实现运算符重载的方法详解

    这篇文章主要为大家详细介绍了如何利用Go语言实现运算符重载的方法,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2022-09-09
  • Golang gRPC HTTP协议转换示例

    Golang gRPC HTTP协议转换示例

    这篇文章主要为大家介绍了Golang gRPC HTTP协议转换示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-06-06
  • Go语言编程中字符串切割方法小结

    Go语言编程中字符串切割方法小结

    这篇文章主要介绍了Go语言编程中字符串切割方法小结,所整理的方法都来自字符串相关的strings包,需要的朋友可以参考下
    2015-10-10
  • go语言中值类型和指针类型的深入理解

    go语言中值类型和指针类型的深入理解

    这篇文章主要给大家介绍了关于go语言中值类型和指针类型的相关资料,文中通过实例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2022-03-03

最新评论