.NET рдХреЛрд░ рдореЗрдВ DiagnosticSource рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛: рд╕рд┐рджреНрдзрд╛рдВрдд

DiagnosticSource API рдХрд╛ рдПрдХ рд╕рд░рд▓ рд▓реЗрдХрд┐рди рдмрд╣реБрдд рдЙрдкрдпреЛрдЧреА рд╕реЗрдЯ рд╣реИ (NuGet рдкреИрдХреЗрдЬ рд╕рд┐рд╕реНрдЯрдо рдореЗрдВ рдЙрдкрд▓рдмреНрдз рд╣реИ редiiostostics.DiagnosticSource), рдЬреЛ рдПрдХ рддрд░рдл, рд╡рд┐рднрд┐рдиреНрди рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЛ рдЙрдирдХреЗ рдХрд╛рдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдирд╛рдорд╛рдВрдХрд┐рдд рдШрдЯрдирд╛рдУрдВ рдХреЛ рднреЗрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░реА рдУрд░, рдЗрди рдШрдЯрдирд╛рдУрдВ рдФрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЗ рд▓рд┐рдП рдЖрд╡реЗрджрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЙрдиреНрд╣реЗрдВред


рдЗрд╕ рддрд░рд╣ рдХреА рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдирд╛ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬрд╛рдирдХрд╛рд░реА (рдкреЗрд▓реЛрдб) рд╣реЛрддреА рд╣реИ, рдФрд░ рдЪреВрдВрдХрд┐ рдШрдЯрдирд╛рдУрдВ рдХреЛ рднреЗрдЬрдиреЗ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рд╣реА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕ рдЬрд╛рдирдХрд╛рд░реА рдореЗрдВ рдХреНрд░рдорд╛рдВрдХрди / deserialization рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛ рд▓рдЧрднрдЧ рдХреЛрдИ рднреА рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред


DiagnosticSource рдкрд╣рд▓реЗ рд╕реЗ рд╣реА AspNetCore, EntityFrameworkCore, HttpClient рдФрд░ SqlClient рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХреЛ рдЗрдирдХрдорд┐рдВрдЧ / рдЖрдЙрдЯрдЧреЛрдЗрдВрдЧ http рдЕрдиреБрд░реЛрдзреЛрдВ, рдбреЗрдЯрд╛рдмреЗрд╕ рдЕрдиреБрд░реЛрдзреЛрдВ, рдПрдХреНрд╕реЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдЬреИрд╕реЗ DbCommand , DbCommand , DbCommand , HttpRequestMessage рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рдиреЗ рдХреА рд╕реБрд╡рд┐рдзрд╛ рджреЗрддрд╛ рд╣реИред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рд╡рд╕реНрддреБрдУрдВред


рдореИрдВрдиреЗ рдЕрдкрдиреА рдХрд╣рд╛рдиреА рдХреЛ DiagnosticSource рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджреЛ рд▓реЗрдЦреЛрдВ рдореЗрдВ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ред рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рд╣рдо рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рддрдВрддреНрд░ рдХреЗ рд╕рдВрдЪрд╛рд▓рди рдХреЗ рд╕рд┐рджреНрдзрд╛рдВрдд рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ, рдФрд░ рдЕрдЧрд▓реЗ I рдореЗрдВ рдЙрди рдШрдЯрдирд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдВрдЧреЗ рдЬреЛ .NET рдореЗрдВ рдореМрдЬреВрдж рд╣реИрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ OZON.ru рдореЗрдВ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдХреБрдЫ рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВред


рдЙрджрд╛рд╣рд░рдг


