20

Just upgraded my application to the latest stable MongoDB C# Driver 2.0.

During the migration, basic functionality has been broken and even the simplest query like: this.collection.Find(e => e.Id == id).SingleOrDefaultAsync() doesn't return the correct data.

Checked the class mappings and conventions but I would like to see the output query in order to properly identify the issue.

So, how should it be done on the MongoClient side?

Setting profiling on the database level is possible but not a good solution since we have several applications and developers using the database.

My application is currently using Ninject.Extensions.Logging and log4net in the UI, business and EF data access.

Shay
  • 1,680
  • 2
  • 26
  • 39
  • 2
    Possible dupe of http://stackoverflow.com/questions/30306193/get-generated-script-in-mongodb-c-sharp-driver – JohnnyHK May 19 '15 at 20:03
  • "Setting profiling on the database is not a good since we have several developers using the database". huh? Can't you use a *local* database for debugging? Is that non-functioning application actually deployed? – mnemosyn May 19 '15 at 20:12
  • @mnemosyn I'm trying to create a functioning development environment so all developers can share. The database is feeding data from external app, and another app is reading that data. – Shay May 19 '15 at 20:20
  • @JohnnyHK - the second answer in your suggested dupe is a good one time solution for a specific query, but is there a logging solution for all app-wide queries? – Shay May 19 '15 at 20:25
  • "functioning development environment" and "developers can share [data]" sounds like a contradiction to me... – mnemosyn May 21 '15 at 15:33
  • @mnemosyn - Whether our development environment is functional to us or not, is our own decision. My question here is irrelevant to that. I am trying to log the queries and operations that are being executed by the MongoDB C# Driver. That should be possible whether the DB is shared or not. Just like in EF where you can output the SQL queries to whatever logging implementation you desire using DI. – Shay May 21 '15 at 21:21
  • @ShayNissel, did this get solved? There isn't a good way to log queries right now. We are working on something for 2.1. The best thing to do would be to do what is suggested in the linked "dupe" ticket. There are 2 ways mentioned there. On a separate note, are you waiting on the result? Simply calling SingleOrDefaultAsync() and not waiting on the result will cause everything to not work. – Craig Wilson May 27 '15 at 16:40
  • @CraigWilson, I didn't integrate logging into my MongoDB queries yet. When needed (for debugging) I use the redundant rendering suggestion from the "dupe". Waiting on 2.1 eagerly. About your Async question, I converted all my repositories and their calling services to use `async` and `await`. – Shay May 27 '15 at 17:43

3 Answers3

46

For newer C# MongoDB drivers the API has changed. You have to use the more complex constructor that accepts a MongoClientSettings object, instead of the connection string.

Use the following code to keep using a connection string, but enable the logging of each command:

var mongoConnectionUrl = new MongoUrl(connectionString);
var mongoClientSettings = MongoClientSettings.FromUrl(mongoConnectionUrl);
mongoClientSettings.ClusterConfigurator = cb => {
    cb.Subscribe<CommandStartedEvent>(e => {
        logger.Log($"{e.CommandName} - {e.Command.ToJson()}");
    });
};
var mongoCfgClient = new MongoClient(mongoClientSettings);
Ramon de Klein
  • 5,172
  • 2
  • 41
  • 64
6

Logging to VS output with 2.7.3 driver.

using MongoDB.Bson;
using MongoDB.Driver;
using System;
#if TRACE
using System.Diagnostics;
using MongoDB.Driver.Core.Configuration;
#endif

...

public static ClusterBuilder ConfigureCluster(ClusterBuilder builder)
{
#if TRACE
    var traceSource = new TraceSource(nameof(Geotagging), SourceLevels.Verbose);
    builder.TraceWith(traceSource);
    builder.TraceCommandsWith(traceSource);
#endif
    return builder;
}

public MongoClient BuildMongoClient(string connection_string)
{
    var mongoUrlBuilder = new MongoUrlBuilder(connection_string);
    var settings = MongoClientSettings.FromUrl(mongoUrlBuilder.ToMongoUrl());
    settings.ClusterConfigurator = cb => ConfigureCluster(cb);
    return new MongoClient(settings);
}
4

You can enable logging by the mongo driver itself:

var settings = new MongoClientSettings
{
    ClusterConfigurator = cb =>
    {
        var textWriter = TextWriter.Synchronized(new StreamWriter("mylogfile.txt"));
        cb.AddListener(new LogListener(textWriter));
    }
};

You can hook it up to log4net if you wish.

seldary
  • 6,186
  • 4
  • 40
  • 55