---
name: "mongoc_logging"
section: "3"
platform: "linux"
package: "libmongoc-doc"
version: "1.30.4-1+deb13u3"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/mongoc_logging"
---

# mongoc\_logging(3)

The MongoDB C driver has two different types of logging available:

- •

  The original **mongoc\_log** facility supports freeform string messages that originate from the driver itself or from application code. This has been retroactively termed "unstructured logging".

- •

  A new **mongoc\_structured\_log** facility reports messages from the driver itself using a BSON format defined across driver implementations by the *MongoDB Logging Specification*.

These two systems are configured and used independently.

## UNSTRUCTURED LOGGING

This is the original logging facility that supports freeform string messages originating from the driver itself or from application code. This has been retroactively termed "unstructured logging". See *Structured Logging* for the newer standardized logging facility.

```
typedef enum {
   MONGOC_LOG_LEVEL_ERROR,
   MONGOC_LOG_LEVEL_CRITICAL,
   MONGOC_LOG_LEVEL_WARNING,
   MONGOC_LOG_LEVEL_MESSAGE,
   MONGOC_LOG_LEVEL_INFO,
   MONGOC_LOG_LEVEL_DEBUG,
   MONGOC_LOG_LEVEL_TRACE,
} mongoc_log_level_t;
#define MONGOC_ERROR(...)
#define MONGOC_CRITICAL(...)
#define MONGOC_WARNING(...)
#define MONGOC_MESSAGE(...)
#define MONGOC_INFO(...)
#define MONGOC_DEBUG(...)
typedef void (*mongoc_log_func_t) (mongoc_log_level_t log_level,
                                   const char *log_domain,
                                   const char *message,
                                   void *user_data);
void
mongoc_log_set_handler (mongoc_log_func_t log_func, void *user_data);
void
mongoc_log (mongoc_log_level_t log_level,
            const char *log_domain,
            const char *format,
            ...);
const char *
mongoc_log_level_str (mongoc_log_level_t log_level);
void
mongoc_log_default_handler (mongoc_log_level_t log_level,
                            const char *log_domain,
                            const char *message,
                            void *user_data);
void
mongoc_log_trace_enable (void);
void
mongoc_log_trace_disable (void);
```

This abstraction can be used for logging in your application, or you can integrate the driver with an existing logging system.

### Macros

To make logging a little less painful, various helper macros are provided. See the following example.

```
#undef MONGOC_LOG_DOMAIN
#define MONGOC_LOG_DOMAIN "my-custom-domain"
MONGOC_WARNING ("An error occurred: %s", strerror (errno));
```

### Custom Log Handlers

The default log handler prints a timestamp and the log message to **stdout**, or to **stderr** for warnings, critical messages, and errors. You can override the handler with **mongoc\_log\_set\_handler()**. Your handler function is called in a mutex for thread safety.

For example, you could register a custom handler to suppress messages at INFO level and below:

```
void
my_logger (mongoc_log_level_t log_level,
           const char *log_domain,
           const char *message,
           void *user_data)
{
   /* smaller values are more important */
   if (log_level < MONGOC_LOG_LEVEL_INFO) {
      mongoc_log_default_handler (log_level, log_domain, message, user_data);
   }
}
int
main (int argc, char *argv[])
{
   mongoc_log_set_handler (my_logger, NULL);
   mongoc_init ();
   /* ... your code ...  */
   mongoc_cleanup ();
   return 0;
}
```

Note that in the example above **mongoc\_log\_set\_handler()** is called before **mongoc\_init()**. Otherwise, some log traces could not be processed by the log handler.

To restore the default handler:

```
mongoc_log_set_handler (mongoc_log_default_handler, NULL);
```

### Disable logging

To disable all logging, including warnings, critical messages and errors, provide an empty log handler:

```
mongoc_log_set_handler (NULL, NULL);
```

### Tracing

If compiling your own copy of the MongoDB C driver, consider configuring with **-DENABLE\_TRACING=ON** to enable function tracing and hex dumps of network packets to **STDERR** and **STDOUT** during development and debugging.

This is especially useful when debugging what may be going on internally in the driver.

Trace messages can be enabled and disabled by calling **mongoc\_log\_trace\_enable()** and **mongoc\_log\_trace\_disable()**

**NOTE:**

Compiling the driver with **-DENABLE\_TRACING=ON** will affect its performance. Disabling tracing with **mongoc\_log\_trace\_disable()** significantly reduces the overhead, but cannot remove it completely.

## STRUCTURED LOGGING

This document describes a newer "structured" logging facility which reports messages from the driver itself using a BSON format defined across driver implementations by the *MongoDB Logging Specification*. See *Unstructured Logging* for the original freeform logging facility.

These two systems are configured and used independently.

Unstructured logging is global to the entire process, but structured logging is configured separately for each *mongoc\_client\_t* or *mongoc\_client\_pool\_t*. See *mongoc\_client\_set\_structured\_log\_opts()* and *mongoc\_client\_pool\_set\_structured\_log\_opts()*.

### Options

Structured log settings are tracked explicitly by a *mongoc\_structured\_log\_opts\_t* instance.

Like other drivers supporting structured logging, we take default settings from environment variables and offer additional optional programmatic configuration. Environment variables are captured during *mongoc\_structured\_log\_opts\_new()*, refer there for a full list of the supported variables.

Normally environment variables provide defaults that can be overridden programmatically. To request the opposite behavior, where your programmatic defaults can be overridden by the environment, see *mongoc\_structured\_log\_opts\_set\_max\_levels\_from\_env()*.

Structured log messages may be filtered in arbitrary ways by the handler, but as both a performance optimization and a convenience, a built-in filter limits the maximum log level of reported messages with a per-component setting.

### mongoc\_structured\_log\_opts\_t

### Synopsis

```
typedef struct mongoc_structured_log_opts_t mongoc_structured_log_opts_t;
```

**mongoc\_structured\_log\_opts\_t** is an opaque type that contains options for the structured logging subsystem: per-component log levels, a maximum logged document length, and a handler function.

Create a **mongoc\_structured\_log\_opts\_t** with *mongoc\_structured\_log\_opts\_new()*, set options and a callback on it, then pass it to *mongoc\_client\_set\_structured\_log\_opts()* or *mongoc\_client\_pool\_set\_structured\_log\_opts()*. Must be destroyed by calling *mongoc\_structured\_log\_opts\_destroy()*.

### Functions

### mongoc\_structured\_log\_opts\_new()

### Synopsis

```
mongoc_structured_log_opts_t *
mongoc_structured_log_opts_new (void);
```

Creates a new *mongoc\_structured\_log\_opts\_t*, filled with defaults captured from the current environment.

Sets a default log handler which would write a text representation of each log message to **stderr**, **stdout**, or another file configurable using **MONGODB\_LOG\_PATH**. This setting has no effect if the default handler is replaced using *mongoc\_structured\_log\_opts\_set\_handler()*.

Environment variable errors are non-fatal, and result in one-time warnings delivered as an unstructured log.

Per-component maximum levels are initialized equivalently to:

```
mongoc_structured_log_opts_set_max_level_for_all_components(opts, MONGOC_STRUCTURED_LOG_LEVEL_WARNING);
mongoc_structured_log_opts_set_max_levels_from_env(opts);
```

### Environment Variables

This is a full list of the captured environment variables.

- •

  **MONGODB\_LOG\_MAX\_DOCUMENT\_LENGTH**: Maximum length for JSON-serialized documents that appear within a log message. It may be a number, in bytes, or **unlimited** (case insensitive) to choose an implementation-specific value near the maximum representable length. By default, the limit is 1000 bytes. This limit affects interior documents like commands and replies, not the total length of a structured log message.

- •

  **MONGODB\_LOG\_PATH**: A file path or one of the special strings **stderr** or **stdout** (case insensitive) specifying the destination for structured logs seen by the default handler. By default, it writes to **stderr**. This path will be captured during **mongoc\_structured\_log\_opts\_new()**, but it will not immediately be opened. If the file can't be opened, a warning is then written to the unstructured log and the handler writes structured logs to **stderr** instead.

  **WARNING:**

  When a file path is given for **MONGODB\_LOG\_PATH**, each log instance (one stand-alone client or pool) will separately open this file for append. The results are operating system specific. On UNIX-like platforms each instance's output will be interleaved, in most cases without splitting individual log messages. Notably on Windows the file will be opened in exclusive mode by the first instance and subsequent instances will fail, falling back on the default of **stderr**. Applications that use multiple processes or multiple client pools will likely want to supply a log handler that annotates each message with information about its originating log instance.

- •

  **MONGODB\_LOG\_COMMAND**: A log level name to set as the maximum for **MONGOC\_STRUCTURED\_LOG\_COMPONENT\_COMMAND**.

- •

  **MONGODB\_LOG\_TOPOLOGY**: A log level name to set as the maximum for **MONGOC\_STRUCTURED\_LOG\_COMPONENT\_TOPOLOGY**.

- •

  **MONGODB\_LOG\_SERVER\_SELECTION**: A log level name to set as the maximum for **MONGOC\_STRUCTURED\_LOG\_COMPONENT\_SERVER\_SELECTION**.

- •

  **MONGODB\_LOG\_CONNECTION**: A log level name to set as the maximum for **MONGOC\_STRUCTURED\_LOG\_COMPONENT\_CONNECTION**.

- •

  **MONGODB\_LOG\_ALL**: A log level name applied to all components not otherwise specified.

Note that log level names are always case insensitive. This is a full list of recognized names, including allowed aliases:

- •

  **emergency**, **off**

- •

  **alert**

- •

  **critical**

- •

  **error**

- •

  **warning**, **warn**

- •

  **notice**

- •

  **informational**, **info**

- •

  **debug**

- •

  **trace**

### Returns

A newly allocated *mongoc\_structured\_log\_opts\_t*.

### mongoc\_structured\_log\_opts\_destroy()

### Synopsis

```
void
mongoc_structured_log_opts_destroy (mongoc_structured_log_opts_t *opts);
```

### Parameters

- •

  **opts**: Pointer to a *mongoc\_structured\_log\_opts\_t* allocated with *mongoc\_structured\_log\_opts\_new()*, or NULL.

### Description

This function releases all resources associated with a *mongoc\_structured\_log\_opts\_t*. Does nothing if **opts** is NULL.

### mongoc\_structured\_log\_opts\_set\_handler()

### Synopsis

```
void
mongoc_structured_log_opts_set_handler (mongoc_structured_log_opts_t *opts,
                                        mongoc_structured_log_func_t log_func,
                                        void *user_data);
```

Sets the function to be called to handle structured log messages, as a *mongoc\_structured\_log\_func\_t*.

The callback is given a *mongoc\_structured\_log\_entry\_t* as a handle for obtaining additional information about the log message. This entry pointer is only valid during a callback, because it's a low cost reference to temporary data.

Structured log handlers must be thread-safe if they will be used with *mongoc\_client\_pool\_t*. Handlers must avoid unbounded recursion, preferably by avoiding the use of any **libmongoc** client or pool which uses the same handler.

This function always replaces the default log handler from *mongoc\_structured\_log\_opts\_new()*, if it was still set. If the **log\_func** is set to NULL, structured logging will be disabled.

### Parameters

- •

  **opts**: Structured log options, allocated with *mongoc\_structured\_log\_opts\_new()*.

- •

  **log\_func**: The handler to install, a *mongoc\_structured\_log\_func\_t*, or NULL to disable structured logging.

- •

  **user\_data**: Optional user data, passed on to the handler.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_opts\_set\_max\_level\_for\_component()

### Synopsis

```
bool
mongoc_structured_log_opts_set_max_level_for_component (mongoc_structured_log_opts_t *opts,
                                                        mongoc_structured_log_component_t component,
                                                        mongoc_structured_log_level_t level);
```

Sets the maximum log level per-component. Only log messages at or below this severity level will be passed to *mongoc\_structured\_log\_func\_t*.

By default, each component's log level may come from environment variables. See *mongoc\_structured\_log\_opts\_set\_max\_levels\_from\_env()*.

### Parameters

- •

  **opts**: Structured log options, allocated with *mongoc\_structured\_log\_opts\_new()*.

- •

  **component**: The component to set a max log level. for, as a *mongoc\_structured\_log\_component\_t*.

- •

  **level**: The new max log level for this component, as a *mongoc\_structured\_log\_level\_t*.

### Returns

Returns **true** on success, or **false** if the supplied parameters were incorrect.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_opts\_set\_max\_level\_for\_all\_components()

### Synopsis

```
bool
mongoc_structured_log_opts_set_max_level_for_all_components (mongoc_structured_log_opts_t *opts,
                                                             mongoc_structured_log_level_t level);
```

Sets all per-component maximum log levels to the same value. Only log messages at or below this severity level will be passed to *mongoc\_structured\_log\_func\_t*. Effective even for logging components not known at compile-time.

### Parameters

- •

  **opts**: Structured log options, allocated with *mongoc\_structured\_log\_opts\_new()*.

- •

  **level**: The max log level for all components, as a *mongoc\_structured\_log\_level\_t*.

### Returns

Returns **true** on success, or **false** if the supplied parameters were incorrect.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_opts\_set\_max\_levels\_from\_env()

### Synopsis

```
bool
mongoc_structured_log_opts_set_max_levels_from_env (mongoc_structured_log_opts_t *opts);
```

Sets any maximum log levels requested by environment variables: **MONGODB\_LOG\_ALL** for all components, followed by per-component log levels **MONGODB\_LOG\_COMMAND**, **MONGODB\_LOG\_CONNECTION**, **MONGODB\_LOG\_TOPOLOGY**, and **MONGODB\_LOG\_SERVER\_SELECTION**.

Expects the value to be recognizable by *mongoc\_structured\_log\_get\_named\_level()*. Parse errors may cause a warning message, delivered via unstructured logging.

Component levels with no valid environment variable setting will be left unmodified.

This happens automatically when *mongoc\_structured\_log\_opts\_new()* establishes defaults. Any subsequent programmatic modifications to the *mongoc\_structured\_log\_opts\_t* will override the environment variable settings. For applications that desire the opposite behavior, where environment variables may override programmatic settings, they may call **mongoc\_structured\_log\_opts\_set\_max\_levels\_from\_env()** after calling *mongoc\_structured\_log\_opts\_set\_max\_level\_for\_component()* and *mongoc\_structured\_log\_opts\_set\_max\_level\_for\_all\_components()*. This will process the environment a second time, allowing it to override customized defaults.

### Returns

Returns **true** on success. If warnings are encountered in the environment, returns **false** and may log additional information to the unstructured logging facility. Note that, by design, these errors are by default non-fatal. When *mongoc\_structured\_log\_opts\_new()* internally calls this function, it ignores the return value.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_opts\_get\_max\_level\_for\_component()

### Synopsis

```
mongoc_structured_log_level_t
mongoc_structured_log_opts_get_max_level_for_component (const mongoc_structured_log_opts_t *opts,
                                                        mongoc_structured_log_component_t component);
```

### Parameters

- •

  **opts**: Structured log options, allocated with *mongoc\_structured\_log\_opts\_new()*.

- •

  **component**: Log component as a *mongoc\_structured\_log\_component\_t*.

### Returns

Returns the configured maximum log level for a specific component, as a *mongoc\_structured\_log\_level\_t*. This may be the last value set with *mongoc\_structured\_log\_opts\_set\_max\_level\_for\_component()* or *mongoc\_structured\_log\_opts\_set\_max\_level\_for\_all\_components()*, or it may be the default obtained from environment variables. If an invalid or unknown component enum is given, returns the lowest log level.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_opts\_set\_max\_document\_length()

### Synopsis

```
bool
mongoc_structured_log_opts_set_max_document_length (mongoc_structured_log_opts_t *opts,
                                                    size_t max_document_length);
```

Sets a maximum length for BSON documents that appear serialized in JSON form as part of a structured log message.

Serialized JSON will be truncated at this limit, interpreted as a count of UTF-8 encoded bytes. Truncation will be indicated with a **...** suffix, the length of which is not included in the max document length. If truncation at the exact indicated length would split a valid UTF-8 sequence, we instead truncate the document earlier at the nearest boundary between code points.

### Parameters

- •

  **opts**: Structured log options, allocated with *mongoc\_structured\_log\_opts\_new()*.

- •

  **max\_document\_length**: Maximum length for each embedded JSON document, in bytes, not including an ellipsis (**...**) added to indicate truncation. Values near or above **INT\_MAX** will be rejected.

### Returns

Returns **true** on success, or **false** if the supplied maximum length is too large.

**SEE ALSO:**

```
Structured Logging
mongoc_structured_log_opts_set_max_document_length_from_env()
```

### mongoc\_structured\_log\_opts\_set\_max\_document\_length\_from\_env()

### Synopsis

```
bool
mongoc_structured_log_opts_set_max_document_length_from_env (mongoc_structured_log_opts_t *opts);
```

Sets a maximum document length from the **MONGODB\_LOG\_MAX\_DOCUMENT\_LENGTH** environment variable, if a valid setting is found. See *mongoc\_structured\_log\_opts\_new()* for a description of the supported environment variable formats.

Parse errors may cause a warning message, delivered via unstructured logging.

This happens automatically when *mongoc\_structured\_log\_opts\_new()* establishes defaults. Any subsequent programmatic modifications to the *mongoc\_structured\_log\_opts\_t* will override the environment variable settings. For applications that desire the opposite behavior, where environment variables may override programmatic settings, they may call **mongoc\_structured\_log\_opts\_set\_max\_document\_length\_from\_env()** after calling *mongoc\_structured\_log\_opts\_set\_max\_document\_length()*. This will process the environment a second time, allowing it to override customized defaults.

### Returns

Returns **true** on success: either a valid environment setting was found, or the value is unset and **opts** will not be modified. If warnings are encountered in the environment, returns **false** and may log additional information to the unstructured logging facility. Note that, by design, these errors are by default non-fatal. When *mongoc\_structured\_log\_opts\_new()* internally calls this function, it ignores the return value.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_opts\_get\_max\_document\_length()

### Synopsis

```
size_t
mongoc_structured_log_opts_get_max_document_length (const mongoc_structured_log_opts_t *opts);
```

### Parameters

- •

  **opts**: Structured log options, allocated with *mongoc\_structured\_log\_opts\_new()*.

### Returns

Returns the current maximum document length set in **opts**, as a **size\_t**.

**SEE ALSO:**

```
Structured Logging
```

**SEE ALSO:**

```
Structured Logging
```

### Levels and Components

Log levels and components are defined as *mongoc\_structured\_log\_level\_t* and *mongoc\_structured\_log\_component\_t* enumerations. Utilities are provided to convert between these values and their standard string representations. The string values are case-insensitive.

```
typedef enum {
  MONGOC_STRUCTURED_LOG_LEVEL_EMERGENCY = 0,  // "Emergency" ("off" also accepted)
  MONGOC_STRUCTURED_LOG_LEVEL_ALERT = 1,      // "Alert"
  MONGOC_STRUCTURED_LOG_LEVEL_CRITICAL = 2,   // "Critical"
  MONGOC_STRUCTURED_LOG_LEVEL_ERROR = 3,      // "Error"
  MONGOC_STRUCTURED_LOG_LEVEL_WARNING = 4,    // "Warning" ("warn" also accepted)
  MONGOC_STRUCTURED_LOG_LEVEL_NOTICE = 5,     // "Notice"
  MONGOC_STRUCTURED_LOG_LEVEL_INFO = 6,       // "Informational" ("info" also accepted)
  MONGOC_STRUCTURED_LOG_LEVEL_DEBUG = 7,      // "Debug"
  MONGOC_STRUCTURED_LOG_LEVEL_TRACE = 8,      // "Trace"
} mongoc_structured_log_level_t;
typedef enum {
  MONGOC_STRUCTURED_LOG_COMPONENT_COMMAND = 0,           // "command"
  MONGOC_STRUCTURED_LOG_COMPONENT_TOPOLOGY = 1,          // "topology"
  MONGOC_STRUCTURED_LOG_COMPONENT_SERVER_SELECTION = 2,  // "serverSelection"
  MONGOC_STRUCTURED_LOG_COMPONENT_CONNECTION = 3,        // "connection"
} mongoc_structured_log_component_t;
```

### mongoc\_structured\_log\_level\_t

### Synopsis

```
typedef enum {
   MONGOC_STRUCTURED_LOG_LEVEL_EMERGENCY = 0,
   MONGOC_STRUCTURED_LOG_LEVEL_ALERT = 1,
   MONGOC_STRUCTURED_LOG_LEVEL_CRITICAL = 2,
   MONGOC_STRUCTURED_LOG_LEVEL_ERROR = 3,
   MONGOC_STRUCTURED_LOG_LEVEL_WARNING = 4,
   MONGOC_STRUCTURED_LOG_LEVEL_NOTICE = 5,
   MONGOC_STRUCTURED_LOG_LEVEL_INFO = 6,
   MONGOC_STRUCTURED_LOG_LEVEL_DEBUG = 7,
   MONGOC_STRUCTURED_LOG_LEVEL_TRACE = 8,
} mongoc_structured_log_level_t;
```

**mongoc\_structured\_log\_level\_t** enumerates the available log levels for use with structured logging.

### Functions

### mongoc\_structured\_log\_get\_level\_name()

### Synopsis

```
const char *
mongoc_structured_log_get_level_name (mongoc_structured_log_level_t level);
```

### Parameters

- •

  **level**: Log level as a *mongoc\_structured\_log\_level\_t*.

### Returns

If the level is known, returns a pointer to a constant string that should not be freed. If the level has no known name, returns NULL.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_get\_named\_level()

### Synopsis

```
bool
mongoc_structured_log_get_named_level (const char *name, mongoc_structured_log_level_t *out);
```

Look up a log level by name. Case insensitive.

### Parameters

- •

  **name**: A name to look up as a log level.

- •

  **out**: On success, the corresponding *mongoc\_structured\_log\_level\_t* is written here.

### Returns

If the level name is known, returns **true** and writes the level enum to **\*out**. If the level name is not known, returns **false** and does not write **\*out**.

**SEE ALSO:**

```
Structured Logging
```

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_component\_t

### Synopsis

```
typedef enum {
   MONGOC_STRUCTURED_LOG_COMPONENT_COMMAND = 0,
   MONGOC_STRUCTURED_LOG_COMPONENT_TOPOLOGY = 1,
   MONGOC_STRUCTURED_LOG_COMPONENT_SERVER_SELECTION = 2,
   MONGOC_STRUCTURED_LOG_COMPONENT_CONNECTION = 3,
} mongoc_structured_log_component_t;
```

**mongoc\_structured\_log\_component\_t** enumerates the structured logging components. Applications should never rely on having an exhaustive list of all log components. Instead, use *mongoc\_structured\_log\_opts\_set\_max\_level\_for\_all\_components()* to set a default level if needed.

### Functions

### mongoc\_structured\_log\_get\_component\_name()

### Synopsis

```
const char *
mongoc_structured_log_get_component_name (mongoc_structured_log_component_t component);
```

### Parameters

- •

  **component**: Log component as a *mongoc\_structured\_log\_component\_t*.

### Returns

If the component is known, returns a pointer to a constant string that should not be freed. If the component has no known name, returns NULL.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_get\_named\_component()

### Synopsis

```
bool
mongoc_structured_log_get_named_component (const char *name, mongoc_structured_log_component_t *out);
```

Look up a component by name. Case insensitive.

### Parameters

- •

  **name**: A name to look up as a log component.

- •

  **out**: On success, the corresponding *mongoc\_structured\_log\_component\_t* is written here.

### Returns

If the component name is known, returns **true** and writes the component enum to **\*out**. If the component name is not known, returns **false** and does not write **\*out**.

**SEE ALSO:**

```
Structured Logging
```

**SEE ALSO:**

```
Structured Logging
```

**SEE ALSO:**

mongoc\_structured\_log\_get\_level\_name mongoc\_structured\_log\_get\_named\_level mongoc\_structured\_log\_get\_component\_name mongoc\_structured\_log\_get\_named\_component

### Log Handlers

Each *mongoc\_client\_pool\_t* or standalone *mongoc\_client\_t* has its own instance of the structured logging subsystem, with its own settings and handler.

When using *mongoc\_client\_pool\_t*, the pooled clients all share a common logging instance. Handlers must be thread-safe.

The handler is called for each log entry with a level no greater than its component's maximum. A *mongoc\_structured\_log\_entry\_t* pointer provides access to further details, during the handler only.

Handlers must take care not to re-enter **libmongoc** with the same *mongoc\_client\_t* or *mongoc\_client\_pool\_t* that the handler has been called by.

### mongoc\_structured\_log\_func\_t

### Synopsis

```
typedef void (*mongoc_structured_log_func_t)
(const mongoc_structured_log_entry_t *entry, void *user_data);
```

Callback function for *mongoc\_structured\_log\_opts\_set\_handler()*. Structured log handlers must be thread-safe if they will be used with *mongoc\_client\_pool\_t*. Handlers must avoid unbounded recursion, preferably by avoiding the use of any **libmongoc** client or pool which uses the same handler.

### Parameters

- •

  **entry**: A *mongoc\_structured\_log\_entry\_t* pointer, only valid during the handler invocation.

- •

  **user\_data**: Optional user data from *mongoc\_structured\_log\_opts\_set\_handler()*.

**SEE ALSO:**

```
Structured Logging
```

### Log Entries

Each log entry is represented within the handler by a short-lived *mongoc\_structured\_log\_entry\_t* pointer. During the handler, this pointer can be used to access the individual properties of an entry: its level, component, and message.

The message will be assembled as a *bson\_t* only when explicitly requested by a call to *mongoc\_structured\_log\_entry\_message\_as\_bson()*. This results in a standalone document that may be retained for any amount of time and must be explicitly destroyed.

### mongoc\_structured\_log\_entry\_t

### Synopsis

```
typedef struct mongoc_structured_log_entry_t mongoc_structured_log_entry_t;
```

**mongoc\_structured\_log\_entry\_t** is an opaque structure which represents the temporary state of an in-progress log entry. It can only be used during a *mongoc\_structured\_log\_func\_t*, it is not valid after the log handler returns. Use the functions below to query individual aspects of the log entry.

### Functions

### mongoc\_structured\_log\_entry\_get\_component()

### Synopsis

```
mongoc_structured_log_component_t
mongoc_structured_log_entry_get_component (const mongoc_structured_log_entry_t *entry);
```

### Parameters

- •

  **entry**: A *mongoc\_structured\_log\_entry\_t* pointer.

### Returns

The *mongoc\_structured\_log\_component\_t* associated with this log entry.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_entry\_get\_level()

### Synopsis

```
mongoc_structured_log_level_t
mongoc_structured_log_entry_get_level (const mongoc_structured_log_entry_t *entry);
```

### Parameters

- •

  **entry**: A *mongoc\_structured\_log\_entry\_t* pointer.

### Returns

The *mongoc\_structured\_log\_level\_t* associated with this log entry.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_entry\_get\_message\_string()

### Synopsis

```
const char *
mongoc_structured_log_entry_get_message_string (const mongoc_structured_log_entry_t *entry);
```

### Parameters

- •

  **entry**: A *mongoc\_structured\_log\_entry\_t* pointer.

### Returns

A string, guaranteed to be valid only during the lifetime of the structured log handler. It should not be freed or modified.

Identical to the value of the **message** key in the document returned by *mongoc\_structured\_log\_entry\_message\_as\_bson()*.

This is not a complete string representation of the structured log, but rather a standardized identifier for a particular log event.

**SEE ALSO:**

```
Structured Logging
```

### mongoc\_structured\_log\_entry\_message\_as\_bson()

### Synopsis

```
bson_t *
mongoc_structured_log_entry_message_as_bson (const mongoc_structured_log_entry_t *entry);
```

Make a new copy, as a *bson\_t*, of the log entry's standardized BSON representation. When possible, a log handler should avoid serializing log messages that will be discarded. Each call allocates an independent copy of the message that must be freed.

### Parameters

- •

  **entry**: A *mongoc\_structured\_log\_entry\_t* pointer.

### Returns

A new allocated *bson\_t* that must be freed with a call to *bson\_destroy()*.

**SEE ALSO:**

```
Structured Logging
```

**SEE ALSO:**

```
Structured Logging
```

### Example

example-structured-log.c

```
/* gcc example-structured-log.c -o example-structured-log \
 *     $(pkg-config --cflags --libs libmongoc-1.0) */
#include <mongoc/mongoc.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
static pthread_mutex_t handler_mutex;
static void
example_handler (const mongoc_structured_log_entry_t *entry, void *user_data)
{
   mongoc_structured_log_component_t component = mongoc_structured_log_entry_get_component (entry);
   mongoc_structured_log_level_t level = mongoc_structured_log_entry_get_level (entry);
   const char *message_string = mongoc_structured_log_entry_get_message_string (entry);
   /*
    * With a single-threaded mongoc_client_t, handlers will always be called
    * by the thread that owns the client. On a mongoc_client_pool_t, handlers
    * are shared by multiple threads and must be reentrant.
    *
    * Note that unstructured logging includes a global mutex in the API,
    * but structured logging allows applications to avoid lock contention
    * even when multiple threads are issuing commands simultaneously.
    *
    * Simple apps like this example can achieve thread safety by adding their
    * own global mutex. For other apps, this would be a performance bottleneck
    * and it would be more appropriate for handlers to process their log
    * messages concurrently.
    *
    * In this example, our mutex protects access to a global log counter.
    * In a real application, you may need to protect access to a shared stream
    * or queue.
    */
   pthread_mutex_lock (&handler_mutex);
   static unsigned log_serial_number = 0;
   printf ("%u. Log entry with component=%s level=%s message_string='%s'\n",
           ++log_serial_number,
           mongoc_structured_log_get_component_name (component),
           mongoc_structured_log_get_level_name (level),
           message_string);
   /*
    * At this point, the handler might make additional filtering decisions
    * before asking for a bson_t. As an example, let's log the component and
    * level for all messages but only show contents for command logs.
    */
   if (component == MONGOC_STRUCTURED_LOG_COMPONENT_COMMAND) {
      bson_t *message = mongoc_structured_log_entry_message_as_bson (entry);
      char *json = bson_as_relaxed_extended_json (message, NULL);
      printf ("Full log message, as json: %s\n", json);
      bson_destroy (message);
      bson_free (json);
   }
   pthread_mutex_unlock (&handler_mutex);
}
int
main (void)
{
   const char *uri_string = "mongodb://localhost:27017";
   int result = EXIT_FAILURE;
   bson_error_t error;
   mongoc_uri_t *uri = NULL;
   mongoc_structured_log_opts_t *log_opts = NULL;
   mongoc_client_t *client = NULL;
   mongoc_client_pool_t *pool = NULL;
   /*
    * Note that structured logging only applies per-client or per-pool,
    * and it won't be used during or before mongoc_init.
    */
   mongoc_init ();
   /*
    * Logging options are represented by a mongoc_structured_log_opts_t,
    * which can be copied into a mongoc_client_t or mongoc_client_pool_t
    * using mongoc_client_set_structured_log_opts() or
    * mongoc_client_pool_set_structured_log_opts(), respectively.
    *
    * Default settings are captured from the environment into
    * this structure when it's constructed.
    */
   log_opts = mongoc_structured_log_opts_new ();
   /*
    * For demonstration purposes, set up a handler that receives all possible log messages.
    */
   pthread_mutex_init (&handler_mutex, NULL);
   mongoc_structured_log_opts_set_max_level_for_all_components (log_opts, MONGOC_STRUCTURED_LOG_LEVEL_TRACE);
   mongoc_structured_log_opts_set_handler (log_opts, example_handler, NULL);
   /*
    * By default libmongoc proceses log options from the environment first,
    * and then allows you to apply programmatic overrides. To request the
    * opposite behavior, allowing the environment to override programmatic
    * defaults, you can ask for the environment to be re-read after setting
    * your own defaults.
    */
   mongoc_structured_log_opts_set_max_levels_from_env (log_opts);
   /*
    * Create a MongoDB URI object. This example assumes a local server.
    */
   uri = mongoc_uri_new_with_error (uri_string, &error);
   if (!uri) {
      fprintf (stderr, "URI parse error: %s\n", error.message);
      goto done;
   }
   /*
    * Create a new client pool.
    */
   pool = mongoc_client_pool_new (uri);
   if (!pool) {
      goto done;
   }
   /*
    * Set the client pool's log options.
    * This must happen only once, and only before the first mongoc_client_pool_pop.
    * There's no need to keep log_opts after this point.
    */
   mongoc_client_pool_set_structured_log_opts (pool, log_opts);
   /*
    * Check out a client, and do some work that we'll see logs from.
    * This example just sends a 'ping' command.
    */
   client = mongoc_client_pool_pop (pool);
   if (!client) {
      goto done;
   }
   bson_t *command = BCON_NEW ("ping", BCON_INT32 (1));
   bson_t reply;
   bool command_ret = mongoc_client_command_simple (client, "admin", command, NULL, &reply, &error);
   bson_destroy (command);
   bson_destroy (&reply);
   mongoc_client_pool_push (pool, client);
   if (!command_ret) {
      fprintf (stderr, "Command error: %s\n", error.message);
      goto done;
   }
   result = EXIT_SUCCESS;
done:
   mongoc_uri_destroy (uri);
   mongoc_structured_log_opts_destroy (log_opts);
   mongoc_client_pool_destroy (pool);
   mongoc_cleanup ();
   return result;
}
```

**SEE ALSO:**

mongoc\_structured\_log\_entry\_get\_component mongoc\_structured\_log\_entry\_get\_level mongoc\_structured\_log\_entry\_message\_as\_bson

## AUTHOR

MongoDB, Inc

## COPYRIGHT

2009-present, MongoDB, Inc.
