Monitoring MongoDB with Application Insights

At LivingLens we have the somewhat dubious blessing of using MongoDB as our database. Historically we used to use LogEntries for our logging and it worked pretty nicely but these days we’re using Application Insights. One of the great features of application insights is the Application Map which generates a visual representation of your application and its dependencies. In the screenshot below you can see a browser application talking to a server which in turn is talking to a SQL Server database.
Application Map: SQL Only
That map is auto generated and you can click through into any part to filter and drill down to the details of the data. you can see that the database is identified as an external SQL dependency and I wanted the same for Mongo.

  1. To log all MongoDB calls to Application Insights
  2. To categorise that logged data as an external database dependency

Fortunately Application Insights provides the TrackDependency method to ‘track the response times and success rates of calls to an external piece of code’. So by extending the logger we’re using I can easily log dependency data.

public class Logger { public static void SendTelemetry(string message, DateTimeOffset startTime, TimeSpan duration, bool success) { var telemetryClient = new TelemetryClient(); telemetryClient.TrackDependency("MongoDB", message, startTime, duration, success); } }

Even more fortunately the MongoDB driver exposes a ClusterConfigrator which allows you to subscribe to events when you are creating a MongoClient instance. This is a little more involved than simply creating a MongoClient by passing it a connection string but it’s still pretty painless.

var connectionString = connectionStringSettings.ConnectionString; 
var mongoUrl = new MongoUrl(connectionString); 
var mongoClientSettings = MongoClientSettings.FromUrl(mongoUrl);
mongoClientSettings.ClusterConfigurator = clusterConfigurator => 
{
    clusterConfigurator.Subscribe<CommandSucceededEvent>(e => 
    { 
        // Log a successful dependency event on every CommandSucceededEvent
        Logger.SendTelemetry(e.CommandName, DateTime.Now.Subtract(e.Duration), e.Duration, true);
    });
    clusterConfigurator.Subscribe<CommandFailedEvent>(e => 
    {
        // Log a failed dependency event on every CommandFailedEvent 
        Logger.SendTelemetry($"{e.CommandName} - {e.ToString()}", DateTime.Now.Subtract(e.Duration), e.Duration, false);
    }); 
}; 
var mongoClient = new MongoClient(mongoClientSettings);

And now when I look at the Application Map I can see and drill down into the details of every success and failure event raised by Mongo.
Application Map: SQL And Mongo
Sweet!