Eine andere Möglichkeit, die Leistung von .NET-Anwendungsmethoden zu messen


Häufig ist es erforderlich, Statistiken über die Leistung von Anwendungsmethoden in Echtzeit zu erfassen (wenn die Anwendung bereits ausgeführt wird), um die Engpässe zu ermitteln und festzustellen, welcher Teil der Anwendung langsamer wird.


Darüber hinaus wäre es hilfreich, den Aufrufkontext zu speichern, in dem die Leistung verfolgt wird (z. B. Argumente zum Methodenaufruf und vom Entwickler hinzugefügte beliebige Daten), zusätzlich zu den Leistungsdaten selbst (Zeitpunkt der Methodenentwicklung, Start- und Enddatum des Aufrufs).


Nun, die "Kirsche auf dem Kuchen" kann als die Bequemlichkeit und Einfachheit des verwendeten Werkzeugs angesehen werden, was auch wichtig ist.


Um diese Probleme zu lösen, wurde eine plattformübergreifende Open-Source-.NET-Bibliothek Unchase.FluentPerformanceMeter entwickelt .


Einleitung


In diesem Artikel wird die Arbeit mit Unchase Fluent Performance Meter beschrieben , einer plattformübergreifenden Open-Source-Bibliothek mit .NET Standard 2.0 zur Berechnung der Leistung von Methoden.


Die Bibliothek kann in .NET Core- und .NET Framework-Anwendungen verwendet werden, die .NET Standard 2.0 unterstützen , und ermöglicht Folgendes :


  • Führen Sie genaue Messungen der Leistung öffentlicher Methoden für öffentliche Klassen sowohl Ihres Codes als auch des Codes der verwendeten Bibliotheken durch (wobei Sie den genauen Zeitpunkt des Beginns und des Endes der Messung festlegen).
  • Fügen Sie den Messergebnissen zusätzliche Daten (benutzerdefinierte Daten) hinzu. Zum Beispiel die Werte der Eingabeparameter der Methode und des Ergebnisses; oder Kontextdaten der Methodenausführung; oder corellationId , mit der mehrere Messungen der Leistung von Methoden verknüpft werden können;
  • Teilen Sie die Messung der Methodenleistung in separate Schritte (Steps) auf, wobei Sie für jeden Schritt eigene Daten festlegen. Außerdem können Sie die minimale Laufzeit festlegen , ab der der Schritt bei der Messung berücksichtigt wird (wenn der Schritt schneller ausgeführt wird, wird er nicht gemessen).
  • Bestimmte Teile des Codes von der Leistungsmessung ausschließen (z. B. Aufrufe einzelner Methoden, deren Ausführungszeit bei der Messung nicht berücksichtigt werden muss);
  • Fügen Sie Ihre eigenen Befehle (Commands) hinzu, die garantiert sofort nach dem Ende der Leistungsmessung der Methode ausgeführt werden (z. B. um die erhaltenen Ergebnisse zusätzlich zu verarbeiten, z. B. um Daten zu protokollieren oder in den Speicher zu schreiben).
  • Fügen Sie einen eigenen Ausnahmehandler für Code hinzu, der im Zusammenhang mit der Messung der Leistung der Methode ausgeführt wird (sowohl für alle Messungen als auch für jede Messung separat).
  • Legen Sie die Zeit zum Speichern der Ergebnisse von Messungen der Produktivität von Methoden fest. Danach werden die Ergebnisse gelöscht.
  • Fügen Sie den Messergebnissen Daten darüber hinzu, wer die Methode ( Aufrufer ) über IHttpContextAccesor oder die Aufgabe des Aufrufers im Code aufruft (Sie können beispielsweise den Namen des externen Dienstes angeben, der die Methode aufgerufen hat).
  • Ergänzen Sie die Messergebnisdaten an der Stelle, an der die Leistungsmessung gestartet wurde (Dateiname und Zeilennummer mit dem Anrufort im Code);
  • Unterbrechen der Messung der Leistung der Methode bis zu ihrem Abschluss .

Die aus der Messung der Leistung der Methoden gewonnenen Daten können verwendet werden, um die Leistung der Anwendung (ihre einzelnen Teile, sowohl interner Code als auch externer Code der verwendeten Bibliotheken) zu analysieren und in einer für Sie geeigneten grafischen Form anzuzeigen.


Inhalt



Erste Schritte


Installieren Sie das NuGet- Paket in Ihrem Projekt, um die Bibliothek zu verwenden:


Manuelles Verwenden des NuGet Package Managers:


