Docs 菜单
Docs 主页
/ / /
Go 驱动程序
/

日志记录

在此页面上

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

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

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

提示

要学习;了解有关日志记录严重性级别的更多信息,请参阅有关消息日志记录的 系统日志标准的 维基百科条目。

要在 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属性,第二列描述属性,第三列列出每个属性相应的 setter 方法和参数:

属性
说明
Setter 方法
ComponentLevels

Type: map[LogComponent]LogLevel
A mapping of components to log severity levels. The driver uses the LogLevel for each LogComponent to determine if the log message is generated.

To learn more about the LogComponent and LogLevel types, see the Log Components and Severity Levels section of this guide.
SetComponentLevel()

Parameters: LogComponent, LogLevel
Sink

Type: LogSink
The logging interface that the driver uses to log messages. The LogSink type is an interface that you can implement to provide a custom sink or integrate a third-party logger for the driver's logs. If you don't set this property, the driver uses the standard logging library.

To learn more, see the Use a Custom Logger and Integrate Third-Party Loggers sections of this guide.
SetSink()

Parameter: LogSink
MaxDocumentLength

Type: uint
Default: 1000
The maximum length in bytes of each log message that the driver emits. If the message is larger than this value, the driver truncates it and appends ellipses to the partial log message.
SetMaxDocumentLength()

Parameter: uint

提示

将日志写入特定文件

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

要指定驱动程序记录日志的组件,请设置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可以让您的记录器安全地供多个 goroutine 并发使用。

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 文档:

后退

事务