Docs Menu
Docs Home
/ / /
Ruby MongoDB Driver
/

Cluster Monitoring

On this page

  • Overview
  • SDAM Subscribers
  • Custom SDAM Monitoring
  • Server Heartbeats
  • Event Descriptions
  • API Documentation

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.

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

ServerClosedLogSubscriber

SERVER_CLOSED

Subscribes to ServerClosed events and logs them.

SERVER_DESCRIPTION_CHANGED

Subscribes to ServerDescriptionChanged events and logs them.

SERVER_OPENING

Subscribes to ServerOpening events and logs them.

TOPOLOGY_CHANGED

Subscribes to TopologyChanged events and logs them.

TOPOLOGY_CLOSED

Subscribes to TopologyClosed events and logs them.

TOPOLOGY_OPENING

Subscribes to TopologyOpening events and logs them.

You can find a table of SDAM event descriptions in the Event Descriptions section on this page.

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.

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 heartbeat

  • succeeded: Response for a successful heartbeat outcome

  • failed: 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

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.

To learn more about any of the classes or methods discussed in this guide, see the following API documentation:

Back

Monitor Your Application