Cluster Monitoring
On this page
Overview
This guide shows you how to use the Ruby driver to monitor server discovery and monitoring (SDAM) events in a MongoDB instance, replica set, or sharded cluster by using custom subscribers or available subscriber methods. These events occur when there are changes in the state of the MongoDB instance or cluster that you are connected to.
You can use information about SDAM events in your application to understand cluster changes, assess cluster health, or perform capacity planning.
SDAM Subscribers
You can use the Ruby driver's subscribe
method to subscribe to events.
Pass a monitoring topic, which defines the monitoring event type, and a subscriber
object as arguments to the subscribe
method.
The following code uses the ServerOpeningLogSubscriber
subscriber to monitor a connection
to a server instance. You can subscribe to events at a global level, which monitors
all clients of a cluster, or at the client level:
subscriber = Mongo::Monitoring::ServerOpeningLogSubscriber.new # Globally subscribes to ServerOpening events by using the SERVER_OPENING monitoring topic Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::SERVER_OPENING, subscriber) client = Mongo::Client.new(['127.0.0.1:27017']) # Subscribes to ServerOpening events at the client level by using the SERVER_OPENING monitoring topic client.subscribe( Mongo::Monitoring::SERVER_OPENING, subscriber )
The following table provides available subscribers and their monitoring topic:
Subscriber Name | Monitoring Topic | Description |
---|---|---|
| Subscribes to | |
| Subscribes to | |
| Subscribes to | |
| Subscribes to | |
| Subscribes to | |
| Subscribes to |
You can find a table of SDAM event descriptions in the Event Descriptions section on this page.
Custom SDAM Monitoring
You can create a custom SDAM subscriber to access details about server and topology events. Create a separate class for each event type, as available data for each event varies.
For all events, the subscriber calls the succeeded
method and passes the event
as an argument. A simple SDAM logging subscriber can look
like the following code:
class SDAMLogSubscriber include Mongo::Loggable def succeeded(event) log_debug(format_event(event)) end private def logger Mongo::Logger.logger end def format_message(message) format("SDAM | %s", message) end end class TopologyOpeningLogSubscriber < SDAMLogSubscriber private def format_event(event) "Topology type '#{event.topology.display_name}' initializing." end end class ServerOpeningLogSubscriber < SDAMLogSubscriber private def format_event(event) "Server #{event.address} initializing." end end class ServerDescriptionChangedLogSubscriber < SDAMLogSubscriber private def format_event(event) "Server description for #{event.address} changed from " + "'#{event.previous_description.server_type}' to '#{event.new_description.server_type}'." end end class TopologyChangedLogSubscriber < SDAMLogSubscriber private def format_event(event) if event.previous_topology != event.new_topology "Topology type '#{event.previous_topology.display_name}' changed to " + "type '#{event.new_topology.display_name}'." else "There was a change in the members of the '#{event.new_topology.display_name}' " + "topology." end end end class ServerClosedLogSubscriber < SDAMLogSubscriber private def format_event(event) "Server #{event.address} connection closed." end end class TopologyClosedLogSubscriber < SDAMLogSubscriber private def format_event(event) "Topology type '#{event.topology.display_name}' closed." end end
To subscribe to events, create the appropriate subscriber and subscribe to the correct monitoring topic. The following code shows how to subscribe to SDAM events globally:
topology_opening_subscriber = TopologyOpeningLogSubscriber.new server_opening_subscriber = ServerOpeningLogSubscriber.new server_description_changed_subscriber = ServerDescriptionChangedLogSubscriber.new topology_changed_subscriber = TopologyChangedLogSubscriber.new server_closed_subscriber = ServerClosedLogSubscriber.new topology_closed_subscriber = TopologyClosedLogSubscriber.new Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::TOPOLOGY_OPENING, topology_opening_subscriber) Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::SERVER_OPENING, server_opening_subscriber) Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::SERVER_DESCRIPTION_CHANGED, server_description_changed_subscriber) Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::TOPOLOGY_CHANGED, topology_changed_subscriber) Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::SERVER_CLOSED, server_closed_subscriber) Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::TOPOLOGY_CLOSED, topology_closed_subscriber)
The following code shows how to subscribe to SDAM events for a single client
by using the sdam-proc
client option:
topology_opening_subscriber = TopologyOpeningLogSubscriber.new server_opening_subscriber = ServerOpeningLogSubscriber.new server_description_changed_subscriber = ServerDescriptionChangedLogSubscriber.new topology_changed_subscriber = TopologyChangedLogSubscriber.new server_closed_subscriber = ServerClosedLogSubscriber.new topology_closed_subscriber = TopologyClosedLogSubscriber.new sdam_proc = Proc.new do |client| client.subscribe(Mongo::Monitoring::TOPOLOGY_OPENING, topology_opening_subscriber) client.subscribe(Mongo::Monitoring::SERVER_OPENING, server_opening_subscriber) client.subscribe(Mongo::Monitoring::SERVER_DESCRIPTION_CHANGED, server_description_changed_subscriber) client.subscribe(Mongo::Monitoring::TOPOLOGY_CHANGED, topology_changed_subscriber) client.subscribe(Mongo::Monitoring::SERVER_CLOSED, server_closed_subscriber) client.subscribe(Mongo::Monitoring::TOPOLOGY_CLOSED, topology_closed_subscriber) end client = Mongo::Client.new(['127.0.0.1:27017'], database: 'test', sdam_proc: sdam_proc)
Note
The :sdam_proc
client option applies only to the given client.
When certain client options are changed by using the
Client#with
call, the driver may create a new cluster with
a default set of event subscribers. If this happens, the provided
:sdam_proc
is not called, and the application may miss events.
When you run the application, your subscriber records the SDAM event and outputs messages such as the following:
D, [2018-10-09T13:58:03.489461 #22079] DEBUG -- : SDAM | Topology type 'Unknown' initializing. D, [2018-10-09T13:58:03.489699 #22079] DEBUG -- : SDAM | Server 127.0.0.1:27100 initializing. D, [2018-10-09T13:58:03.491384 #22079] DEBUG -- : SDAM | Server description for 127.0.0.1:27100 changed from 'unknown' to 'unknown'. D, [2018-10-09T13:58:03.491642 #22079] DEBUG -- : SDAM | Server localhost:27100 initializing. D, [2018-10-09T13:58:03.493199 #22079] DEBUG -- : SDAM | Server description for localhost:27100 changed from 'unknown' to 'primary'. D, [2018-10-09T13:58:03.493473 #22079] DEBUG -- : SDAM | Server localhost:27101 initializing. D, [2018-10-09T13:58:03.494874 #22079] DEBUG -- : SDAM | Server description for localhost:27101 changed from 'unknown' to 'secondary'. D, [2018-10-09T13:58:03.495139 #22079] DEBUG -- : SDAM | Server localhost:27102 initializing. D, [2018-10-09T13:58:03.496504 #22079] DEBUG -- : SDAM | Server description for localhost:27102 changed from 'unknown' to 'secondary'. D, [2018-10-09T13:58:03.496777 #22079] DEBUG -- : SDAM | Topology type 'Unknown' changed to type 'ReplicaSetNoPrimary'. D, [2018-10-09T13:58:03.497306 #22079] DEBUG -- : SDAM | Server 127.0.0.1:27100 connection closed. D, [2018-10-09T13:58:03.497606 #22079] DEBUG -- : SDAM | Topology type 'ReplicaSetNoPrimary' changed to type 'ReplicaSetWithPrimary'. # client.close D, [2018-10-09T13:58:05.342057 #22079] DEBUG -- : SDAM | Server localhost:27100 connection closed. D, [2018-10-09T13:58:05.342299 #22079] DEBUG -- : SDAM | Server localhost:27101 connection closed. D, [2018-10-09T13:58:05.342565 #22079] DEBUG -- : SDAM | Server localhost:27102 connection closed. D, [2018-10-09T13:58:05.342693 #22079] DEBUG -- : SDAM | Topology type 'ReplicaSetWithPrimary' closed.
Server Heartbeats
You can also create a custom subscriber to monitor server heartbeats, which occur
when the server monitor sends a hello
command to the server.
Custom server heartbeat subscribers differ from other SDAM subscribers, as they must implement the following three methods:
started
: Invoked when the listener receives the heartbeatsucceeded
: Response for a successful heartbeat outcomefailed
: Response for a failed heartbeat outcome
The following example shows a heartbeat event subscriber:
class HeartbeatLogSubscriber include Mongo::Loggable def started(event) log_debug("#{event.address} | STARTED") end def succeeded(event) log_debug("#{event.address} | SUCCEEDED | #{event.duration}s") end def failed(event) log_debug("#{event.address} | FAILED | #{event.error.class}: #{event.error.message} | #{event.duration}s") end private def logger Mongo::Logger.logger end def format_message(message) format("HEARTBEAT | %s", message) end end
You can subscribe to heartbeat events globally or for a specific client, as shown in the following example:
subscriber = HeartbeatLogSubscriber.new # Globally subscribes to Server Opening events Mongo::Monitoring::Global.subscribe(Mongo::Monitoring::SERVER_HEARTBEAT, subscriber) # Subscribes to Server Opening events at the client level client = Mongo::Client.new([ '127.0.0.1:27017' ], database: 'test' ) client.subscribe( Mongo::Monitoring::SERVER_HEARTBEAT, subscriber )
When you run the application, your subscriber records the heartbeat event and outputs messages such as the following:
D, [2018-09-23T13:44:10.707018 #1739] DEBUG -- : HEARTBEAT | 127.0.0.1:27027 | STARTED D, [2018-09-23T13:44:10.707778 #1739] DEBUG -- : HEARTBEAT | 127.0.0.1:27027 | SUCCEEDED | 0.000772381s
Event Descriptions
The following table provides the name and description of each SDAM event:
Event Type | Description |
---|---|
Event created when the server instance is closed. | |
Event created when a server's description changes. | |
Event created when a server heartbeat fails. | |
Event created when a server heartbeat is received by the listener. | |
Event created when a server heartbeat succeeds. | |
Event created when the driver connects to the server. | |
Event created when the topology changes. | |
Event created when all instance connections in the topology close. | |
Event created before the driver attempts to connect to an instance. |
API Documentation
To learn more about any of the classes or methods discussed in this guide, see the following API documentation: