.NET рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдХрд╛ рдПрдХ рдФрд░ рддрд░реАрдХрд╛ рд╣реИ


рдЕрдХреНрд╕рд░, рдЕрдкрдиреА рдЕрдбрд╝рдЪрдиреЛрдВ рдХреЛ рдкрд╣рдЪрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП рдФрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рдордп рдореЗрдВ рдЖрд╡реЗрджрди рдХреЗ рддрд░реАрдХреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдкрд░ рдЖрдБрдХрдбрд╝реЗ рдПрдХрддреНрд░ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддрд╛ рд╣реИ (рдЬрдм рдЖрд╡реЗрджрди рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЪрд▓ рд░рд╣рд╛ рд╣реИ)ред


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


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


рдЗрди рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдПрдХ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлреЙрд░реНрдо рдУрдкрди-рд╕реЛрд░реНрд╕ .NET рд▓рд╛рдЗрдмреНрд░реЗрд░реА Unchase.FluentPerformanceMeter рд╡рд┐рдХрд╕рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред


рдкрд░рд┐рдЪрдп


рдЗрд╕рд▓рд┐рдП, рдпрд╣ рд▓реЗрдЦ Unchase рдзрд╛рд░рд╛рдкреНрд░рд╡рд╛рд╣ рдкреНрд░рджрд░реНрд╢рди рдореАрдЯрд░ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рд╡рд┐рд╡рд░рдг рд╣реИ, рдПрдХ рдХреНрд░реЙрд╕-рдкреНрд▓реЗрдЯрдлрд╝реЙрд░реНрдо рдУрдкрди-рд╕реЛрд░реНрд╕ .net Standard 2.0 рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдЬреЛ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ .NET рдХреЛрд░ рдФрд░ .NET рдлреНрд░реЗрдорд╡рд░реНрдХ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ .Net рдорд╛рдирдХ 2.0 рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЕрдиреБрдорддрд┐ рджреЗрддреЗ рд╣реИрдВ:


  • рдЕрдкрдиреЗ рдХреЛрдб рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рдкреБрд╕реНрддрдХрд╛рд▓рдпреЛрдВ рдХреЗ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╡рд░реНрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рддрд░реАрдХреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХрд╛ рд╕рдЯреАрдХ рдорд╛рдк рдХрд░реЗрдВ (рдорд╛рдк рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ рд╕рдорд╛рдкреНрддрд┐ рдХрд╛ рд╕рд╣реА рд╕рдордп рдлрд┐рдХреНрд╕ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде);
  • рдорд╛рдк рдкрд░рд┐рдгрд╛рдореЛрдВ рдореЗрдВ рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ (рдХрд╕реНрдЯрдо рдбреЗрдЯрд╛) рдЬреЛрдбрд╝реЗрдВ ред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡рд┐рдзрд┐ рдФрд░ рдкрд░рд┐рдгрд╛рдо рдХреЗ рдЗрдирдкреБрдЯ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рдореВрд▓реНрдп; рдпрд╛ рд╡рд┐рдзрд┐ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдВрджрд░реНрдн рдбреЗрдЯрд╛; рдпрд╛ corellationId , рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рддрд░реАрдХреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдХрдИ рдорд╛рдкреЛрдВ рдХреЛ рдЬреЛрдбрд╝рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛;
  • рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдХреЗ рд▓рд┐рдП рд╕реНрд╡рдпрдВ рдХреЗ рдбреЗрдЯрд╛ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд╕рд╛рде рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЪрд░рдгреЛрдВ (рдЪрд░рдгреЛрдВ) рдореЗрдВ рд╡рд┐рдзрд┐ рдкреНрд░рджрд░реНрд╢рди рдорд╛рдк рдХреЛ рддреЛрдбрд╝реЗрдВ ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдиреНрдпреВрдирддрдо рд░рдирдЯрд╛рдЗрдо рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдореЗрдВ рд╕реЗ рдХрджрдо рдХреЛ рдорд╛рдк рдореЗрдВ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛ (рдпрджрд┐ рдХрджрдо рддреЗрдЬреА рд╕реЗ рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдЗрд╕реЗ рдорд╛рдкрд╛ рдирд╣реАрдВ рдЬрд╛рдПрдЧрд╛);
  • рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рд╕реЗ рдХреЛрдб рдХреЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░реЗрдВ рдЬрд┐рдирдХреЗ рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рд╕рдордп рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рдмрд╛рдж рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ);
  • рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рдХрдорд╛рдВрдб (рдХрдорд╛рдВрдб) рдЬреЛрдбрд╝реЗрдВ , рдЬреЛ рд╡рд┐рдзрд┐ рдкреНрд░рджрд░реНрд╢рди рдорд╛рдк рдХреЗ рдЕрдВрдд рдХреЗ рддреБрд░рдВрдд рдмрд╛рдж рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рдХреА рдЧрд╛рд░рдВрдЯреА рд╣реИ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд░рд╛рдкреНрдд рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП, рдЬреИрд╕реЗ рд▓реЙрдЧрд┐рдВрдЧ рдпрд╛ рд╕реНрдЯреЛрд░реЗрдЬ рдХреЗ рд▓рд┐рдП рдбреЗрдЯрд╛ рд▓рд┐рдЦрдирд╛);
  • рд╡рд┐рдзрд┐ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рдХреЛрдб рдХреЗ рд▓рд┐рдП рдЕрдкрдирд╛ рд╕реНрд╡рдпрдВ рдХрд╛ рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ рдЬреЛрдбрд╝реЗрдВ (рд╕рднреА рдорд╛рдкреЛрдВ рдХреЗ рд▓рд┐рдП рджреЛрдиреЛрдВ рд╕рд╛рдорд╛рдиреНрдп рд╣реИ, рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдк рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ рд╕реЗ);
  • рддрд░реАрдХреЛрдВ рдХреА рдЙрддреНрдкрд╛рджрдХрддрд╛ рдХреЗ рдорд╛рдк рдХреЗ рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЛ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ , рдЬрд┐рд╕рдХреЗ рдмрд╛рдж рдкрд░рд┐рдгрд╛рдо рд╣рдЯрд╛ рджрд┐рдП рдЬрд╛рдПрдВрдЧреЗ;
  • рдорд╛рдк рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреЗ рд▓рд┐рдП рдХреЛрдб рдореЗрдВ IHttpContextAccesor рдпрд╛ рдХреЙрд▓рд░ рдХреЗ рдХрд╛рд░реНрдп рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХреЙрд▓ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рдЬреЛрдбрд╝реЗрдВ (рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдЖрдк рдЙрд╕ рдмрд╛рд╣рд░реА рд╕реЗрд╡рд╛ рдХрд╛ рдирд╛рдо рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдЬрд┐рд╕реЗ рд╡рд┐рдзрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ);
  • рдЙрд╕ рд╕реНрдерд╛рди рдкрд░ рдорд╛рдк рдкрд░рд┐рдгрд╛рдо рдбреЗрдЯрд╛ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ рдЬрд╣рд╛рдВ рдкреНрд░рджрд░реНрд╢рди рдорд╛рдк рд╢реБрд░реВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ (рдХреЛрдб рдореЗрдВ рдХреЙрд▓ рд╕реНрдерд╛рди рдХреЗ рд╕рд╛рде рдлрд╝рд╛рдЗрд▓ рдирд╛рдо рдФрд░ рд▓рд╛рдЗрди рдирдВрдмрд░);
  • рдирд┐рд╖реНрдкрд╛рджрди рдХреЗ рдЕрдВрдд рд╕реЗ рдкрд╣рд▓реЗ рд╡рд┐рдзрд┐ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдорд╛рдк рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП ред

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


рд╕рд╛рдордЧреНрд░реА



рд╢реБрд░реБрдЖрдд рд╣реЛ рд░рд╣реА рд╣реИ


рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЕрдкрдиреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ NuGet рдкреИрдХреЗрдЬ рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:


рдореИрдиреНрдпреБрдЕрд▓ рд░реВрдк рд╕реЗ NuGet рдкреИрдХреЗрдЬ рдореИрдиреЗрдЬрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:


Install-Package Unchase.FluentPerformanceMeter 

.NET CLI рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛:


 dotnet add package Unchase.FluentPerformanceMeter --version {version} 

рдЬрд╣рд╛рдВ {рд╕рдВрд╕реНрдХрд░рдг} рдЙрд╕ рдкреИрдХреЗрдЬ рдХрд╛ рд╕рдВрд╕реНрдХрд░рдг рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдЗрдВрд╕реНрдЯреЙрд▓ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВред
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, dotnet add package Unchase.FluentPerformanceMeter --version 1.0.0

рдЙрдкрдпреЛрдЧ рдХреЗ рдЙрджрд╛рд╣рд░рдг


рд╡рд┐рдзрд┐ рдкреНрд░рджрд░реНрд╢рди рдорд╛рдкрди


SimpleWatchingMethodStart рдХрдВрдЯреНрд░реЛрд▓рд░ (рдХрдВрдЯреНрд░реЛрд▓рд░) PerformanceMeterController SimpleWatchingMethodStart Core 2.2 WebAPI рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рдкреНрд░рджрд░реНрд╢рди (рдХреНрд░рд┐рдпрд╛) SimpleWatchingMethodStart рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд▓рд┐рдП рд▓рд╛рдЗрдмреНрд░реЗрд░реА (рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдФрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рдХреЗ рдмрд┐рдирд╛) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ .WatchingMethod().Start() рдпрд╛ рдПрдХ рд╕рдорд╛рди рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ .StartWatching() ред
.WatchingMethod().Start(SimpleWatchingMethodStart) рдмрд╛рдж рд╕реЗ, рдЖрдк .WatchingMethod().Start(SimpleWatchingMethodStart) рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ .WatchingMethod().Start(SimpleWatchingMethodStart) рдпрд╛ .StartWatching(SimpleWatchingMethodStart) рд╡рд┐рдзрд┐ рдирд╛рдо рдХреЗ рд╕рд╛рде рдХрд░реЗрдВред


