.NET · mongoDB

MongoDB Driver events

One of the new cool features of the mongoDB Driver is that you can hook up to events on mongoDB and do monitoring/logging for your application. In this post I will show you a simple ASP.NET MVC project with logging.

First of all, you need to get the project up and running and get the MongoDB.Driver from NuGet. You can check out the sample project here. If you are new to mongoDB Driver you can read more here.

In short, what you do is create an instance of CarContext in your CarController. You will probably use an IOC container for this on a real project, but for this sample, I will just put this in the CarController. The important thing is that it is thread safe and only initiated once.

public static CarContext Context = new CarContext();

The CarContext is the place you will set up connection and communication to mongoDB. In production you will probably create a generic repository, but I am trying to make this sample very simple. In the constructer of CarContext, create a new client for the mongo connection and connection to the mongoDB.

public class CarContext
{
  public IMongoDatabase Database;
 
  public CarContext()
   {
     var client = new MongoClient("mongodb://localhost");
     Database = client.GetDatabase("DemoEvents");
   }
 
  public IMongoCollection<Car> Cars => Database.GetCollection<Car>("Cars");
 
}

You do not need to set up or create the database before running the application. MongoDB Driver will do that for you.

If you do not want to work on mongoDB using the shell, I recommend you to install a tool like RoboMongo.

Now make sure you set your profiling level on you database so we can start diagnosing database interactions. If you want to know more about profiling you can read this post.

Connect to you database with Robomongo, right click your database to open shell and type: “db.setProfilingLevel(2)”

me1

If you now run the application to get some queries executed and then in the shell in Robomongo type: “.system.profile.find()” you will get analytic data for the queries in mongoDB.

me2

Now let us wire up the event subscription with mongoDB Driver. First, we need to change our overload on MongoClient in CarContext from just being a connection string to a MongoClientSettings object. Next, on our mongoSettings object we need to set up the CluserConfigurator, which is a delegate to set up the configuration. This gives us access to include the event subscription.

me3

To start easy I will only specify the CommandStartedEvent that represents the start of any event that will be executed against the server.

If you go to “Post Car” page and add a car, and set a breakpoint on to event, you will catch the Insert Command from your application.

 

public CarContext()
        {
            var mongoSettings = MongoClientSettings.FromUrl(new MongoUrl("mongodb:// localhost:27017/DemoEvents"));
            mongoSettings.ClusterConfigurator = builder => builder.Subscribe<CommandStartedEvent>(md =>
            {
            });
            var client = new MongoClient(mongoSettings);
            Database = client.GetDatabase("DemoEvents");
        }

 

If you want to subscribe to multiple events, you can implement your own event subscriber like this:

mongoSettings.ClusterConfigurator = builder => builder.Subscribe(new LogMongeEvents());
public class LogMongeEvents : IEventSubscriber
    {
        public bool TryGetEventHandler<TEvent>(out Action<TEvent> handler)
        {
            handler = e =>
            {
                // log any event
            };
            return true;
        }
    }

 

If you want to subscribe for spesiffic event handler you can use a ReflectionEventSubscriber like this:

 

public class LogMongeEvents : IEventSubscriber
    {
        private ReflectionEventSubscriber eventSubscriber;
 
        public LogMongeEvents()
        {
            eventSubscriber = new ReflectionEventSubscriber(this);
        }
 
        public bool TryGetEventHandler<TEvent>(out Action<TEvent> handler)
        {
            return eventSubscriber.TryGetEventHandler(out handler);
        }
 
        public void Handle(CommandStartedEvent startedEvent)
        {
            // log for started Event
        }
    }

 

Thanks for reading