Overview
En esta guía, puedes aprender cómo usar el controlador para configurar el registro para tu aplicación. El registro tiene como objetivo registrar los eventos del controlador.
Un registrador registra mensajes en un nivel de gravedad o nivel de verbosidad que puedes especificar. Al habilitar un registrador en tu aplicación, podrás recibir información sobre las actividades de tu aplicación a un nivel alto, a un nivel detallado, o en cualquier punto intermedio.
Tip
Para aprender más sobre los niveles de gravedad del registro, consulte la entrada de Wikipedia sobre el Estándar Syslog para el registro de mensajes.
Habilitar registro
Para configurar un logger en tu Client instancia, llama al método SetLoggerOptions() al crear tu objeto ClientOptions. El método SetLoggerOptions() acepta un tipo LoggerOptions como parámetro. Establece este tipo LoggerOptions para configurar el registrador de logs de tu aplicación.
El siguiente código muestra cómo crear un cliente con registro activado:
loggerOptions := options. Logger(). SetComponentLevel(options.LogComponentCommand, options.LogLevelDebug) clientOptions := options. Client(). ApplyURI(uri). SetLoggerOptions(loggerOptions) client, err := mongo.Connect(context.TODO(), clientOptions)
Configurar un registrador
Para crear un objeto LoggerOptions, llama al método options.Logger(). La siguiente tabla describe cómo ajustar las propiedades de un tipo LoggerOptions para configurar tu registrador. La primera columna enumera las propiedades de LoggerOptions, la segunda columna describe las propiedades y la tercera columna enumera el método setter correspondiente y los parámetros de cada propiedad:
Propiedad | Descripción | Método setter |
|---|---|---|
ComponentLevelsType: 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 |
SinkType: 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 |
MaxDocumentLengthType: uintDefault: 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
Guardar registros en un archivo específico
Por defecto, el registrador estándar registra mensajes en tu consola (stderr). Puedes especificar un destino de registro configurando la variable de entorno MONGODB_LOG_PATH en stdout o una ruta de archivo.
Componentes de registro y niveles de severidad
Para especificar los componentes sobre los que el driver registra, establecer el tipo LogComponent. La siguiente tabla describe las especificaciones integradas para LogComponent:
Configuración | Descripción | Valor de enumeración |
|---|---|---|
| Habilita el registro para todos los componentes |
|
| Activa el registro del monitor de comandos |
|
| Permite el registro de la topología |
|
| Habilita el registro de selección de servidor |
|
| Habilita el registro de servicios de conexión |
|
Puede especificar el componente de registro utilizando el nombre de la configuración o su valor de enumeración. El siguiente código muestra formas equivalentes de habilitar la supervisión de comandos:
// Using named value comp := options.LogComponentCommand // Using enumeration comp := options.LogComponent(1)
Para especificar el nivel de gravedad del registro, establece el LogLevel tipo. El siguiente código muestra cómo habilitar el registro en el nivel LevelDebug:
lvl := options.LogLevelDebug
Importante
El controlador de Go actualmente emite únicamente mensajes de nivel LevelDebug, pero admite otras especificaciones para LogLevel. Para obtener más información, consulta la documentación de la API de LogLevel.
Ejemplo
Este ejemplo muestra cómo configurar el registrador estándar con las siguientes especificaciones:
La longitud máxima del documento es de
25bytes.El componente de registro es
LogComponentCommand.El nivel de gravedad del registro es
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)
El siguiente código realiza una operación de inserción que genera mensajes de registro:
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":...}
Utiliza un registrador personalizado
Si la librería estándar de logging no satisface tus necesidades, puedes implementar un registrador personalizado. Al personalizar tu configuración de logging, tienes más control sobre el contenido, formato y frecuencia de los mensajes de registro.
Para utilizar un logger personalizado, defina un struct de logger e implemente los métodos Info() y Error() para dicho struct. A continuación, establezca el registrador como el LogSink para su Client llamando al método SetSink() en su instancia LoggerOptions.
Ejemplo
Este ejemplo demuestra cómo definir e implementar un logger personalizado.
Defina la estructura CustomLogger.
type CustomLogger struct { io.Writer mu sync.Mutex }
Nota
El ejemplo de código anterior utiliza un tipo Mutex en la estructura CustomLogger para garantizar escrituras atómicas y evitar condiciones de carrera. Establecer un Mutex hace que tu registrador sea seguro para el uso concurrente por múltiples goroutines.
Implementa los métodos Info() y Error() con un formato personalizado de registro de mensajes.
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) }
Asigne un Writer a su registrador y establezca como Sink para su Client.
En este ejemplo, el logger registra comandos y eventos de conexión en el nivel 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)
Ejecuta una operación.
El siguiente código realiza una operación de inserción que genera mensajes de registro:
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
Integra registradores de terceros
Hay muchos paquetes de registro externos disponibles en Go. Para utilizar un registrador de terceros en tu aplicación, crea un registrador y asígnalo como el destino en tu instancia de LoggerOptions.
Ejemplo
Este ejemplo demuestra cómo integrar logrus, un paquete de registro de terceros, en tu aplicación.
Define el registrador logrus.
El siguiente código crea un registrador logrus con estas especificaciones:
El registrador registra mensajes en la consola.
El registrador registra mensajes en el nivel
DebugLevel.El logger formatea los mensajes utilizando el formato
JSONFormatter.
myLogger := &logrus.Logger{ Out: os.Stderr, Level: logrus.DebugLevel, Formatter: &logrus.JSONFormatter{ TimestampFormat: "2006-01-02 15:04:05", PrettyPrint: true, }, }
Configure el registrador como el Sink para su Client.
En el siguiente ejemplo de código, el logger está configurado para registro de comandos en el nivel 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)
Realizar operaciones.
El siguiente código realiza algunas operaciones CRUD, que generan mensajes de registro:
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
Paquetes de registro
Puedes encontrar más información sobre paquetes de logs de terceros en sus respectivos repositorios de GitHub:
Para ver ejemplos de código completos que integran estos registradores, consulta las pruebas de registro en el repositorio Github del controlador de Go.
Información Adicional
Para obtener más información sobre cómo configurar las opciones del cliente, consulta la Guía de conexión.
Tip
Monitoring
Además del registro, puedes habilitar la selección de servidores y la supervisión de la topología en tu aplicación. Para obtener más información, consulta la guía de Fundamentos de supervisión.
Documentación de la API
Para aprender más sobre cualquiera de los tipos o métodos discutidos en esta guía, consulta la siguiente documentación de la API: