文档菜单
文档首页
/ / /
Go 驱动
/

日志记录

在本页

  • 概述
  • 启用日志记录
  • 配置日志记录器
  • 日志组件和严重级别
  • 示例
  • 使用自定义日志记录器
  • 示例
  • 集成第三方日志记录器
  • 示例
  • 更多信息
  • API 文档

在本指南中,您可以学习如何使用驱动程序来配置应用程序的日志记录。日志记录的目的是记录驱动程序事件。

日志记录器可以按照您指定的严重性或详细程度级别记录消息。通过在您的应用程序中启用日志记录器,您可以接收有关应用程序活动的信息,无论是高级别、详细级别还是在两者之间。

提示

要了解有关日志严重性级别的更多信息,请参阅维基百科上的消息日志的Syslog标准.

要配置您的Client实例上的日志记录器,在创建您的ClientOptions对象时调用SetLoggerOptions()方法。该SetLoggerOptions()方法接受一个LoggerOptions类型作为参数。将此LoggerOptions类型设置为您应用程序的日志记录器进行配置。

以下代码显示了如何创建启用日志记录的客户端

loggerOptions := options.
Logger().
SetComponentLevel(options.LogComponentCommand, options.LogLevelDebug)
clientOptions := options.
Client().
ApplyURI(uri).
SetLoggerOptions(loggerOptions)
client, err := mongo.Connect(context.TODO(), clientOptions)

要创建一个 LoggerOptions 对象,请调用 options.Logger() 方法。下表描述了如何设置 LoggerOptions 类型的属性以配置您的日志记录器。第一列列出 LoggerOptions 属性,第二列描述属性,第三列列出每个属性的相应设置方法和参数。

属性
描述
设置方法
ComponentLevels

类型map[LogComponent]LogLevel
组件到日志严重级别的映射。驱动程序使用每个 LogComponentLogLevel 来确定是否生成日志消息。

有关 LogComponentLogLevel 类型的更多信息,请参阅本指南的 日志组件和严重级别 部分。
SetComponentLevel()

参数LogComponentLogLevel
Sink

类型LogSink
驱动程序用于记录消息的日志接口。LogSink 类型是一个接口,您可以实现它以提供自定义接收器或集成第三方日志记录器以用于驱动程序的日志。如果您不设置此属性,则驱动程序使用标准日志库。

有关更多信息,请参阅本指南的 使用自定义日志记录器集成第三方日志记录器 部分。
SetSink()

参数LogSink
MaxDocumentLength

类型uint
默认值1000
驱动程序发出的每个日志消息的最大字节长度。如果消息大于此值,则驱动程序将截断它并在部分日志消息的末尾添加省略号。
SetMaxDocumentLength()

参数uint

提示

将日志写入特定文件

默认情况下,标准日志记录器将消息记录到您的控制台(stderr)。您可以通过设置环境变量 MONGODB_LOG_PATHstdout 或文件路径来指定日志目标。

要指定驱动程序记录的组件,请设置 LogComponent 类型。下表描述了 LogComponent 的内置规格

设置
描述
枚举值
LogComponentAll
启用所有组件的记录
0
LogComponentCommand
启用命令监控记录
1
LogComponentTopology
启用拓扑记录
2
LogComponentServerSelection
启用服务器选择记录
3
LogComponentConnection
启用连接服务记录
4

您可以通过设置名称或枚举值来指定日志组件。以下代码显示了启用命令监控的等效方式

// Using named value
comp := options.LogComponentCommand
// Using enumeration
comp := options.LogComponent(1)

要指定日志严重级别,请设置 LogLevel 类型。以下代码显示了如何在 LevelDebug 级别启用记录

lvl := options.LogLevelDebug

重要

Go 驱动程序目前仅发出 LevelDebug 级别的消息,但它支持 LogLevel 的其他规格。有关更多信息,请参阅 LogLevel API 文档。

此示例显示了如何使用以下规格配置标准记录器

  • 最大文档长度为 25 字节。

  • 日志组件是 LogComponentCommand

  • 记录严重级别是 LevelDebug

loggerOptions := options.
Logger().
SetMaxDocumentLength(25).
SetComponentLevel(options.LogComponentCommand, options.LogLevelDebug)
// Creates options that include the logger specification
clientOptions := options.
Client().
ApplyURI(uri).
SetLoggerOptions(loggerOptions)

以下代码执行插入操作,这将生成日志消息

type Item struct {
Name string
}
coll := client.Database("db").Collection("testColl")
_, err = coll.InsertOne(context.TODO(), Item{Name: "grapefruit"})
{"command":"{\"insert\": \"testColl\",\"or...","commandName":"insert","databaseName":"db","driverConnectionId":1,"message":"Command started","operationId":0,"requestId":13,"serverConnectionId":97377,"serverHost":"...","serverPort":27017,"timestamp":...}
{"commandName":"insert","driverConnectionId":1,"durationMS":19,"message":"Command succeeded","operationId":0,"reply":"{\"n\": {\"$numberInt\":\"1\"},...","requestId":13,"serverConnectionId":97377,"serverHost":"...","serverPort":27017,"timestamp":...}

如果标准日志库无法满足您的需求,您可以实现一个自定义日志记录器。通过自定义日志配置,您可以更好地控制日志内容、格式和频率。

要使用自定义日志记录器,定义一个日志记录器结构体,并实现结构体的 Info()Error() 方法。接下来,通过在您的 LoggerOptions 实例上调用 SetSink() 方法,将日志记录器设置为您的 ClientLogSink

本示例演示了如何定义和实现一个自定义日志记录器。

1
type CustomLogger struct {
io.Writer
mu sync.Mutex
}

注意

前面的代码示例在 CustomLogger 结构体中使用了 Mutex 类型,以确保原子写入并防止竞争条件。设置 Mutex 使您的日志记录器能够安全地由多个 goroutines 同时使用。

2
func (logger *CustomLogger) Info(level int, msg string, _ ...interface{}) {
logger.mu.Lock()
defer logger.mu.Unlock()
if options.LogLevel(level+1) == options.LogLevelDebug {
fmt.Fprintf(logger, "level: %d DEBUG, message: %s\n", level, msg)
} else {
fmt.Fprintf(logger, "level: %d INFO, message: %s\n", level, msg)
}
}
func (logger *CustomLogger) Error(err error, msg string, _ ...interface{}) {
logger.mu.Lock()
defer logger.mu.Unlock()
fmt.Fprintf(logger, "error: %v, message: %s\n", err, msg)
}
3

在这个示例中,日志记录器以LevelDebug级别记录命令和连接事件

buf := bytes.NewBuffer(nil)
sink := &CustomLogger{Writer: buf}
loggerOptions := options.
Logger().
SetSink(sink).
SetComponentLevel(options.LogComponentCommand, options.LogLevelDebug).
SetComponentLevel(options.LogComponentConnection, options.LogLevelDebug)
// Creates options that include the logger specification
clientOptions := options.
Client().
ApplyURI(uri).
SetLoggerOptions(loggerOptions)
4

以下代码执行插入操作,这将生成日志消息

type Item struct {
Name string
}
coll := client.Database("db").Collection("testColl")
_, err = coll.InsertOne(context.TODO(), Item{Name: "grapefruit"})
level: 1 DEBUG, message: Connection pool created
level: 1 DEBUG, message: Connection pool ready
level: 1 DEBUG, message: Connection pool created
level: 1 DEBUG, message: Connection pool ready
level: 1 DEBUG, message: Connection pool created
level: 1 DEBUG, message: Connection pool ready
level: 1 DEBUG, message: Connection checkout started
level: 1 DEBUG, message: Connection created
level: 1 DEBUG, message: Connection ready
level: 1 DEBUG, message: Connection checked out
level: 1 DEBUG, message: Command started
level: 1 DEBUG, message: Command succeeded
level: 1 DEBUG, message: Connection checked in

Go语言中有许多第三方日志记录包可用。要在您的应用程序中使用第三方日志记录器,创建一个日志记录器并将它作为您的 LoggerOptions 实例的输出端。

此示例演示了如何将第三方日志记录包 logrus 集成到您的应用程序中。

1

在您的终端中运行以下 go get 命令以下载此示例所需的 logrus

go get github.com/bombsimon/logrusr/v4
go get github.com/sirupsen/logrus
2

以下代码创建了一个具有以下规范的 logrus 日志记录器。

  • 该日志记录器将消息记录到控制台。

  • 该日志记录器在 DebugLevel 级别记录消息。

  • 该日志记录器使用 JSONFormatter 格式化器格式化消息。

myLogger := &logrus.Logger{
Out: os.Stderr,
Level: logrus.DebugLevel,
Formatter: &logrus.JSONFormatter{
TimestampFormat: "2006-01-02 15:04:05",
PrettyPrint: true,
},
}
3

在以下代码示例中,日志记录器被配置为在 LevelDebug 级别记录命令。

sink := logrusr.New(myLogger).GetSink()
// Sets options when configuring the logrus logger
loggerOptions := options.
Logger().
SetSink(sink).
SetComponentLevel(options.LogComponentCommand, options.LogLevelDebug)
// Creates options that include the logger specification
clientOptions := options.
Client().
ApplyURI(uri).
SetLoggerOptions(loggerOptions)
4

以下代码执行了一些 CRUD 操作,这些操作将生成日志消息。

type Item struct {
Name string
}
coll := client.Database("db").Collection("testColl")
docs := []interface{}{
Item{Name: "starfruit"},
Item{Name: "kiwi"},
Item{Name: "cantaloupe"},
}
_, err = coll.InsertMany(context.TODO(), docs)
if err != nil {
panic(err)
}
_, err = coll.DeleteOne(context.TODO(), Item{Name: "kiwi"})
if err != nil {
panic(err)
}
{
"command": "{\"insert\": \"testColl\", ...}",
"commandName": "insert",
"databaseName": "db",
...
"level": "debug",
"message": "Command started",
"msg": "Command started",
...
"time": "2023-07-06 10:23:42"
}
{
"commandName": "insert",
...
"level": "debug",
"message": "Command succeeded",
"msg": "Command succeeded",
...
"time": "2023-07-06 10:23:42"
}
{
"command": "{\"delete\": \"testColl\", ...}",
"commandName": "delete",
"databaseName": "db",
...
"level": "debug",
"message": "Command started",
"msg": "Command started",
...
"time": "2023-07-06 10:23:42"
}
{
"commandName": "delete",
...
"level": "debug",
"message": "Command succeeded",
"msg": "Command succeeded",
...
"time": "2023-07-06 10:23:42"
}

提示

日志包

您可以在各自的 GitHub 仓库中找到有关第三方日志包的更多信息。

要查看集成这些日志记录器的完整代码示例,请参阅Go 驱动器 Github 仓库中的日志测试。

有关设置客户端选项的更多信息,请参阅连接指南.

提示

监控

除了日志记录之外,您还可以在应用程序中启用服务器选择和拓扑监控。有关更多信息,请参阅监控基础指南。

要了解本指南中讨论的任何类型或方法,请参阅以下API文档

返回

事务