Zapewne każdy pracujący na dowolnym ORM-mie, nie zależnie czy komunikuje się z bazą danych za pomocą bibliotek, klas czy kawałka kodu zewnętrznego, ceni sobie możliwość podejrzenia w konsoli generowanych zapytań SQL. Chcąc ułatwić wam życie zademonstruje sposób logowania zapytań w kliencie csharp bazy MongoDB.
Dodanie opcji logowania na konsole
Najprostszym sposobem stworzenia klienta bazy MongoDB jest zastosowanie connection string-a. Wtedy kod wygląda następująco:
services.AddSigleton<IMongoClient>(new MongoClient("mongodb://localhost:27017/database"));
Trzeba pamiętać, że wraz ze wzrostem złożoności connection string-a, zapis zaczyna tracić na czytelności. Wystarczy dodać użytkownika bazy i hasło, aby sporo wydłużyć naszą linijkę kodu.
services.AddSigleton<IMongoClient>(new MongoClient("mongodb://user:password@localhost:27017/database"));
Łatwo zauważyć jeszcze jedna wadę. Nie możemy wykorzystać event-ów, danych nam przez mongo driver, aby np. wypisać wygenerowane zapytanie do mongo na konsole. Ok, więc olewamy i dziękuje za dzisiaj. A w następnym poście... Nie no ok, podaje sposób rozwiązania problemu: chcąc korzystać z jej dobrodziejstw, musimy stworzyć obiekt klasy MongoClientSettings i przekazać w argumencie MongoClient.
Odwzorowanie kodu opisanego wyżej wygląda następująco:
var settings = new MongoClientSettings
{
Server = new MongoServerAddress("localhost"),
Credential = MongoCredential.CreateCredential("database", "user", "password"),
};
var client = new MongoClient(settings);
services.AddSingleton<IMongoClient>(client);
Czytelność kodu została zachowana, a o to nam chodzi zawsze. Zawsze! Miłym zaskoczeniem był dla mnie fakt, iż w klasie MongoServerAddress nie musimy podawać protokołu (mongodb) ani portu (27017). Tak samo stworzenie danych autoryzacyjnych, potrzebnych do zalogowania się na serwerze mongo, wygląda dość prosto.
W dalszym ciągu nie otrzymaliśmy logowania na konsole zapytań mogno. Więc jak się za to zabrać? Klasa MongoClientSettings udostępnia propertis "ClusterConfigurator". Możemy w nim przekazać wyrażenie lambda, aby np. zapisać się na zdarzenia rzucone bezpośrednio przez sterownik bazy danych.
To co chcemy zrobić wymaga zapisania się na event "CommandStartedEvent". Przykładowa implementacja wygląda następująco:
var settings = new MongoClientSettings
{
Server = new MongoServerAddress("localhost"),
Credential = MongoCredential.CreateCredential("database", "user", "password"),
ClusterConfigurator = cb => {
cb.Subscribe<CommandStartedEvent>(e =>
{
Console.WriteLine($"{e.CommandName} - {e.Command.ToJson()}");
});
}
};
var client = new MongoClient(settings);
services.AddSingleton<IMongoClient>(client)
Dwa wyrażenia lambda później mamy gotową implementację. Powyższy kod obsłuży wypisywanie zapytań MongoDB na konsolę.
Wykorzystanie Serilog
Jako, że podczas pisania tego artykułu zostało mi jeszcze trochę kakałka w kubku, mam siłę i czas podzielić się dodatkową wiedzą. Wiedz, drogi czytelniku, że raczej staram się nie logować żadnych ciekawych informacji za pomocą konsoli, tylko używam do tego bardziej zaawansowanych narzędzi. Jednym z nich jest Serilog z integracją do ELK stack-a. Pokaże, jak do naszego kodu dołączyć jego biblioteką.
Jak pewnie wszyscy wiedzą, tworzenie klienta do komunikacji z bazą danych MongoDB zazwyczaj znajduje się w sekcji "ConfigureServices" klasy Startup. Trochę to utrudnia sprawę, ponieważ musimy wpierw, sami, zbudować provider-a, który rozwiąże nam typ ILogger. Po dodaniu dwóch linijek (i edytowaniu trzeciej) nasza implementacja powinna wyglądać następująco:
var provider = services.BuildServiceProvider();
var logger = provider.GetService<ILogger>();
var settings = new MongoClientSettings
{
Server = new MongoServerAddress("localhost"),
Credential = MongoCredential.CreateCredential("database", "user", "password"),
ClusterConfigurator = cb => {
cb.Subscribe<CommandStartedEvent>(e =>
{
logger.LogInformation($"{e.CommandName} - {e.Command.ToJson()}");
});
}
};
var client = new MongoClient(settings);
services.AddSingleton<IMongoClient>(client);
Podsumowanie
Kakałko się skończyło więc pora kończyć artykuł. Na szczęście wszystko wygląda ładnie, a co najważniejsze, działa zgodnie z naszymi oczekiwaniami. Mamy, od razu w konsoli, wypisywane zapytania do MongoDB. W razie kłopotów, czy to z pobieraniem danych, czy z długim czasem wykonania zapytania na konsoli, mamy punkt zaczepienia. Jak zawsze mam nadzieje, że artykuł okazał się być pomocny.
Do Następnego!