рдкреБрд╕реНрддрдХрд╛рд▓рдп рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд╕рднреА рдЙрджрд╛рд╣рд░рдг Unchase.FluentPerformanceMeter.Test* рдореЗрдВ рдЗрд╕ рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдХреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯреНрд╕ рдореЗрдВ Unchase.FluentPerformanceMeter.Test* рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред

 /// <summary> /// Test GET method with simple performance watching. /// </summary> [HttpGet("SimpleWatchingMethodStart")] public ActionResult SimpleWatchingMethodStart() { // for C# 8 you can use: //using var pm = PerformanceMeter<PerformanceMeterController>.StartWatching(); using (PerformanceMeter<PerformanceMeterController>.WatchingMethod().Start()) { // put your code with some logic here return Ok(); } } 

PerformanceMeterController рдирд┐рдпрдВрддреНрд░рдХ рд╡рд░реНрдЧ рдХреЗ рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рддрд░реАрдХреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдорд╛рдк рдХреЗ рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдк рдирд┐рдореНрди рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 /// <summary> /// Get methods performance info for this controller. /// </summary> /// <returns>Returns methods performance info.</returns> [HttpGet("GetPerformanceInfo")] [IgnoreMethodPerformance] public ActionResult<IPerformanceInfo> GetPerformanceInfo() { return Ok(PerformanceMeter<PerformanceMeterController>.PerformanceInfo); } 

SimpleWatchingMethodStart рдХреЙрд▓ рдХрд░рддреЗ рд╕рдордп SimpleWatchingMethodStart рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж:


 { "methodCalls": [ { "methodName": "SimpleWatchingMethodStart", "elapsed": "00:00:00.0016350", "caller": "unknown", "startTime": "2019-12-06T10:27:27.3385385Z", "endTime": "2019-12-06T10:27:27.3401735Z", "customData": {}, "steps": [] } ], "totalActivity": [ { "methodName": "SimpleWatchingMethodStart", "callsCount": 1 } ], "currentActivity": [ { "methodName": "SimpleWatchingMethodStart", "callsCount": 0 } ], "uptimeSince": "2019-12-06T10:27:27.3370183Z", "className": "Unchase.FluentPerformanceMeter.TestWebAPI.Controllers.PerformanceMeterController", "methodNames": [ "SimpleWatchingMethodStart" ], "customData": {}, "timerFrequency": 10000000 } 

DiagnosticSource рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рд╡рд┐рдзрд┐ рдкреНрд░рджрд░реНрд╢рди рдорд╛рдк


