Overview
In this guide, you can learn how to use the driver to configure logging for your application. The purpose of logging is to record driver events.
A logger logs messages at a severity, or verbosity, level that you can specify. By enabling a logger in your application, you can receive information about your application's activities at a high level, a detailed level, or somewhere in between.
Tip
To learn more about logging severity levels, see the Wikipedia entry on the Syslog standard for message logging.
Enable Logging
To configure a logger on your Client
instance, call the SetLoggerOptions()
method when creating your ClientOptions
object. The SetLoggerOptions()
method takes a LoggerOptions
type as a parameter. Set this LoggerOptions
type to configure the logger for your application.
The following code shows how to create a client with logging enabled:
loggerOptions := options. Logger(). SetComponentLevel(options.LogComponentCommand, options.LogLevelDebug) clientOptions := options. Client(). ApplyURI(uri). SetLoggerOptions(loggerOptions) client, err := mongo.Connect(clientOptions)
Configure a Logger
To create a LoggerOptions
object, call the options.Logger()
method. The following table describes how to set properties on a LoggerOptions
type to configure your logger. The first column lists the LoggerOptions
properties, the second column describes the properties, and the third column lists the corresponding setter method and parameters for each property:
Property | Description | Setter Method |
---|---|---|
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 |
Tip
Write Logs to a Specific File
By default, the standard logger logs messages to your console (stderr
). You can specify a logging destination by setting the MONGODB_LOG_PATH
environment variable to stdout
or a filepath.
Log Components and Severity Levels
To specify the components that the driver logs against, set the LogComponent
type. The following table describes built-in specifications for LogComponent
:
Setting | Description | Enumeration Value |
---|---|---|
| Enables logging for all components |
|
| Enables command monitor logging |
|
| Enables topology logging |
|
| Enables server selection logging |
|
| Enables connection services logging |
|
You can specify the log component by using either the setting name or its enumeration value. The following code shows equivalent ways of enabling command monitoring:
// Using named value comp := options.LogComponentCommand // Using enumeration comp := options.LogComponent(1)
To specify the log severity level, set the LogLevel
type. The following code shows how to enable logging at the LevelDebug
level:
lvl := options.LogLevelDebug
Important
The Go driver currently emits only LevelDebug
level messages, but it supports other specifications for LogLevel
. To learn more, see the LogLevel API documentation.
Example
This example shows how to configure the standard logger with the following specifications:
The maximum document length is
25
bytes.The log component is
LogComponentCommand
.The logging severity level is
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)
The following code performs an insert operation, which generates log messages:
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":...}
Use a Custom Logger
If the standard logging library does not meet your needs, you can implement a custom logger. By customizing your logging configuration, you have more control over the content, format, and frequency of log messages.
To use a custom logger, define a logger struct and implement the Info()
and Error()
methods for the struct. Next, set the logger as the LogSink
for your Client
by calling the SetSink()
method on your LoggerOptions
instance.
Example
This example demonstrates how to define and implement a custom logger.
Implement the Info()
and Error()
methods with custom log message formatting.
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) }
Assign a Writer
to your logger and set it as the Sink
for your Client
.
In this example, the logger logs commands and connection events at the LevelDebug
level:
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)
Perform an operation.
The following code performs an insert operation, which generates log messages:
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
Integrate Third-Party Loggers
There are many third-party logging packages available in Go. To use a third-party logger in your application, create a logger and assign it as the sink in your LoggerOptions
instance.
Example
This example demonstrates how to integrate logrus
, a third-party logging package, into your application.
Define the logrus
logger.
The following code creates a logrus
logger with these specifications:
The logger logs messages to the console.
The logger logs messages at the
DebugLevel
level.The logger formats messages using the
JSONFormatter
formatter.
myLogger := &logrus.Logger{ Out: os.Stderr, Level: logrus.DebugLevel, Formatter: &logrus.JSONFormatter{ TimestampFormat: "2006-01-02 15:04:05", PrettyPrint: true, }, }
Set the logger as the Sink
for your Client
.
In the following code example, the logger is configured to log commands at the LevelDebug
level.
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)
Perform operations.
The following code performs some CRUD operations, which generate log messages:
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" }
Tip
Logging Packages
You can find more information on third-party logging packages in their respective GitHub repositories:
To see full code examples that integrate these loggers, see the logging tests in the Go driver Github repository.
Additional Information
For more information about setting client options, see the Connection Guide.
Tip
Monitoring
In addition to logging, you can enable server selection and topology monitoring in your application. To learn more, see the Monitoring Fundamentals guide.
API Documentation
To learn more about any of the types or methods discussed in this guide, see the following API Documentation: