Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
MONGOC_APPLIC...NCE_MONITORING(3)  libmongoc MONGOC_APPLIC...NCE_MONITORING(3)

The MongoDB C Driver allows you	to monitor all the MongoDB operations the dri-
ver  executes.	This  event-notification system	conforms to two	MongoDB	driver
specs:

        Command Logging and Monitoring: events	related	to all application op-
	 erations.

        SDAM Monitoring: events related to the	driver's Server	Discovery  And
	 Monitoring logic.

       To   receive   notifications,   create  a  mongoc_apm_callbacks_t  with
       mongoc_apm_callbacks_new(), set	callbacks  on  it,  then  pass	it  to
       mongoc_client_set_apm_callbacks()				    or
       mongoc_client_pool_set_apm_callbacks().

COMMAND-MONITORING EXAMPLE
       example-command-monitoring.c

	  /* gcc example-command-monitoring.c -o example-command-monitoring \
	   *	 $(pkg-config --cflags --libs libmongoc-1.0) */

	  /* ./example-command-monitoring [CONNECTION_STRING] */

	  #include <mongoc/mongoc.h>
	  #include <stdio.h>

	  typedef struct {
	     int started;
	     int succeeded;
	     int failed;
	  } stats_t;

	  void
	  command_started (const mongoc_apm_command_started_t *event)
	  {
	     char *s;

	     s = bson_as_relaxed_extended_json (mongoc_apm_command_started_get_command (event),	NULL);
	     printf ("Command %s started on %s:\n%s\n\n",
		     mongoc_apm_command_started_get_command_name (event),
		     mongoc_apm_command_started_get_host (event)->host,
		     s);

	     ((stats_t *) mongoc_apm_command_started_get_context (event))->started++;

	     bson_free (s);
	  }

	  void
	  command_succeeded (const mongoc_apm_command_succeeded_t *event)
	  {
	     char *s;

	     s = bson_as_relaxed_extended_json (mongoc_apm_command_succeeded_get_reply (event),	NULL);
	     printf ("Command %s succeeded:\n%s\n\n", mongoc_apm_command_succeeded_get_command_name (event), s);

	     ((stats_t *) mongoc_apm_command_succeeded_get_context (event))->succeeded++;

	     bson_free (s);
	  }

	  void
	  command_failed (const	mongoc_apm_command_failed_t *event)
	  {
	     bson_error_t error;

	     mongoc_apm_command_failed_get_error (event, &error);
	     printf ("Command %s failed:\n\"%s\"\n\n", mongoc_apm_command_failed_get_command_name (event), error.message);

	     ((stats_t *) mongoc_apm_command_failed_get_context	(event))->failed++;
	  }

	  int
	  main (int argc, char *argv[])
	  {
	     mongoc_client_t *client;
	     mongoc_apm_callbacks_t *callbacks;
	     stats_t stats = {0};
	     mongoc_collection_t *collection;
	     bson_error_t error;
	     const char	*uri_string = "mongodb://127.0.0.1/?appname=cmd-monitoring-example";
	     mongoc_uri_t *uri;
	     const char	*collection_name = "test";
	     bson_t *docs[2];

	     mongoc_init ();

	     if	(argc >	1) {
		uri_string = argv[1];
	     }

	     uri = mongoc_uri_new_with_error (uri_string, &error);
	     if	(!uri) {
		fprintf	(stderr,
			 "failed to parse URI: %s\n"
			 "error	message:       %s\n",
			 uri_string,
			 error.message);
		return EXIT_FAILURE;
	     }

	     client = mongoc_client_new_from_uri (uri);
	     if	(!client) {
		return EXIT_FAILURE;
	     }

	     mongoc_client_set_error_api (client, 2);
	     callbacks = mongoc_apm_callbacks_new ();
	     mongoc_apm_set_command_started_cb (callbacks, command_started);
	     mongoc_apm_set_command_succeeded_cb (callbacks, command_succeeded);
	     mongoc_apm_set_command_failed_cb (callbacks, command_failed);
	     mongoc_client_set_apm_callbacks (client, callbacks, (void *) &stats /* context pointer */);

	     collection	= mongoc_client_get_collection (client,	"test",	collection_name);
	     mongoc_collection_drop (collection, NULL);

	     docs[0] = BCON_NEW	("_id",	BCON_INT32 (0));
	     docs[1] = BCON_NEW	("_id",	BCON_INT32 (1));
	     mongoc_collection_insert_many (collection,	(const bson_t **) docs,	2, NULL, NULL, NULL);

	     /*	duplicate key error on the second insert */
	     mongoc_collection_insert_one (collection, docs[0],	NULL, NULL, NULL);

	     mongoc_collection_destroy (collection);
	     mongoc_apm_callbacks_destroy (callbacks);
	     mongoc_uri_destroy	(uri);
	     mongoc_client_destroy (client);

	     printf ("started: %d\nsucceeded: %d\nfailed: %d\n", stats.started,	stats.succeeded, stats.failed);

	     bson_destroy (docs[0]);
	     bson_destroy (docs[1]);

	     mongoc_cleanup ();

	     return EXIT_SUCCESS;
	  }

       This example program prints:

	  Command drop started on 127.0.0.1:
	  { "drop" : "test" }

	  Command drop succeeded:
	  { "ns" : "test.test",	"nIndexesWas" :	1, "ok"	: 1.0 }

	  Command insert started on 127.0.0.1:
	  {
	    "insert" : "test",
	    "ordered" :	true,
	    "documents"	: [
	      {	"_id" :	0 }, { "_id" : 1 }
	    ]
	  }

	  Command insert succeeded:
	  { "n"	: 2, "ok" : 1.0	}

	  Command insert started on 127.0.0.1:
	  {
	    "insert" : "test",
	    "ordered" :	true,
	    "documents"	: [
	      {	"_id" :	0 }
	    ]
	  }

	  Command insert succeeded:
	  {
	    "n"	: 0,
	    "writeErrors" : [
	      {	"index"	: 0, "code" : 11000, "errmsg" :	"duplicate key"	}
	    ],
	    "ok" : 1.0
	  }

	  started: 3
	  succeeded: 3
	  failed: 0

       The output has been edited and formatted	for clarity. Depending on your
       server configuration, messages may include metadata like	database name,
       logical session ids, or cluster times that are not shown	here.

       The final  "insert"  command  is	 considered  successful,  despite  the
       writeError,  because  the  server  replied  to the overall command with
       "ok": 1.

SDAM MONITORING	EXAMPLE
       example-sdam-monitoring.c

	  /* gcc example-sdam-monitoring.c -o example-sdam-monitoring \
	   *	 $(pkg-config --cflags --libs libmongoc-1.0) */

	  /* ./example-sdam-monitoring [CONNECTION_STRING] */

	  #include <mongoc/mongoc.h>
	  #include <stdio.h>

	  typedef struct {
	     int server_changed_events;
	     int server_opening_events;
	     int server_closed_events;
	     int topology_changed_events;
	     int topology_opening_events;
	     int topology_closed_events;
	     int heartbeat_started_events;
	     int heartbeat_succeeded_events;
	     int heartbeat_failed_events;
	  } stats_t;

	  static void
	  server_changed (const	mongoc_apm_server_changed_t *event)
	  {
	     stats_t *context;
	     const mongoc_server_description_t *prev_sd, *new_sd;

	     context = (stats_t	*) mongoc_apm_server_changed_get_context (event);
	     context->server_changed_events++;

	     prev_sd = mongoc_apm_server_changed_get_previous_description (event);
	     new_sd = mongoc_apm_server_changed_get_new_description (event);

	     printf ("server changed: %s %s -> %s\n",
		     mongoc_apm_server_changed_get_host	(event)->host_and_port,
		     mongoc_server_description_type (prev_sd),
		     mongoc_server_description_type (new_sd));
	  }

	  static void
	  server_opening (const	mongoc_apm_server_opening_t *event)
	  {
	     stats_t *context;

	     context = (stats_t	*) mongoc_apm_server_opening_get_context (event);
	     context->server_opening_events++;

	     printf ("server opening: %s\n", mongoc_apm_server_opening_get_host	(event)->host_and_port);
	  }

	  static void
	  server_closed	(const mongoc_apm_server_closed_t *event)
	  {
	     stats_t *context;

	     context = (stats_t	*) mongoc_apm_server_closed_get_context	(event);
	     context->server_closed_events++;

	     printf ("server closed: %s\n", mongoc_apm_server_closed_get_host (event)->host_and_port);
	  }

	  static void
	  topology_changed (const mongoc_apm_topology_changed_t	*event)
	  {
	     stats_t *context;
	     const mongoc_topology_description_t *prev_td;
	     const mongoc_topology_description_t *new_td;
	     mongoc_server_description_t **prev_sds;
	     size_t n_prev_sds;
	     mongoc_server_description_t **new_sds;
	     size_t n_new_sds;
	     size_t i;
	     mongoc_read_prefs_t *prefs;

	     context = (stats_t	*) mongoc_apm_topology_changed_get_context (event);
	     context->topology_changed_events++;

	     prev_td = mongoc_apm_topology_changed_get_previous_description (event);
	     prev_sds =	mongoc_topology_description_get_servers	(prev_td, &n_prev_sds);
	     new_td = mongoc_apm_topology_changed_get_new_description (event);
	     new_sds = mongoc_topology_description_get_servers (new_td,	&n_new_sds);

	     printf ("topology changed:	%s -> %s\n",
		     mongoc_topology_description_type (prev_td),
		     mongoc_topology_description_type (new_td));

	     if	(n_prev_sds) {
		printf ("  previous servers:\n");
		for (i = 0; i <	n_prev_sds; i++) {
		   printf ("	  %s %s\n",
			   mongoc_server_description_type (prev_sds[i]),
			   mongoc_server_description_host (prev_sds[i])->host_and_port);
		}
	     }

	     if	(n_new_sds) {
		printf ("  new servers:\n");
		for (i = 0; i <	n_new_sds; i++)	{
		   printf ("	  %s %s\n",
			   mongoc_server_description_type (new_sds[i]),
			   mongoc_server_description_host (new_sds[i])->host_and_port);
		}
	     }

	     prefs = mongoc_read_prefs_new (MONGOC_READ_SECONDARY);

	     if	(mongoc_topology_description_has_readable_server (new_td, prefs)) {
		printf ("  secondary AVAILABLE\n");
	     } else {
		printf ("  secondary UNAVAILABLE\n");
	     }

	     if	(mongoc_topology_description_has_writable_server (new_td)) {
		printf ("  primary AVAILABLE\n");
	     } else {
		printf ("  primary UNAVAILABLE\n");
	     }

	     mongoc_read_prefs_destroy (prefs);
	     mongoc_server_descriptions_destroy_all (prev_sds, n_prev_sds);
	     mongoc_server_descriptions_destroy_all (new_sds, n_new_sds);
	  }

	  static void
	  topology_opening (const mongoc_apm_topology_opening_t	*event)
	  {
	     stats_t *context;

	     context = (stats_t	*) mongoc_apm_topology_opening_get_context (event);
	     context->topology_opening_events++;

	     printf ("topology opening\n");
	  }

	  static void
	  topology_closed (const mongoc_apm_topology_closed_t *event)
	  {
	     stats_t *context;

	     context = (stats_t	*) mongoc_apm_topology_closed_get_context (event);
	     context->topology_closed_events++;

	     printf ("topology closed\n");
	  }

	  static void
	  server_heartbeat_started (const mongoc_apm_server_heartbeat_started_t	*event)
	  {
	     stats_t *context;

	     context = (stats_t	*) mongoc_apm_server_heartbeat_started_get_context (event);
	     context->heartbeat_started_events++;

	     printf ("%s heartbeat started\n", mongoc_apm_server_heartbeat_started_get_host (event)->host_and_port);
	  }

	  static void
	  server_heartbeat_succeeded (const mongoc_apm_server_heartbeat_succeeded_t *event)
	  {
	     stats_t *context;
	     char *reply;

	     context = (stats_t	*) mongoc_apm_server_heartbeat_succeeded_get_context (event);
	     context->heartbeat_succeeded_events++;

	     reply = bson_as_canonical_extended_json (mongoc_apm_server_heartbeat_succeeded_get_reply (event), NULL);

	     printf (
		"%s heartbeat succeeded: %s\n",	mongoc_apm_server_heartbeat_succeeded_get_host (event)->host_and_port, reply);

	     bson_free (reply);
	  }

	  static void
	  server_heartbeat_failed (const mongoc_apm_server_heartbeat_failed_t *event)
	  {
	     stats_t *context;
	     bson_error_t error;

	     context = (stats_t	*) mongoc_apm_server_heartbeat_failed_get_context (event);
	     context->heartbeat_failed_events++;
	     mongoc_apm_server_heartbeat_failed_get_error (event, &error);

	     printf (
		"%s heartbeat failed: %s\n", mongoc_apm_server_heartbeat_failed_get_host (event)->host_and_port, error.message);
	  }

	  int
	  main (int argc, char *argv[])
	  {
	     mongoc_client_t *client;
	     mongoc_apm_callbacks_t *cbs;
	     stats_t stats = {0};
	     const char	*uri_string = "mongodb://127.0.0.1/?appname=sdam-monitoring-example";
	     mongoc_uri_t *uri;
	     bson_t cmd	= BSON_INITIALIZER;
	     bson_t reply;
	     bson_error_t error;

	     mongoc_init ();

	     if	(argc >	1) {
		uri_string = argv[1];
	     }

	     uri = mongoc_uri_new_with_error (uri_string, &error);
	     if	(!uri) {
		fprintf	(stderr,
			 "failed to parse URI: %s\n"
			 "error	message:       %s\n",
			 uri_string,
			 error.message);
		return EXIT_FAILURE;
	     }

	     client = mongoc_client_new_from_uri (uri);
	     if	(!client) {
		return EXIT_FAILURE;
	     }

	     mongoc_client_set_error_api (client, 2);
	     cbs = mongoc_apm_callbacks_new ();
	     mongoc_apm_set_server_changed_cb (cbs, server_changed);
	     mongoc_apm_set_server_opening_cb (cbs, server_opening);
	     mongoc_apm_set_server_closed_cb (cbs, server_closed);
	     mongoc_apm_set_topology_changed_cb	(cbs, topology_changed);
	     mongoc_apm_set_topology_opening_cb	(cbs, topology_opening);
	     mongoc_apm_set_topology_closed_cb (cbs, topology_closed);
	     mongoc_apm_set_server_heartbeat_started_cb	(cbs, server_heartbeat_started);
	     mongoc_apm_set_server_heartbeat_succeeded_cb (cbs,	server_heartbeat_succeeded);
	     mongoc_apm_set_server_heartbeat_failed_cb (cbs, server_heartbeat_failed);
	     mongoc_client_set_apm_callbacks (client, cbs, (void *) &stats /* context pointer */);

	     /*	the driver connects on demand to perform first operation */
	     BSON_APPEND_INT32 (&cmd, "buildinfo", 1);
	     mongoc_client_command_simple (client, "admin", &cmd, NULL,	&reply,	&error);
	     mongoc_uri_destroy	(uri);
	     mongoc_client_destroy (client);

	     printf ("Events:\n"
		     "	 server	changed: %d\n"
		     "	 server	opening: %d\n"
		     "	 server	closed:	%d\n"
		     "	 topology changed: %d\n"
		     "	 topology opening: %d\n"
		     "	 topology closed: %d\n"
		     "	 heartbeat started: %d\n"
		     "	 heartbeat succeeded: %d\n"
		     "	 heartbeat failed: %d\n",
		     stats.server_changed_events,
		     stats.server_opening_events,
		     stats.server_closed_events,
		     stats.topology_changed_events,
		     stats.topology_opening_events,
		     stats.topology_closed_events,
		     stats.heartbeat_started_events,
		     stats.heartbeat_succeeded_events,
		     stats.heartbeat_failed_events);

	     bson_destroy (&cmd);
	     bson_destroy (&reply);
	     mongoc_apm_callbacks_destroy (cbs);

	     mongoc_cleanup ();

	     return EXIT_SUCCESS;
	  }

       Start a 3-node replica set on localhost with set	name  "rs"  and	 start
       the program:

	  ./example-sdam-monitoring "mongodb://localhost:27017,localhost:27018/?replicaSet=rs"

       This example program prints something like:

	  topology opening
	  topology changed: Unknown -> ReplicaSetNoPrimary
	    secondary UNAVAILABLE
	    primary UNAVAILABLE
	  server opening: localhost:27017
	  server opening: localhost:27018
	  localhost:27017 heartbeat started
	  localhost:27018 heartbeat started
	  localhost:27017 heartbeat succeeded: { ... reply ... }
	  server changed: localhost:27017 Unknown -> RSPrimary
	  server opening: localhost:27019
	  topology changed: ReplicaSetNoPrimary	-> ReplicaSetWithPrimary
	    new	servers:
		RSPrimary localhost:27017
	    secondary UNAVAILABLE
	    primary AVAILABLE
	  localhost:27019 heartbeat started
	  localhost:27018 heartbeat succeeded: { ... reply ... }
	  server changed: localhost:27018 Unknown -> RSSecondary
	  topology changed: ReplicaSetWithPrimary -> ReplicaSetWithPrimary
	    previous servers:
		RSPrimary localhost:27017
	    new	servers:
		RSPrimary localhost:27017
		RSSecondary localhost:27018
	    secondary AVAILABLE
	    primary AVAILABLE
	  localhost:27019 heartbeat succeeded: { ... reply ... }
	  server changed: localhost:27019 Unknown -> RSSecondary
	  topology changed: ReplicaSetWithPrimary -> ReplicaSetWithPrimary
	    previous servers:
		RSPrimary localhost:27017
		RSSecondary localhost:27018
	    new	servers:
		RSPrimary localhost:27017
		RSSecondary localhost:27018
		RSSecondary localhost:27019
	    secondary AVAILABLE
	    primary AVAILABLE
	  topology closed

	  Events:
	     server changed: 3
	     server opening: 3
	     server closed: 0
	     topology changed: 4
	     topology opening: 1
	     topology closed: 1
	     heartbeat started:	3
	     heartbeat succeeded: 3
	     heartbeat failed: 0

       The driver connects to the mongods on ports 27017 and 27018, which were
       specified  in the URI, and determines which is primary. It also discov-
       ers the third member, "localhost:27019",	and adds it to the topology.

AUTHOR
       MongoDB,	Inc

COPYRIGHT
       2009-present, MongoDB, Inc.

1.30.2				 Apr 12, 2025MONGOC_APPLIC...NCE_MONITORING(3)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=mongoc_application_performance_monitoring&sektion=3&manpath=FreeBSD+Ports+14.3.quarterly>

home | help