DiagnosticSource рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЗрд╕реЗ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП, рдбреЗрдЯрд╛рдмреЗрд╕ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдкреНрдЯ рдХрд░рдиреЗ рдХреЗ рдЫреЛрдЯреЗ рдЙрджрд╛рд╣рд░рдг рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рд░рд▓ рдХрдВрд╕реЛрд▓ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реИ рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИ рдФрд░ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИред


 public static class Program { public const string ConnectionString = @"Data Source=localhost;Initial Catalog=master;User ID=sa;Password=Password12!;"; public static async Task Main() { var answer = await GetAnswerAsync(); Console.WriteLine(answer); } public static async Task<int> GetAnswerAsync() { using (var connection = new SqlConnection(ConnectionString)) { // using Dapper return await connection.QuerySingleAsync<int>("SELECT 42;"); } } } 

рд╕рд╛рджрдЧреА рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдПрдХ рдбреЙрдХрдЯрд░ рдХрдВрдЯреЗрдирд░ рдореЗрдВ SQL рд╕рд░реНрд╡рд░ рдЙрдард╛рдпрд╛ред


рдбреЙрдХ рдЪрд▓рд╛рдиреЗ рд╡рд╛рд▓рд╛
 docker run --rm --detach --name mssql-server \ --publish 1433:1433 \ --env ACCEPT_EULA=Y \ --env SA_PASSWORD=Password12! \ mcr.microsoft.com/mssql/server:2017-latest 

рдЕрдм рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдХрд╛рд░реНрдп рд╣реИ: рд╣рдореЗрдВ Stopwatch рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рд╕рднреА рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЛ рдорд╛рдкрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░ рдХрдВрд╕реЛрд▓ рдореЗрдВ "рдЕрдиреБрд░реЛрдз" - "рд░рдирдЯрд╛рдЗрдо" рдЬреЛрдбрд╝реЗ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВред


рдмреЗрд╢рдХ, рдЖрдк рдмрд╕ рдЙрд╕ рдХреЛрдб рдХреЗ QuerySingleAsync рдХреЙрд▓ QuerySingleAsync рд▓рдкреЗрдЯ рд╕рдХрддреЗ рд╣реИрдВ рдЬреЛ Stopwatch рдЖрд╡реГрддреНрддрд┐ рдмрдирд╛рддрд╛ рд╣реИ рдФрд░ рд╢реБрд░реВ рд╣реЛрддрд╛ рд╣реИ, рдХреНрд╡реЗрд░реА рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рдХреЗ рдмрд╛рдж рдЗрд╕реЗ рд░реЛрдХ рджреЗрддрд╛ рд╣реИ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рдмрд╛рд░ рдореЗрдВ рдХрдИ рдХрдард┐рдирд╛рдЗрдпрд╛рдВ рд╣реИрдВ:


  • рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЖрд╡реЗрджрди рдореЗрдВ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдЕрдиреБрд░реЛрдз рд╣реИрдВ?
  • рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╡рд╛рд▓рд╛ рдХреЛрдб рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕рдВрдХрд▓рд┐рдд рд╣реИ, рдПрдХ NuGet рдкреИрдХреЗрдЬ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реИ, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕реЗ рдмрджрд▓рдиреЗ рдХрд╛ рдХреЛрдИ рддрд░реАрдХрд╛ рдирд╣реАрдВ рд╣реИ?
  • рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдкрд░ рдХреНрд╡реЗрд░реА рдбреИрдкрд░ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ рдХреА рдЬрд╛рддреА рд╣реИ, рд▓реЗрдХрд┐рди EntityFramework рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ DbCommand рдСрдмреНрдЬреЗрдХреНрдЯ рдпрд╛ рдЙрддреНрдкрдиреНрди рдХреНрд╡реЗрд░реА рдЯреЗрдХреНрд╕реНрдЯ рддрдХ рдкрд╣реБрдВрдЪ рдирд╣реАрдВ рд╣реИ рдЬреЛ рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдЧреА?

рдЪрд▓рд┐рдП DiagnosticSource рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░рддреЗ рд╣реИрдВред


NuGet System.Diagnostics.DiagnosticSource рдкреИрдХреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


System.Diagnostics.DiagnosticSource рдХреЗ NuGet рдкреИрдХреЗрдЬ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдмрд╛рдж рдХрд░рдиреЗ рд╡рд╛рд▓реА рдкрд╣рд▓реА рдЪреАрдЬрд╝ рдПрдХ рдРрд╕реА рдХреНрд▓рд╛рд╕ рдмрдирд╛рдирд╛ рд╣реИ рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рд░реВрдЪрд┐ рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╣реИрдВрдбрд▓ рдХрд░реЗрдЧреА:


 public sealed class ExampleDiagnosticObserver { } 

рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЗрд╕ рд╡рд░реНрдЧ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдиреЗ рдФрд░ рд╕реНрдереИрддрд┐рдХ рдСрдмреНрдЬреЗрдХреНрдЯ DiagnosticListener.AllListeners рд▓рд┐рд╕реНрдЯрдирд░ рдореЗрдВ рд╕рднреА рдкрд░реНрдпрд╡реЗрдХреНрд╖рдХ рдХреЗ рд░реВрдк рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рд╕рднреА ( System.Diagnostics рдирд╛рдо рд╕реНрдерд╛рди рдореЗрдВ рд╕реНрдерд┐рдд)ред рд╣рдо рдЗрд╕реЗ Main рд╕рдорд╛рд░реЛрд╣ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдХрд░рддреЗ рд╣реИрдВ:


 public static async Task Main() { var observer = new ExampleDiagnosticObserver(); IDisposable subscription = DiagnosticListener.AllListeners.Subscribe(observer); var answer = await GetAnswerAsync(); Console.WriteLine(answer); } 

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдХрдВрдкрд╛рдЗрд▓рд░ рд╣рдореЗрдВ рдареАрдХ рд╕реЗ рдмрддрд╛рдПрдЧрд╛ рдХрд┐ ExampleDiagnosticObserver рд╡рд░реНрдЧ рдХреЛ IObserver<DiagnosticListener> рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдЖрдЗрдП рдЗрд╕реЗ рд▓рд╛рдЧреВ рдХрд░реЗрдВ:


 public sealed class ExampleDiagnosticObserver : IObserver<DiagnosticListener> { void IObserver<DiagnosticListener>.OnNext(DiagnosticListener diagnosticListener) { Console.WriteLine(diagnosticListener.Name); } void IObserver<DiagnosticListener>.OnError(Exception error) { } void IObserver<DiagnosticListener>.OnCompleted() { } } 

рдпрджрд┐ рд╣рдо рдЕрднреА рдпрд╣ рдХреЛрдб рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдВрд╕реЛрд▓ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдВрдЧреЗ:


 SqlClientDiagnosticListener SqlClientDiagnosticListener 42 

рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдХрд╣реАрдВ рди рдХрд╣реАрдВред рдореЗрдВ DiagnosticListener рдкреНрд░рдХрд╛рд░ рдХреА рджреЛ рд╡рд╕реНрддреБрдУрдВ рдХреЛ "SqlClientDiagnosticListener" рдирд╛рдо рд╕реЗ рдкрдВрдЬреАрдХреГрдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрдм рдЗрд╕ рдХреЛрдб рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ред


рдпрд╣рд╛рдБ рд╡реЗ github.com рдкрд░ рд╣реИрдВ

рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЙрдирдореЗрдВ рд╕реЗ рддреАрди рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ рд╣рдордиреЗ SqlTransaction рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛, рдХреЗрд╡рд▓ рджреЛ рдиреЗ рдХрд╛рдо рдХрд┐рдпрд╛:



IObserver<DiagnosticListener>.OnNext рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдмрд╛рд░ рдкрд╣рд▓реЗ DiagnosticListener рдкреНрд░рддреНрдпреЗрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдЖрдорддреМрд░ рдкрд░ рд╡реЗ рд╕реНрдерд┐рд░ рдЧреБрдгреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдмрдирд╛рдП рдЬрд╛рддреЗ рд╣реИрдВ)ред рдЕрдм рд╣рдордиреЗ рдХрдВрд╕реЛрд▓ рдореЗрдВ DiagnosticListener рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдХрд╛ рдирд╛рдо рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдЗрд╕ рдирд╛рдо рдХреА рдЬрд╛рдБрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдФрд░, рдпрджрд┐ рд╣рдо рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдШрдЯрдирд╛рдУрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ Subscribe рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ Subscribe ред


рдореИрдВ рдпрд╣ рднреА рдиреЛрдЯ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ рдХрд┐ рдЬрдм рд╣рдо DiagnosticListener.AllListeners.Subscribe рдХреЙрд▓ рдХрд░рддреЗ рд╣реИрдВ DiagnosticListener.AllListeners.Subscribe рддреЛ рд╣рдореЗрдВ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдПрдХ subscription рдСрдмреНрдЬреЗрдХреНрдЯ рдорд┐рд▓реЗрдЧрд╛, рдЬреЛ IDisposable рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рдкрд░ IObserver<DiagnosticListener>.OnCompleted рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рд╕реЗ рд╕рджрд╕реНрдпрддрд╛ рд╕рдорд╛рдкреНрдд рд╣реЛ рдЬрд╛рдПрдЧреА, рдЬрд┐рд╕реЗ IObserver<DiagnosticListener>.OnCompleted рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред


IObserver<DiagnosticListener> рд▓рд╛рдЧреВ рдХрд░реЗрдВ IObserver<DiagnosticListener> рдлрд┐рд░ рд╕реЗ:


 public sealed class ExampleDiagnosticObserver : IObserver<DiagnosticListener> { private readonly List<IDisposable> _subscriptions = new List<IDisposable>(); void IObserver<DiagnosticListener>.OnNext(DiagnosticListener diagnosticListener) { if (diagnosticListener.Name == "SqlClientDiagnosticListener") { var subscription = diagnosticListener.Subscribe(this); _subscriptions.Add(subscription); } } void IObserver<DiagnosticListener>.OnError(Exception error) { } void IObserver<DiagnosticListener>.OnCompleted() { _subscriptions.ForEach(x => x.Dispose()); _subscriptions.Clear(); } } 

рдЕрдм рдХрдВрдкрд╛рдЗрд▓рд░ рд╣рдореЗрдВ рдмрддрд╛рдПрдЧрд╛ рдХрд┐ рд╣рдорд╛рд░реЗ ExampleDiagnosticObserver рд╡рд░реНрдЧ рдХреЛ IObserver<KeyValuePair<string, object>> interface рдХреЛ рднреА рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣рд╛рдВ рд╣рдореЗрдВ IObserver<KeyValuePair<string, object>>.OnNext рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ KeyValuePair<string, object> рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдХреБрдВрдЬреА рдИрд╡реЗрдВрдЯ рдХрд╛ рдирд╛рдо рд╣реИ, рдФрд░ рдорд╛рди рдПрдХ рдЕрдирд╛рдо рдСрдмреНрдЬреЗрдХреНрдЯ (рдЖрдорддреМрд░ рдкрд░) рд╣реИ рдЬреЛ рдордирдорд╛рдиреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рд╣реИ рдЬрд┐рд╕рдХрд╛ рд╣рдо рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдкрдиреЗ рд╡рд┐рд╡реЗрдХ рдкрд░ред рдЖрдЗрдП рдЗрд╕ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдЬреЛрдбрд╝реЗрдВ:


 public sealed class ExampleDiagnosticObserver : IObserver<DiagnosticListener>, IObserver<KeyValuePair<string, object>> { // IObserver<DiagnosticListener> implementation // ... void IObserver<KeyValuePair<string, object>>.OnNext(KeyValuePair<string, object> pair) { Write(pair.Key, pair.Value); } void IObserver<KeyValuePair<string, object>>.OnError(Exception error) { } void IObserver<KeyValuePair<string, object>>.OnCompleted() { } private void Write(string name, object value) { Console.WriteLine(name); Console.WriteLine(value); Console.WriteLine(); } } 

рдпрджрд┐ рд╣рдо рдЕрдм рдкрд░рд┐рдгрд╛рдореА рдХреЛрдб рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдВрд╕реЛрд▓ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдВрдЧреЗ:


 System.Data.SqlClient.WriteConnectionOpenBefore { OperationId = 3da1b5d4-9ce1-4f28-b1ff-6a5bfc9d64b8, Operation = OpenAsync, Connection = System.Data.SqlClient.SqlConnection, Timestamp = 26978341062 } System.Data.SqlClient.WriteConnectionOpenAfter { OperationId = 3da1b5d4-9ce1-4f28-b1ff-6a5bfc9d64b8, Operation = OpenAsync, ConnectionId = 84bd0095-9831-456b-8ebc-cb9dc2017368, Connection = System.Data.SqlClient.SqlConnection, Statistics = System.Data.SqlClient.SqlStatistics+StatisticsDictionary, Timestamp = 26978631500 } System.Data.SqlClient.WriteCommandBefore { OperationId = 5c6d300c-bc49-4f80-9211-693fa1e2497c, Operation = ExecuteReaderAsync, ConnectionId = 84bd0095-9831-456b-8ebc-cb9dc2017368, Command = System.Data.SqlClient.SqlComman d } System.Data.SqlClient.WriteCommandAfter { OperationId = 5c6d300c-bc49-4f80-9211-693fa1e2497c, Operation = ExecuteReaderAsync, ConnectionId = 84bd0095-9831-456b-8ebc-cb9dc2017368, Command = System.Data.SqlClient.SqlComman d, Statistics = System.Data.SqlClient.SqlStatistics+StatisticsDictionary, Timestamp = 26978709490 } System.Data.SqlClient.WriteConnectionCloseBefore { OperationId = 3f6bfd8f-e5f6-48b7-82c7-41aeab881142, Operation = Close, ConnectionId = 84bd0095-9831-456b-8ebc-cb9dc2017368, Connection = System.Data.SqlClient.SqlConnection, Stat istics = System.Data.SqlClient.SqlStatistics+StatisticsDictionary, Timestamp = 26978760625 } System.Data.SqlClient.WriteConnectionCloseAfter { OperationId = 3f6bfd8f-e5f6-48b7-82c7-41aeab881142, Operation = Close, ConnectionId = 84bd0095-9831-456b-8ebc-cb9dc2017368, Connection = System.Data.SqlClient.SqlConnection, Stat istics = System.Data.SqlClient.SqlStatistics+StatisticsDictionary, Timestamp = 26978772888 } 42 

рдХреБрд▓ рдорд┐рд▓рд╛рдХрд░, рд╣рдо рдЫрд╣ рдШрдЯрдирд╛рдУрдВ рдХреЛ рджреЗрдЦреЗрдВрдЧреЗред рдЙрдирдореЗрдВ рд╕реЗ рджреЛ рдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдЦреЛрд▓рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдФрд░ рдмрд╛рдж рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рджреЛ - рдХрдорд╛рдВрдб рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдФрд░ рдмрд╛рдж рдореЗрдВ, рдФрд░ рджреЛ рдФрд░ - рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдХрдиреЗрдХреНрд╢рди рдХреЛ рдмрдВрдж рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рдФрд░ рдмрд╛рдж рдореЗрдВред


рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдирд╛ рдореЗрдВ рдкреИрд░рд╛рдореАрдЯрд░ рдХрд╛ рдПрдХ рд╕реЗрдЯ рд╣реЛрддрд╛ рд╣реИ, рдЬреИрд╕реЗ рдХрд┐ OperationId , ConnectionId , Connection , Command , рдЬреЛ рдЖрдорддреМрд░ рдкрд░ рдПрдХ рдЕрдирд╛рдо рд╡рд╕реНрддреБ рдХреЗ рдЧреБрдгреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред рдЖрдк рдЗрди рдЧреБрдгреЛрдВ рдХреЗ рд▓рд┐рдП рдЯрд╛рдЗрдк рдХрд┐рдП рдЧрдП рдорд╛рди рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗред (рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ, рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдмрд╣реБрдд рд╡рд╛рдВрдЫрдиреАрдп рдирд╣реАрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдШрдЯрдирд╛ рдХреЗ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд╛рдпрдиреЗрдорд┐рдХрдореЗрдереЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред)


рдЕрдм рд╣рдо рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИрдВ - рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдЗрд╕реЗ рдореВрд▓ рдЕрдиреБрд░реЛрдз рдХреЗ рд╕рд╛рде рдХрдВрд╕реЛрд▓ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВред


рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ Write рд╡рд┐рдзрд┐ рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЛ рдмрджрд▓реЗрдВ:


 public sealed class ExampleDiagnosticObserver : IObserver<DiagnosticListener>, IObserver<KeyValuePair<string, object>> { // IObserver<DiagnosticListener> implementation // ... // IObserver<KeyValuePair<string, object>> implementation // ... private readonly AsyncLocal<Stopwatch> _stopwatch = new AsyncLocal<Stopwatch>(); private void Write(string name, object value) { switch (name) { case "System.Data.SqlClient.WriteCommandBefore": { //           _stopwatch.Value = Stopwatch.StartNew(); break; } case "System.Data.SqlClient.WriteCommandAfter": { //           var stopwatch = _stopwatch.Value; stopwatch.Stop(); var command = GetProperty<SqlCommand>(value, "Command"); Console.WriteLine($"CommandText: {command.CommandText}"); Console.WriteLine($"Elapsed: {stopwatch.Elapsed}"); Console.WriteLine(); break; } } } private static T GetProperty<T>(object value, string name) { return (T) value.GetType() .GetProperty(name) .GetValue(value); } } 

рдпрд╣рд╛рдВ рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ рдЕрдВрдд рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рд░реЛрдХрддреЗ рд╣реИрдВред рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдо рд╕реНрдЯреЙрдкрд╡реЙрдЪ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рд╡рд╛рдкрд╕ рд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП, AsyncLocal<Stopwatch> рдПрдХ рдЪрд░ рдореЗрдВ рдЗрд╕реЗ рд╕рд╣реЗрдЬрддреЗ рд╣реИрдВред рдЕрдиреБрд░реЛрдз рдХреЛ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рд╣рдо рдкрд╣рд▓реЗ рд▓реЙрдиреНрдЪ рдХрд┐рдП рдЧрдП рд╕реНрдЯреЙрдкрд╡реЙрдЪ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕реЗ рд░реЛрдХрддреЗ рд╣реИрдВ, рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ value рдкреИрд░рд╛рдореАрдЯрд░ рд╕реЗ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХрдорд╛рдВрдб рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЛ рдХрдВрд╕реЛрд▓ рдкрд░ рдкреНрд░рд┐рдВрдЯ рдХрд░рддреЗ рд╣реИрдВред


рдпрджрд┐ рд╣рдо рдЕрдм рдкрд░рд┐рдгрд╛рдореА рдХреЛрдб рдЪрд▓рд╛рддреЗ рд╣реИрдВ, рддреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХрдВрд╕реЛрд▓ рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдВрдЧреЗ:


 CommandText: SELECT 42; Elapsed: 00:00:00.0341357 42 

рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЕрдкрдиреА рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рдХрд░ рдЪреБрдХреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдПрдХ рдЫреЛрдЯрд╛ рд╕рд╛ рд╡рд┐рд╡рд░рдг рд╢реЗрд╖ рд╣реИред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ рдЬрдм рд╣рдо DiagnosticListener рдИрд╡реЗрдВрдЯ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рд╣рдо рдЗрд╕реЗ рдЙрди рдШрдЯрдирд╛рдУрдВ рд╕реЗ рднреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВ рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рджрд┐рд▓рдЪрд╕реНрдк рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рдЪреВрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдИрд╡реЗрдВрдЯ рдХреЛ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдЕрдирд╛рдо рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ GC рдкрд░ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд▓реЛрдб рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред


рдЗрд╕ рд╕реНрдерд┐рддрд┐ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рдЖрдкрдХреЛ рдпрд╣ рдмрддрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рд╣рдо рдХреМрди рд╕реА рдШрдЯрдирд╛рдУрдВ рдХрд╛ DiagnosticListener рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рд╣рдо рд╕рдмреНрд╕рдХреНрд░рд╛рдЗрдм рдХрд░рддреЗ рд╕рдордп Predicate<string> рдЯрд╛рдЗрдк рдХреЗ рдПрдХ рд╡рд┐рд╢реЗрд╖ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдЗрд╡реЗрдВрдЯ рдХрд╛ рдирд╛рдо рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рд▓реЗрддрд╛ рд╣реИ рдФрд░ true рдпрджрд┐ рдЗрд╕ рдИрд╡реЗрдВрдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред


IObserver<DiagnosticListener>.OnNext рдЕрдкрдиреА рдХрдХреНрд╖рд╛ рдореЗрдВ IObserver<DiagnosticListener>.OnNext рдХреЛ IObserver<DiagnosticListener>.OnNext :


 void IObserver<DiagnosticListener>.OnNext(DiagnosticListener diagnosticListener) { if (diagnosticListener.Name == "SqlClientDiagnosticListener") { var subscription = diagnosticListener.Subscribe(this, IsEnabled); _subscriptions.Add(subscription); } } private bool IsEnabled(string name) { return name == "System.Data.SqlClient.WriteCommandBefore" || name == "System.Data.SqlClient.WriteCommandAfter"; } 

рдЕрдм рд╣рдорд╛рд░рд╛ Write рддрд░реАрдХрд╛ рдХреЗрд╡рд▓ "System.Data.SqlClient.WriteCommandBefore" рдФрд░ "System.Data.SqlClient.WriteCommandAfter" рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


Microsoft рдХреЗ NuGet Package.Extensions.DiagnosticAdapter рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛


рдЪреВрдВрдХрд┐ рдШрдЯрдирд╛ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рдЬреЛ рд╣рдо DiagnosticListener рд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рдЖрдорддреМрд░ рдкрд░ рдПрдХ рдЕрдирд╛рдо рд╡рд╕реНрддреБ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдкреНрд░рддрд┐рдмрд┐рдВрдм рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЙрдиреНрд╣реЗрдВ рдкреБрдирд░реНрдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдмрд╣реБрдд рдорд╣рдВрдЧрд╛ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд╕реМрднрд╛рдЧреНрдп рд╕реЗ, Microsoft.Extensions.DiagnosticAdapter NuGet рдкреИрдХреЗрдЬ рд╣реИ рдЬреЛ рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдРрд╕рд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, System.Reflection.Emit рд╕реЗ рд░рдирдЯрд╛рдЗрдо рдХреЛрдб рдкреАрдврд╝реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд░рд╣рд╛ рд╣реИред


рдЗрд╕ рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬрдм Subscribe рд╡рд┐рдзрд┐ рдХреЗ рдмрдЬрд╛рдп DiagnosticListener рдЙрджрд╛рд╣рд░рдг рд╕реЗ рдШрдЯрдирд╛рдУрдВ рдХреА Subscribe рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдЖрдкрдХреЛ SubscribeWithAdapter рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ IObserver<KeyValuePair<string, object>> interface рдХреЛ рд▓рд╛рдЧреВ рдХрд░рдирд╛ рдЕрдм рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИред рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдирд╛ рдХреЗ рд▓рд┐рдП рдЬрд┐рд╕реЗ рд╣рдо рд╕рдВрднрд╛рд▓рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдПрдХ рдЕрд▓рдЧ рд╡рд┐рдзрд┐ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЗрд╕реЗ DiagnosticNameAttribute рд╡рд┐рд╢реЗрд╖рддрд╛ ( Microsoft.Extensions.DiagnosticAdapter рдирд╛рдорд╕реНрдерд╛рди рд╕реЗ) рдХреЗ рд╕рд╛рде рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рдирд╛ рд╣реИред рдЗрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд┐рдП рдЬрд╛ рд░рд╣реЗ рдЗрд╡реЗрдВрдЯ рдХреЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реЛрдВрдЧреЗред


рдЕрдЧрд░ рд╣рдо рдЗрд╕ NuGet рдкреИрдХреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдиреЗ ExampleDiagnosticObserver рд╡рд░реНрдЧ рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрддреЗ рд╣реИрдВ, рддреЛ рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдорд┐рд▓рддреЗ рд╣реИрдВ:


 public sealed class ExampleDiagnosticObserver : IObserver<DiagnosticListener> { private readonly List<IDisposable> _subscriptions = new List<IDisposable>(); void IObserver<DiagnosticListener>.OnNext(DiagnosticListener diagnosticListener) { if (diagnosticListener.Name == "SqlClientDiagnosticListener") { var subscription = diagnosticListener.SubscribeWithAdapter(this); _subscriptions.Add(subscription); } } void IObserver<DiagnosticListener>.OnError(Exception error) { } void IObserver<DiagnosticListener>.OnCompleted() { _subscriptions.ForEach(x => x.Dispose()); _subscriptions.Clear(); } private readonly AsyncLocal<Stopwatch> _stopwatch = new AsyncLocal<Stopwatch>(); [DiagnosticName("System.Data.SqlClient.WriteCommandBefore")] public void OnCommandBefore() { _stopwatch.Value = Stopwatch.StartNew(); } [DiagnosticName("System.Data.SqlClient.WriteCommandAfter")] public void OnCommandAfter(DbCommand command) { var stopwatch = _stopwatch.Value; stopwatch.Stop(); Console.WriteLine($"CommandText: {command.CommandText}"); Console.WriteLine($"Elapsed: {stopwatch.Elapsed}"); Console.WriteLine(); } } 

рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдЕрдм рд╣рдо рдЕрдкрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рд╕рднреА рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЛ рдорд╛рдк рд╕рдХрддреЗ рд╣реИрдВ, рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рд░реВрдк рд╕реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдХреЛрдб рдХреЛ рдмрджрд▓реЗ рдмрд┐рдирд╛ред


рдЕрдкрдиреА рдЦреБрдж рдХреА DiagnosticListener рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдирд╛


рд╡реНрдпрд╡рд╣рд╛рд░ рдореЗрдВ DiagnosticSource рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рдЬреНрдпрд╛рджрд╛рддрд░ рдорд╛рдорд▓реЛрдВ рдореЗрдВ рдЖрдк рдореМрдЬреВрджрд╛ рдШрдЯрдирд╛рдУрдВ рдХреА рд╕рджрд╕реНрдпрддрд╛ рд▓реЗрдВрдЧреЗред рдЖрдкрдХреЛ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИ рдХрд┐ рдЖрдкрдХреЛ рдЕрдкрдиреЗ рдЦреБрдж рдХреЗ DiagnosticListener рдФрд░ рдЕрдкрдиреА рдЦреБрдж рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рднреЗрдЬрдирд╛ рд╣реЛрдЧрд╛ (рдХреЗрд╡рд▓ рдЕрдЧрд░ рдЖрдк рдХрд┐рд╕реА рднреА рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рд╡рд┐рдХрд╛рд╕ рдирд╣реАрдВ рдХрд░ рд░рд╣реЗ рд╣реИрдВ), рддреЛ рдореИрдВ рдЗрд╕ рдЦрдВрдб рдкрд░ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдирд╣реАрдВ рд░рд╣реВрдВрдЧрд╛ред


DiagnosticListener рдХрд╛ рдЕрдкрдирд╛ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдЗрд╕реЗ рдХреЛрдб рдореЗрдВ рдХрд╣реАрдВ рдПрдХ рд╕реНрдерд┐рд░ рдЪрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛:


 private static readonly DiagnosticSource _myDiagnosticSource = new DiagnosticListener("MyLibraty"); 

рдЙрд╕рдХреЗ рдмрд╛рдж, рдХрд┐рд╕реА рдИрд╡реЗрдВрдЯ рдХреЛ рднреЗрдЬрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдлрд╝реЙрд░реНрдо рдХреЗ рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 if (_myDiagnosticSource.IsEnabled("MyEvent")) _myDiagnosticSource.Write("MyEvent", new { /* parameters */ }); 

рдЕрдкрдирд╛ рдЦреБрдж рдХрд╛ DiagnosticListener рдЗрдВрд╕реНрдЯреЗрдВрд╕ рдмрдирд╛рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП DiagnosticSource рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдорд╛рд░реНрдЧрджрд░реНрд╢рд┐рдХрд╛ рджреЗрдЦреЗрдВ , рдЬрд┐рд╕рдореЗрдВ DiagnosticSource рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡реЛрддреНрддрдо рдЕрднреНрдпрд╛рд╕реЛрдВ рдХрд╛ рд╡рд┐рд╡рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рдирд┐рд╖реНрдХрд░реНрд╖


рд╣рдордиреЗ рдЬреЛ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛, рд╡рд╣ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдмрд╣реБрдд рд╕рд╛рд░рдЧрд░реНрднрд┐рдд рд╣реИ рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧреА рд╣реЛрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди рдпрд╣ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рджрд┐рдЦрд╛рддрд╛ рд╣реИ рдХрд┐ рдЗрд╕ рддрдВрддреНрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдкрдХреЗ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдФрд░ рдирд┐рджрд╛рди рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред


рдЕрдЧрд▓реЗ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдореЗрд░реЗ рд▓рд┐рдП рдЬреНрдЮрд╛рдд рдШрдЯрдирд╛рдУрдВ рдХреА рдПрдХ рд╕реВрдЪреА рджреВрдВрдЧрд╛ рдЬреЛ рдХрд┐ DiagnosticSource рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИрдВ, рдФрд░ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЗ рдХреБрдЫ рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЙрджрд╛рд╣рд░рдг рджрд┐рдЦрд╛ рд╕рдХрддреЗ рд╣реИрдВред

Source: https://habr.com/ru/post/hi435896/


All Articles