Logging
On this page
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(context.TODO(), 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 |
---|---|---|
LogComponentAll | Enables logging for all components | 0 |
LogComponentCommand | Enables command monitor logging | 1 |
LogComponentTopology | Enables topology logging | 2 |
LogComponentServerSelection | Enables server selection logging | 3 |
LogComponentConnection | Enables connection services logging | 4 |
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: