MONGOC_STRUCTURED_LOG(3)

okay so welcome to MONGOC_STRUCTURED_LOG(3) from libmongoc, bestie ๐Ÿ’–. This page is all about the newer โ€œstructuredโ€ logging facility, which reports messages from the driver itself using a BSON format defined across driver implementations by the MongoDB Logging Specification. For the original freeform logging facility, go check out Unstructured Logging.

These two systems are configured and used independently, no cap. 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. Slay.

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. Itโ€™s giving โ€œeverything in one little handleโ€ energy.

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. Iconic.

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. Literally the chillest cleanup function.

๐Ÿฆ‹ 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. This is where you get main character energy and make logging do your thing.

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. iykyk.

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 โ€” true on success, bestie. ๐Ÿซถ But if there's warnings lurking in the environment, it returns false and may log extra info over to the unstructured logging facility. And like โ€” by design โ€” these errors are non-fatal by default, so don't panic ๐Ÿ˜Œ. Lowkey important detail: when mongoc_structured_log_opts_new() calls this function internally, it just ignores the return value entirely. Not even looking at it. ๐Ÿ’€
๐Ÿ”Ž 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: the log component you care about, as a mongoc_structured_log_component_t.

๐Ÿ’– Returns

Gives you back the configured max log level for that specific component, as a mongoc_structured_log_level_t. This could be the last value you set with mongoc_structured_log_opts_set_max_level_for_component() or mongoc_structured_log_opts_set_max_level_for_all_components(), or it might just be the default it picked up from environment variables. ๐ŸŒฑ And if you hand it an invalid or unknown component enum? It returns the lowest log level. No drama, no crash. ๐Ÿ’…

๐Ÿ”Ž 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);

Okay so this one sets a max length for BSON documents that show up serialized as JSON inside a structured log message. ๐Ÿ“

The serialized JSON gets truncated at that limit, and the limit is counted in UTF-8 encoded bytes. Truncation is marked with a ... suffix โ€” and the length of that suffix does not count toward the max document length, so don't come for me about the math. ๐Ÿงฎ Also, if truncating at the exact indicated length would split a valid UTF-8 sequence, it truncates the document earlier instead, at the nearest boundary between code points. Respectful. ๐Ÿซถ

๐ŸŽ€ Parameters

  • opts: structured log options, allocated with mongoc_structured_log_opts_new().
  • max_document_length: max length for each embedded JSON document, in bytes, not including the ellipsis (...) added to indicate truncation. Values near or above INT_MAX get rejected. ๐Ÿšซ

๐Ÿ’– Returns

true on success, or false if the length you supplied is too big. That's it. Simple. Slay.

๐Ÿ”Ž 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 max document length from the MONGODB_LOG_MAX_DOCUMENT_LENGTH environment variable โ€” but only if it finds a valid setting in there. ๐Ÿ‘€ Peep mongoc_structured_log_opts_new() for the whole rundown on the supported environment variable formats.

Heads up: parse errors may throw a warning message, delivered via unstructured logging. ๐Ÿ™ˆ

This happens automatically when mongoc_structured_log_opts_new() establishes defaults. And any programmatic modifications you make to the mongoc_structured_log_opts_t afterward will override whatever the environment variable said. ๐Ÿ†

Now โ€” for the apps that want the opposite vibe, where the environment variables get to override the programmatic settings? They can call mongoc_structured_log_opts_set_max_document_length_from_env() after calling mongoc_structured_log_opts_set_max_document_length(). That processes the environment a second time, letting it override your customized defaults. Iconic little loophole. ๐Ÿ’…

๐Ÿ’– Returns

true on success โ€” either it found a valid environment setting, or the value is unset and opts stays untouched. ๐ŸŽ€ If there's warnings in the environment it returns false and may log additional info to the unstructured logging facility. Again: by design, these errors are non-fatal by default. And again: when mongoc_structured_log_opts_new() internally calls this function, it ignores the return value. It does not care. ๐Ÿ’€

๐Ÿ”Ž 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

The current maximum document length set in opts, as a size_t. That's the whole function. Get you a function that just does its job. ๐Ÿ‘‘

๐Ÿ”Ž SEE ALSO: Structured Logging
๐Ÿ”Ž SEE ALSO: Structured Logging

๐ŸŒˆ LEVELS AND COMPONENTS ๐ŸŒˆ

So log levels and components are defined as the mongoc_structured_log_level_t and mongoc_structured_log_component_t enumerations, respectively. And because we're nice, there's utilities to convert between these values and their standard string representations. ๐ŸŽ€ The string values are case-insensitive, so go ahead and lowercase them, bestie, it won't be mad.

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 all the available log levels, for use with structured logging. Nine of them. A whole little ladder from "everything is on fire" to "tell me literally everything." ๐Ÿ”ฅ

๐Ÿ› ๏ธ 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, you get a pointer to a constant string โ€” and do not free it, bestie, it's not yours. ๐Ÿ™… If the level has no known name, you get 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);

Looks 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 gets 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. So check that bool, okay? ๐Ÿซถ

๐Ÿ”Ž 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. Real talk though โ€” applications should never rely on having an exhaustive list of all log components. ๐Ÿ˜ค The list can grow, and you don't want your code in shambles when it does. Instead, use mongoc_structured_log_opts_set_max_level_for_all_components() to set a default level if you need one. That's the move. โœจ

๐Ÿ› ๏ธ 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, you get a pointer to a constant string that should not be freed. If the component has no known name, you get NULL. Same rules as its level-name sibling. ๐Ÿ’œ

๐Ÿ”Ž 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);

Looks 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 gets 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. No cap. ๐Ÿซก

๐Ÿ”Ž 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 ๐Ÿ”ฅ

Every mongoc_client_pool_t or standalone mongoc_client_t gets its very own instance of the structured logging subsystem โ€” its own settings, its own handler. Main character energy, individually. ๐Ÿ‘‘

When you're using a mongoc_client_pool_t, all the pooled clients share one common logging instance. Which means: handlers must be thread-safe. โš ๏ธ Yes, really. Don't skip that part.

The handler gets called for each log entry whose level is no greater than its component's maximum. And the mongoc_structured_log_entry_t pointer gives you access to further details โ€” but only during the handler. After that? Gone. Poof. ๐Ÿ’€

โš ๏ธ Handlers must take care not to re-enter libmongoc with the same mongoc_client_t or mongoc_client_pool_t that the handler was called by. Just... don't do it. Please. ๐Ÿ™ˆ

๐Ÿฆ‹ mongoc_structured_log_func_t

โœจ Synopsis

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

This is the callback function for mongoc_structured_log_opts_set_handler(). ๐ŸŽ€ Structured log handlers must be thread-safe if they're going to be used with mongoc_client_pool_t. And handlers must avoid unbounded recursion โ€” preferably by avoiding the use of any libmongoc client or pool that uses the same handler. Like, just steer clear of that whole vibe. ๐ŸŒ€

๐ŸŽ€ Parameters

  • entry: a mongoc_structured_log_entry_t pointer, only valid during the handler invocation. Blink and it's gone. ๐Ÿ˜ญ
  • user_data: optional user data from mongoc_structured_log_opts_set_handler().
๐Ÿ”Ž SEE ALSO: Structured Logging

๐Ÿ’– LOG ENTRIES ๐Ÿ’–

okay so bestie, every log entry shows up inside the handler as a short-lived mongoc_structured_log_entry_t pointer. During the handler, that pointer lets you peek at the individual properties of an entry: its level, component, and message. ๐Ÿ‘‘

The message gets assembled as a bson_t only when you explicitly ask for it by calling mongoc_structured_log_entry_message_as_bson(). That gives you a standalone document that may be retained for any amount of time and must be explicitly destroyed. no cap, you gotta clean it up yourself. ๐Ÿงน

๐Ÿซถ 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 representing the temporary state of an in-progress log entry. It can only be used during a mongoc_structured_log_func_t, and 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. iykyk โ€” it's a label, not the whole story. ๐ŸŽ€

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)
{
   (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 processes 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

2009-present, MongoDB, Inc.

๐Ÿ’– and that's the whole page, bestie โ€” MONGOC_STRUCTURED_LOG(3), version 2.5.6, dated Oct 09, 2026. slay, go forth and log responsibly ๐Ÿ’…โœจ

๐Ÿ“ฆ where this page comes from