Install-Package Unchase.FluentPerformanceMeter 

Verwenden der .NET CLI:


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

Wobei {version} die Version des Pakets ist, das Sie installieren möchten.
Beispiel: dotnet add package Unchase.FluentPerformanceMeter --version 1.0.0

Anwendungsbeispiele


Methodenleistungsmessung


Im Folgenden finden Sie ein einfaches Beispiel für die Verwendung der Bibliothek (ohne Konfiguration und zusätzliche Einstellungen) zum Messen der Leistung der (Action) SimpleWatchingMethodStart Asp.Net Core 2.2-WebAPI- Anwendung " SimpleWatchingMethodStart controller (Controller) PerformanceMeterController " . Dazu können Sie die Erweiterungsmethode .WatchingMethod().Start() oder eine ähnliche Funktion .StartWatching() .
Ab Version 1.0.5 können Sie auch .WatchingMethod().Start(SimpleWatchingMethodStart) oder .StartWatching(SimpleWatchingMethodStart) mit dem Methodennamen verwenden.


Alle Beispiele für die Verwendung der Bibliothek finden Sie in den Unchase.FluentPerformanceMeter.Test* -Projekten dieses Repositorys .

 /// <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(); } } 

Um die Ergebnisse von Leistungsmessungen öffentlicher Methoden der Controller-Klasse PerformanceMeterController abzurufen, können Sie die folgende Methode aufrufen:


 /// <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); } 

Nach dem Aufruf der SimpleWatchingMethodStart Methode beim Aufruf von GetPerformanceInfo wir:


 { "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 } 

Methodenleistungsmessung mit DiagnosticSource


Ab Version 1.1.0 konnte die Leistung von Methoden in einer AspNetCore MVC- Anwendung mithilfe von DiagnosticSource und dem speziellen Attribut WatchingWithDiagnosticSourceAttribute gemessen werden.
Unchase.FluentPerformanceMeter.AspNetCore.Mvc Sie dazu das Unchase.FluentPerformanceMeter.AspNetCore.Mvc Paket zum NuGet- Projekt hinzu und fügen Sie Startap.cs den folgenden Code 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(); } 

Dann markieren Sie mit dem Attribut WatchingWithDiagnosticSourceAttribute oder einzelnen Methoden:


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

oder die ganze Klasse:


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

Ab Version 1.2.0 konnten in einer AspNetCore MVC- Anwendung mithilfe des speziellen AddMethodArgumentsToCustomDataAttribute Attributs in Verbindung mit dem WatchingWithDiagnosticSourceAttribute Attribut AddMethodArgumentsToCustomDataAttribute Leistungsmessdaten von Benutzermethoden AddMethodArgumentsToCustomDataAttribute werden:


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

Nach dem Aufruf der SimpleWatchingMethodStartWithArgs Methode beim Aufruf von GetPerformanceInfo wir:


 { "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 } 

Messung der Leistung der von der Bibliothek verwendeten Methode


Um die Leistung der öffentlichen Methode der öffentlichen Klasse der verwendeten Drittanbieter-Bibliothek zu messen, müssen Sie die Klasse selbst und den Namen ihrer Methode explizit festlegen:


 [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); } 

Die ausgeführte Methode gibt Folgendes zurück:


 "00:00:01.0033040" 

Sie können Daten zum Aufrufen dieser Methode über einen Aufruf abrufen:


 /// <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); } 

Das IgnoreMethodPerformance Attribut IgnoreMethodPerformance so konzipiert, dass die von ihm IgnoreMethodPerformance Methode beim Messen der Leistung nicht berücksichtigt wird.

Als Antwort auf den Aufruf dieser Methode wird sein:


 { "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 } 

Hinzufügen zusätzlicher Daten (benutzerdefinierte Daten) und Paginierung (Schritte)


Sie können zusätzliche Daten (benutzerdefinierte Daten) für alle Leistungsmessungen von Methoden einer bestimmten Klasse hinzufügen. Zum Beispiel im statischen Konstruktor der Controller-Klasse 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 } 

Darüber hinaus können Sie mithilfe der Erweiterungsmethode .WithSettingData.CustomData("<key>", <value>) (einschließlich eines speziellen Attributs der MethodCustomDataAttribute Methode) und für jeden Schritt (Step) zusätzliche Daten (Custom Data) für eine bestimmte Messung hinzufügen ) dieser Messung, hinzugefügt unter Verwendung der Erweiterungsmethode .Step("<step_name>") , unter Verwendung der Erweiterungsmethode .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"); // ... } } } 

Als Ergebnis GetPerformanceInfo wir beim Aufruf von 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 } 

Ausnahme von der Messung (Ignorieren)


Sie können einzelne Teile der Methode beim Messen der Leistung ignorieren (mithilfe von .Ignore() oder .Executing().WithoutWatching().Start(<Action>) ) und auch einzelne Schritte nicht speichern (Erweiterungsmethode .StepIf("<step_name>", <minSaveMs>) ), wenn sie die Bedingung nicht erfüllen (die Ausführungszeit des Schritts wird in der Ausführungszeit der Methode berücksichtigt):


 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(); } 

Als Ergebnis erhalten wir:


 { "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 } 

Befehle und Aktionen hinzufügen


Um einen Befehl hinzuzufügen, dessen Ausführung nach Abschluss der Messung der Leistung einer Methode garantiert ist, muss eine Befehlsklasse erstellt werden, die die IPerformanceCommand Schnittstelle implementiert.
Gleichzeitig können Sie beliebige Daten über den Konstruktor des erstellten Befehls übertragen, der während seiner Ausführung verwendet wird. Zum Beispiel:


 /// <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; } } 

Sie können einen Befehl (IPerformanceCommand) und eine Aktion (Action) hinzufügen, damit sie am Ende der Messung wie folgt ausgeführt werden:


 // 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(); } 

Als Ergebnis wird am Ende der Messung der Leistung der Methode in der Debug- Konsole Folgendes angezeigt:


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

Ausnahmebehandlungsroutinen hinzufügen


Wenn Sie Ausnahmen behandeln müssen, die während der Ausführung eines Teils der Methode auftreten können, für die die Leistung überwacht wird, müssen Sie einen Ausnahmebehandler wie folgt hinzufügen:


 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(); } 

Wo ist die CustomException Klasse, zum Beispiel:


 /// <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() { } } 

Infolgedessen zeigt die Debug- Konsole Folgendes an:


 Exception Custom exception was occured! 

Darüber hinaus können Sie einen Ausnahmebehandler angeben, der standardmäßig zum Messen der Leistung jeder Methode dieser Klasse verwendet wird, z. B. über den statischen Konstruktor der PerformanceMeterController Controllerklasse:


 [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 } 

Einstellen der Datenspeicherzeit (Set Cache Time)


Sie können die Speicherzeit für die Daten der Leistungsmessungen von Methoden einstellen, nach deren Ablauf diese Daten gelöscht werden. Für jede Klasse, für die eine Messung durchgeführt wird, wird diese Zeit separat eingestellt. Die Zeit kann beispielsweise über den statischen Konstruktor der PerformanceMeterController Controller-Klasse festgelegt werden:


 [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 } 

Hinzufügen von Daten zur aufrufenden Methode und zum Ort des Anrufs (und Unterbrechen der Leistungsmessung)


  • Sie können angeben, wer die Methode aufruft, indem Sie die Erweiterungsmethode .CallerFrom("<caller_name>") (entweder eine Zeichenfolge oder IHttpContextAccessor wird an sie übergeben ) oder ein spezielles Attribut der Methode [MethodCaller("<caller_name>")] . Wenn sowohl das Attribut als auch die Erweiterungsmethode verwendet werden, wird der Wert von dieser übernommen.


  • Mit der Erweiterungsmethode .WithSettingData.CallerSourceData() ein .WithSettingData.CallerSourceData() zum Messen der Leistung hinzugefügt.


  • Verwenden Sie die Erweiterungsmethode .StopWatching() oder die Methode Dispose() direkt, um die Messung der Leistung innerhalb des using Blocks zu .StopWatching() :



 [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); } } 

Durch den Aufruf der Methode 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 } 

Fazit


Die vorgestellte Lösung ermöglicht es uns daher, die Erfassung von Informationen über die Leistung von .NET-Anwendungsmethoden auf eine recht bequeme Weise teilweise zu automatisieren. Die gesammelten Daten können auf eine Weise visualisiert werden, die für den jeweiligen Entwickler besser geeignet ist.


Natürlich löst die Bibliothek nicht alle Probleme, die mit dem Sammeln von Daten zur Leistung von Methoden verbunden sind, sondern versucht, die gängigsten zu vereinfachen.


Bei der Bibliothek handelt es sich um eine Open-Source-Lösung. Vorschläge und Vorschläge für deren Entwicklung sind ebenso willkommen wie Fehlerberichte (jeder kann dem Link folgen; der Autor ist für jede Hilfe dankbar!).

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


All Articles