Как Application Insights перехватывает вызовы SQL? - PullRequest
1 голос
/ 10 октября 2019

Application Insights автоматически обеспечивает отслеживание многих зависимостей, в частности, за это отвечает DependencyTrackingTelemetryModule. Среди других методов телеметрии зависимостей он собирает все вызовы базы данных, которые выполнялись с использованием ADO.NET (в основном, все, что можно сделать с помощью System.Data.SqlClient.).

Мне стало интересно посмотреть, как это реализовано внутри, и открыл IlSpy дляобзор внутренних органов;не было большим сюрпризом видеть код, подобный приведенному ниже, из класса Microsoft.ApplicationInsights.DependencyCollector.Implementation.ProfilerRuntimeInstrumentation:

internal static void DecorateProfilerForSqlCommand(ref ProfilerSqlCommandProcessing sqlCallbacks)
{
    Functions.Decorate("System.Data", "System.Data.dll", "System.Data.SqlClient.SqlCommand.ExecuteNonQuery", sqlCallbacks.OnBeginForOneParameter, sqlCallbacks.OnEndForOneParameter, sqlCallbacks.OnExceptionForOneParameter, false, true);
    Functions.Decorate("System.Data", "System.Data.dll", "System.Data.SqlClient.SqlCommand.ExecuteReader", sqlCallbacks.OnBeginForOneParameter, sqlCallbacks.OnEndForOneParameter, sqlCallbacks.OnExceptionForOneParameter, false, true);
    Functions.Decorate("System.Data", "System.Data.dll", "System.Data.SqlClient.SqlCommand.ExecuteReader", sqlCallbacks.OnBeginForThreeParameters, sqlCallbacks.OnEndForThreeParameters, sqlCallbacks.OnExceptionForThreeParameters, false, true);
    // and others...
}

Однако чем глубже я копаю, тем меньше понимаю, как он работает. Если мы посмотрим на реализацию Functions.Decorate, то обнаружим, что она в основном делегирует работу методу Microsoft.Diagnostics.Instrumentation.Extensions.Intercept.Decorator.Decorate, который внутренне вызывает Microsoft.Diagnostics.Instrumentation.Extensions.Intercept.Internal.DecoratorInternal. Затем он вызывает Microsoft.Diagnostics.Instrumentation.Extensions.Intercept.Internal.NativeMethods.Decorate.

Вот изюминка. Ниже приведена реализация последнего метода, который предполагал (на мой взгляд) выполнять настоящую работу.

[MethodImpl(MethodImplOptions.NoInlining)]
internal static int Decorate(int methodId, long assemblyNamePtr, long moduleNamePtr, long typeNamePtr, long methodNamePtr, uint argsCount)
{
    return 0;
}

Итак, вопрос - кто-нибудь знает, как это действительно работает?

...