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;
}
Итак, вопрос - кто-нибудь знает, как это действительно работает?