рд╕рдВрд╕реНрдХрд░рдг v1.1.0 рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рдирд╛, DiagnosticSource рдФрд░ рд╡рд┐рд╢реЗрд╖ WatchingWithDiagnosticSourceAttribute рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ AspNetCore MVC рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЧрдпрд╛ред
рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, NuGet рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ Unchase.FluentPerformanceMeter.AspNetCore.Mvc рдкреИрдХреЗрдЬ рдЬреЛрдбрд╝реЗрдВ рдФрд░ рдирд┐рдореНрди рдХреЛрдб Startap.cs :


 public void ConfigureServices(IServiceCollection services) { // ... // allows to measure methods performance for class "MeasurableClass" and "MeasurableSecondClass" services.AddPerformanceDiagnosticObserver<MeasurableClass>(); services.AddPerformanceDiagnosticObserver<MeasurableSecondClass>(); // ... the same for another classes services.AddMvc(); // ... } public void Configure(IApplicationBuilder app, IHostingEnvironment env) { // ... app.UsePerformanceDiagnosticObserver(); app.UseMvc(); } 

рдлрд┐рд░ рд╡рд┐рд╢реЗрд╖рддрд╛ WatchingWithDiagnosticSourceAttribute рдпрд╛ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЛрдВ рд╕реЗ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░реЗрдВ:


 [HttpGet("SimpleWatchingMethodStart")] [WatchingWithDiagnosticSource] public ActionResult SimpleWatchingMethodStart() { return Ok(); } 

рдпрд╛ рдкреВрд░реА рдХрдХреНрд╖рд╛:


 [ApiController] [Route("api/v1/[controller]")] [Produces("application/json")] [SwaggerTag("Unchase.PerformanceMeter Test WebAPI Controller")] [WatchingWithDiagnosticSource] public class PerformanceMeterController : ControllerBase { // measurable methods } 

рд╕рдВрд╕реНрдХрд░рдг v1.2.0 рд╕реЗ рд╢реБрд░реВ рд╣реЛрдХрд░, AddMethodArgumentsToCustomDataAttribute рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЗ рд╕рд╛рде рд╕рдВрдпреЛрдЬрди рдХреЗ рд░реВрдк рдореЗрдВ рд╡рд┐рд╢реЗрд╖ AddMethodArgumentsToCustomDataAttribute рд╡рд┐рд╢реЗрд╖рддрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ AspNetCore MVC рдЕрдиреБрдкреНрд░рдпреЛрдЧ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╡рд┐рдзрд┐ рдкреНрд░рджрд░реНрд╢рди рдорд╛рдк рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдП рдЖрд╣реНрд╡рд╛рди рддрд░реНрдХ рдЬреЛрдбрд╝рдирд╛ рд╕рдВрднрд╡ рд╣реЛ рдЧрдпрд╛ред


 [HttpPost("SimpleWatchingMethodStartWithArgs")] [WatchingWithDiagnosticSource] [AddMethodArgumentsToCustomData("actionArguments")] public ActionResult SimpleWatchingMethodStartWithArgs(DTOArgument arg) { return Ok(); } 

SimpleWatchingMethodStartWithArgs рдХреЙрд▓ рдХрд░рдиреЗ рдкрд░ SimpleWatchingMethodStartWithArgs рдкрджреНрдзрддрд┐ рдкрд░ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж:


 { "methodCalls": [ { "methodName": "SimpleWatchingMethodStartWithArgs", "elapsed": "00:00:00.0016350", "caller": "unknown", "startTime": "2019-12-06T10:27:27.3385385Z", "endTime": "2019-12-06T10:27:27.3401735Z", "customData": { "actionArguments": { "arg": { "data": "<string_in_DTOArgument>" } } }, "steps": [] } ], "totalActivity": [ { "methodName": "SimpleWatchingMethodStartWithArgs", "callsCount": 1 } ], "currentActivity": [ { "methodName": "SimpleWatchingMethodStartWithArgs", "callsCount": 0 } ], "uptimeSince": "2019-12-06T10:27:27.3370183Z", "className": "Unchase.FluentPerformanceMeter.TestWebAPI.Controllers.PerformanceMeterController", "methodNames": [ "SimpleWatchingMethodStartWithArgs" ], "customData": {}, "timerFrequency": 10000000 } 

рдкреБрд╕реНрддрдХрд╛рд▓рдп рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рд╡рд┐рдзрд┐ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдирд╛


рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХреА рдЬрд╛рдиреЗ рд╡рд╛рд▓реА рддреГрддреАрдп-рдкрдХреНрд╖ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреА рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рд╡рд┐рдзрд┐ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдХрдХреНрд╖рд╛ рдФрд░ рдЙрд╕рдХреА рд╡рд┐рдзрд┐ рдХрд╛ рдирд╛рдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛:


 [HttpGet("GetThreadSleepPerformance")] public ActionResult<string> GetThreadSleepPerformance() { using (PerformanceMeter<Thread>.WatchingMethod(nameof(Thread.Sleep)).Start()) { Thread.Sleep(1000); } return Ok(PerformanceMeter<Thread>.PerformanceInfo.MethodCalls.FirstOrDefault(ta => ta.MethodName == nameof(Thread.Sleep))?.Elapsed); } 

рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╡рд┐рдзрд┐ рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧреА:


 "00:00:01.0033040" 

рдЖрдк рдХреЙрд▓ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЗрд╕ рд╡рд┐рдзрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


 /// <summary> /// Get methods performance info for Thread class. /// </summary> /// <returns>Returns Thread methods performance info.</returns> [HttpGet("GetThreadPerformanceInfo")] [IgnoreMethodPerformance] public ActionResult<IPerformanceInfo> GetThreadPerformanceInfo() { return Ok(PerformanceMeter<Thread>.PerformanceInfo); } 

IgnoreMethodPerformance рд╡рд┐рд╢реЗрд╖рддрд╛ IgnoreMethodPerformance рдбрд┐рдЬрд╝рд╛рдЗрди рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рддрд╛рдХрд┐ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрддреЗ рд╕рдордп рдЬрд┐рд╕ рд╡рд┐рдзрд┐ рдХреЛ IgnoreMethodPerformance рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЙрд╕ рдкрд░ рдзреНрдпрд╛рди рди рджрд┐рдпрд╛ рдЬрд╛рдПред

рдЗрд╕ рдкрджреНрдзрддрд┐ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдХреЗ рдЬрд╡рд╛рдм рдореЗрдВ рд╣реЛрдЧрд╛:


 { "methodCalls": [ { "methodName": "Sleep", "elapsed": "00:00:01.0033040", "caller": "unknown", "startTime": "2019-12-06T13:08:09.336624Z", "endTime": "2019-12-06T13:08:10.339928Z", "customData": {}, "steps": [] } ], "totalActivity": [ { "methodName": "Abort", "callsCount": 0 }, // ... { "methodName": "Sleep", "callsCount": 1 } // ... ], "currentActivity": [ { "methodName": "Abort", "callsCount": 0 }, // ... { "methodName": "Sleep", "callsCount": 1 } // ... ], "uptimeSince": "2019-12-06T13:08:09.3357028Z", "className": "System.Threading.Thread", "methodNames": [ "Abort", // ... "Sleep", // ... ], "customData": {}, "timerFrequency": 10000000 } 

рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ (рдХрд╕реНрдЯрдо рдбреЗрдЯрд╛) рдФрд░ рдкреГрд╖реНрдард╛рдВрдХрди (рдЪрд░рдг) рдЬреЛрдбрд╝рдирд╛


рдЖрдк рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рд╡рд░реНрдЧ рдХреЗ рддрд░реАрдХреЛрдВ рдХреЗ рд╕рднреА рдкреНрд░рджрд░реНрд╢рди рдорд╛рдкреЛрдВ рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ (рдХрд╕реНрдЯрдо рдбреЗрдЯрд╛) рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, PerformanceMeterController рдирд┐рдпрдВрддреНрд░рдХ рд╡рд░реНрдЧ рдХреЗ рд╕реНрдерд┐рд░ рдирд┐рд░реНрдорд╛рддрд╛ рдореЗрдВ:


 [ApiController] [Route("api/v1/[controller]")] public class PerformanceMeterController : ControllerBase { /// <summary> /// Static constructor. /// </summary> static PerformanceMeterController() { // add common custom data (string) to class performance information PerformanceMeter<PerformanceMeterController>.AddCustomData("Tag", "CustomTag"); // add common custom data (anonymous class) to class performance information PerformanceMeter<PerformanceMeterController>.AddCustomData("Custom anonymous class", new { Name = "Custom Name", Value = 1 }); } // ... actions } 

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдкрджреНрдзрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рдк рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛ (рдХрд╕реНрдЯрдо рдбреЗрдЯрд╛) рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред .WithSettingData.CustomData("<key>", <value>) ( MethodCustomDataAttribute рд╡рд┐рдзрд┐ рдХреА рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╕рд╣рд┐рдд) рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдХреЗ рд▓рд┐рдП (рдЪрд░рдг) рдЗрд╕ рдорд╛рдк рдХрд╛), .Step("<step_name>") рдПрдХреНрд╕рдЯреЗрдВрд╢рди .Step("<step_name>") , .AddCustomData("<key>", <value>) рдПрдХреНрд╕рдЯреЗрдВрд╢рди .AddCustomData("<key>", <value>) рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛:


 /// <summary> /// Test GET method with simple performance watching (with steps). /// </summary> [HttpGet("SimpleStartWatchingWithSteps")] [MethodCustomData("Custom data from attribute", "Attr")] public ActionResult SimpleStartWatchingWithSteps() { using (var pm = PerformanceMeter<PerformanceMeterController> .WatchingMethod() .WithSettingData .CustomData("coins", 1) .CustomData("Coins sets", new { Gold = "Many", Silver = 5 }) .Start()) { // put your code with some logic here // add "Step 1" using (pm.Step("Step 1")) { Thread.Sleep(1000); } // add "Step 2" with custom data using (var pmStep = pm.Step("Step 2").AddCustomData("step2 custom data", "data!")) { // add "Step 3 in Step 2" using (pm.Step("Step 3 in Step 2")) { Thread.Sleep(1000); } // add custom data to "Step 2" pmStep.AddCustomData("step2 another custom data", "data2!"); // get and remove custom data from "Step 2" var customData = pmStep.GetAndRemoveCustomData<string>("step2 custom data"); // get custom data from "Step 2" (without removing) var anotherCustomData = pmStep.GetCustomData<string>("step2 another custom data"); // ... } } } 

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, GetPerformanceInfo рдХреЙрд▓ рдХрд░рддреЗ GetPerformanceInfo рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:


 { "methodCalls": [ { "methodName": "SimpleStartWatchingWithSteps", "elapsed": "00:00:02.0083031", "caller": "unknown", "startTime": "2019-12-06T11:58:18.9006891Z", "endTime": "2019-12-06T11:58:20.9089922Z", "customData": { "Coins sets": { "gold": "Many", "silver": 5 }, "coins": 1, "Custom data from attribute": "Attr" }, "steps": [ { "stepName": "Step 1", "elapsed": "00:00:01.0009758", "startTime": "2019-12-06T11:58:18.9018272Z", "endTime": "2019-12-06T11:58:19.902803Z", "customData": {} }, { "stepName": "Step 3 in Step 2", "elapsed": "00:00:01.0004549", "startTime": "2019-12-06T11:58:19.9046523Z", "endTime": "2019-12-06T11:58:20.9051072Z", "customData": {} }, { "stepName": "Step 2", "elapsed": "00:00:01.0029596", "startTime": "2019-12-06T11:58:19.904534Z", "endTime": "2019-12-06T11:58:20.9074936Z", "customData": { "step2 another custom data": "data2!" } } ] } ], "totalActivity": [ { "methodName": "SimpleStartWatchingWithSteps", "callsCount": 1 } ], "currentActivity": [ { "methodName": "SimpleStartWatchingWithSteps", "callsCount": 0 } ], "uptimeSince": "2019-12-06T11:58:18.8801249Z", "className": "Unchase.FluentPerformanceMeter.TestWebAPI.Controllers.PerformanceMeterController", "methodNames": [ "SimpleStartWatchingWithSteps" ], "customData": { "Tag": "CustomTag", "Custom anonymous class": { "name": "Custom Name", "value": 1 } }, "timerFrequency": 10000000 } 

рдорд╛рдк рд╕реЗ рдЕрдкрд╡рд╛рдж (рдЙрдкреЗрдХреНрд╖рд╛)


рдЖрдк рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рддрд░реАрдХреЗ ( .Ignore() рдпрд╛ .Executing().WithoutWatching().Start(<Action>) ) рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣рд┐рд╕реНрд╕реЛрдВ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЪрд░рдгреЛрдВ (рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдзрд┐ .StepIf("<step_name>", <minSaveMs>) ) рдХреЛ рднреА рдирд╣реАрдВ рдмрдЪрд╛ .StepIf("<step_name>", <minSaveMs>) ) рдЕрдЧрд░ рд╡реЗ рд╢рд░реНрдд рдХреЛ рдкреВрд░рд╛ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ (рд╡рд┐рдзрд┐ рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдореЗрдВ рдХрджрдо рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдПрдЧрд╛):


 using (var pm = PerformanceMeter<PerformanceMeterController>.WatchingMethod().Start()) { // put your code with some logic here // sleep 1 sec Thread.Sleep(1000); // ignore this block in performance watching using (pm.Ignore()) { Thread.Sleep(5000); } // skip this step with minSaveMs (not save, but consider duration in method performance watching) using (pm.StepIf("Skipped step", minSaveMs: 1000)) { Thread.Sleep(500); } // execute action without performance watching pm.Executing().WithoutWatching().Start(() => { Thread.Sleep(2000); }); return Ok(); } 

рдирддреАрдЬрддрди, рд╣рдо рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ:


 { "methodCalls": [ { "methodName": "SimpleStartWatchingWithIgnored", "elapsed": "00:00:01.5080227", "caller": "unknown", "startTime": "2019-12-06T12:34:36.9187359Z", "endTime": "2019-12-06T12:34:38.4267586Z", "customData": {}, "steps": [] } ], "totalActivity": [ { "methodName": "SimpleStartWatchingWithIgnored", "callsCount": 1 } ], "currentActivity": [ { "methodName": "SimpleStartWatchingWithIgnored", "callsCount": 0 } ], "uptimeSince": "2019-12-06T12:34:36.9035129Z", "className": "Unchase.FluentPerformanceMeter.TestWebAPI.Controllers.PerformanceMeterController", "methodNames": [ "SimpleStartWatchingWithIgnored" ], "customData": { }, "timerFrequency": 10000000 } 

рдХрдорд╛рдВрдб рдФрд░ рдХреНрд░рд┐рдпрд╛рдПрдБ рдЬреЛрдбрд╝рдирд╛


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


 /// <summary> /// Custom executed command. /// </summary> public class ExecutedCommand : IPerformanceCommand { /// <summary> /// Executed commad name. /// </summary> public string CommandName => this.GetType().Name; private string _customString { get; } internal bool IsCommandExecuted { get; private set; } /// <summary> /// Constructor. /// </summary> /// <remarks> /// You can pass any data through the command constructor. /// </remarks> /// <param name="customString"></param> public ExecutedCommand(string customString) { this._customString = customString; } /// <summary> /// Execute command. /// </summary> /// <param name="performanceInfo"><see cref="IPerformanceInfo"/>.</param> public void Execute(IPerformanceInfo performanceInfo) { // for example, write to the debug console some information Debug.WriteLine(this.CommandName); Debug.WriteLine(this._customString); Debug.WriteLine($"Method names count: {performanceInfo.MethodNames.Count}"); this.IsCommandExecuted = true; } } 

рдЖрдк рдПрдХ рдХрдорд╛рдВрдб (IPerformanceCommand) рдФрд░ рдПрдХ рдПрдХреНрд╢рди (рдПрдХреНрд╢рди) рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рддрд╛рдХрд┐ рд╡реЗ рдорд╛рдк рдХреЗ рдЕрдВрдд рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд░реАрдХреЗ рд╕реЗ:


 // custom "ExecutedCommand" will be executed after performance watching is completed using (PerformanceMeter<PerformanceMeterController> .WatchingMethod() .WithExecutingOnComplete .Command(new ExecutedCommand("bla-bla-bla")) .Action((pi) => { Debug.WriteLine($"Class name: {pi.ClassName}"); }) .Start()) { return Ok(); } 

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдбрд┐рдмрдЧ- рдХрдВрд╕реЛрд▓ рдореЗрдВ рд╡рд┐рдзрд┐ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рдЕрдВрдд рдореЗрдВ, рдпрд╣ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдЧрд╛:


 ExecutedCommand bla-bla-bla Method names count: 13 Class name: Unchase.FluentPerformanceMeter.TestWebAPI.Controllers.PerformanceMeterController 

рдЕрдкрд╡рд╛рдж рд╣реИрдВрдбрд▓рд░ рдЬреЛрдбрд╝рдирд╛


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


 using (var pm = PerformanceMeter<PerformanceMeterController>.StartWatching()) { // execute action throws Exception with exception handler pm.Executing() .WithExceptionHandler((ex) => Debug.WriteLine(ex.Message)) .Start(() => throw new Exception("Exception")); // execute action throws custom Exception with exception handler pm.Executing<CustomException>() .WithExceptionHandler((ex) => { Debug.WriteLine(ex.Message); }) .Start(() => { throw new CustomException("Custom exception was occured!"); }); return Ok(); } 

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, CustomException рд╡рд░реНрдЧ рдХрд╣рд╛рдБ рд╣реИ:


 /// <summary> /// Custom exception. /// </summary> public class CustomException : Exception { public CustomException(string message) : base(message) { } public CustomException(string message, Exception innerException) : base(message, innerException) { } public CustomException() { } } 

рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рдбрд┐рдмрдЧ рдХрдВрд╕реЛрд▓ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдЧрд╛:


 Exception Custom exception was occured! 

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


 [ApiController] [Route("api/v1/[controller]")] public class PerformanceMeterController : ControllerBase { /// <summary> /// Static constructor. /// </summary> static PerformanceMeterController() { // set default exception handler for PerformanceMeterController class PerformanceMeter<PerformanceMeterController>.SetDefaultExceptionHandler((ex) => Debug.WriteLine(ex.Message)); } // ... actions } 

рдбреЗрдЯрд╛ рд╕рдВрдЧреНрд░рд╣рдг рд╕рдордп рд╕реЗрдЯ рдХрд░рдирд╛ (рдХреИрд╢ рд╕рдордп рд╕реЗрдЯ рдХрд░реЗрдВ)


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


 [ApiController] [Route("api/v1/[controller]")] public class PerformanceMeterController : ControllerBase { /// <summary> /// Static constructor. /// </summary> static PerformanceMeterController() { // set cache time for PerformanceMeterController class PerformanceMeter<PerformanceMeterController>.SetMethodCallsCacheTime(5); } // ... actions } 

рдХреЙрд▓рд┐рдВрдЧ рд╡рд┐рдзрд┐ рдФрд░ рдХреЙрд▓ рдХреА рдЬрдЧрд╣ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдбреЗрдЯрд╛ рдЬреЛрдбрд╝рдирд╛ (рдФрд░ рдкреНрд░рджрд░реНрд╢рди рдХреА рдорд╛рдк рдХреЛ рдмрд╛рдзрд┐рдд рдХрд░рдирд╛)


  • рдЖрдк рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХреМрди рдХреЙрд▓ рдХрд░ рд░рд╣рд╛ рд╣реИред .CallerFrom("<caller_name>") (рдпрд╛ рддреЛ рдПрдХ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдпрд╛ IHttpContextAccessor рдЗрд╕реЗ рдкрд╛рд╕ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ) рдпрд╛ рд╡рд┐рдзрд┐ рдХреА рдПрдХ рд╡рд┐рд╢реЗрд╖ рд╡рд┐рд╢реЗрд╖рддрд╛ рд╣реИ - [MethodCaller("<caller_name>")] ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрджрд┐ рд╡рд┐рд╢реЗрд╖рддрд╛ рдФрд░ рд╡рд┐рд╕реНрддрд╛рд░ рд╡рд┐рдзрд┐ рджреЛрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдореВрд▓реНрдп рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рд╕реЗ рд▓рд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред


  • рдкреНрд░рджрд░реНрд╢рди рд╡рд┐рдзрд┐ .WithSettingData.CallerSourceData() рдЙрдкрдпреЛрдЧ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрд▓ рдмрд┐рдВрджреБ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


  • using рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрджрд░ рдкреНрд░рджрд░реНрд╢рди рдХреЛ рдорд╛рдкрдиреЗ рд╕реЗ рд░реЛрдХрдиреЗ рдХреЗ рд▓рд┐рдП, .StopWatching() рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╡рд┐рдзрд┐ рдпрд╛ .StopWatching() Dispose() рд╡рд┐рдзрд┐ рдХрд╛ рд╕реАрдзреЗ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:



 [HttpPost("StartWatchingWithCallerName")] [MethodCaller("testCaller")] public ActionResult<string> StartWatchingWithCallerName([FromBody] string value) { // method performance info will reach with caller name (if internal HttpContextAccessor is null) using (var pm = PerformanceMeter<PerformanceMeterController> .WatchingMethod() .WithSettingData .CallerSourceData() .CallerFrom("Test caller") .Start()) { pm.StopWatching(); // stop watching here (or you can use "pm.Dispose();") Thread.Sleep(2000); return Ok(value); } } 

GetPerformanceInfo рдкрджреНрдзрддрд┐ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ GetPerformanceInfo , GetPerformanceInfo рдорд┐рд▓реЗрдЧрд╛:


 { "methodCalls": [ { "methodName": "StartWatchingWithCallerName", "elapsed": "00:00:00.0019172", "caller": "Test caller", "startTime": "2019-12-06T13:35:45.3164507Z", "endTime": "2019-12-06T13:35:45.3183679Z", "customData": { "customData123": 123, "callerSourceLineNumber": 525, "callerSource": "D:\\GitHub\\Unchase.FluentPerformanceMeter\\Unchase.FluentPerformanceMeter.TestWebAPI\\Controllers\\PerformanceMeterController.cs" }, "steps": [] } ], "totalActivity": [ { "methodName": "StartWatchingWithCallerName", "callsCount": 1 } ], "currentActivity": [ { "methodName": "StartWatchingWithCallerName", "callsCount": 0 } ], "uptimeSince": "2019-12-06T13:35:45.2601668Z", "className": "Unchase.FluentPerformanceMeter.TestWebAPI.Controllers.PerformanceMeterController", "methodNames": [ "StartWatchingWithCallerName" ], "customData": { }, "timerFrequency": 10000000 } 

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


рдЗрд╕ рдкреНрд░рдХрд╛рд░, рдкреНрд░рд╕реНрддреБрдд рд╕рдорд╛рдзрд╛рди рд╣рдореЗрдВ рдПрдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рддрд░реАрдХреЗ рд╕реЗ .NET рдЖрд╡реЗрджрди рд╡рд┐рдзрд┐рдпреЛрдВ рдХреЗ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕рдВрдЧреНрд░рд╣ рдХреЛ рдЖрдВрд╢рд┐рдХ рд░реВрдк рд╕реЗ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдПрдХрддреНрд░рд┐рдд рдбреЗрдЯрд╛ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдбреЗрд╡рд▓рдкрд░ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рдЙрдкрдпреБрдХреНрдд рд╣реЛред


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


рдкреБрд╕реНрддрдХрд╛рд▓рдп рдПрдХ рдУрдкрди-рд╕реЛрд░реНрд╕ рд╕рдорд╛рдзрд╛рди рд╣реИ, рдЗрд╕рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдХреЛрдИ рднреА рд╕реБрдЭрд╛рд╡ рдФрд░ рд╕реБрдЭрд╛рд╡ рдХреЗрд╡рд▓ рд╕реНрд╡рд╛рдЧрдд рдпреЛрдЧреНрдп рд╣реИрдВ, рдЬреИрд╕реЗ рдмрдЧ-рд░рд┐рдкреЛрд░реНрдЯ (рд╣рд░ рдХреЛрдИ рд▓рд┐рдВрдХ рдХрд╛ рдЕрдиреБрд╕рд░рдг рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдЦрдХ рдХрд┐рд╕реА рднреА рдорджрдж рдХреЗ рд▓рд┐рдП рдЖрднрд╛рд░реА рд╣реЛрдЧрд╛!)ред

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


All Articles