Oktatóanyag: Teljesítmény mérése EventCounters használatával a .NET Core-ban
Ez a cikk a következő kiadásokra vonatkozik: ✔️ .NET Core 3.0 SDK és újabb verziók
Ebben az oktatóanyagban megtudhatja, hogyan EventCounter mérheti a teljesítményt nagy gyakoriságú eseményekkel. Használhatja a különböző hivatalos .NET Core-csomagok, külső szolgáltatók által közzétett számlálókat , vagy létrehozhat saját metrikákat a monitorozáshoz.
Az oktatóanyagban a következőket végezheti el:
- Implementál egy EventSourceelemet.
- Számlálók figyelése dotnet-counters használatával.
Előfeltételek
Az oktatóanyag a következőket használja:
- .NET Core 3.1 SDK vagy újabb verzió.
- dotnet-counters az eseményszámlálók figyeléséhez.
- Minta hibakeresési célalkalmazás diagnosztizálásához.
A forrás lekérése
A rendszer a mintaalkalmazást használja a monitorozás alapjául. A minta-ASP.NET Core adattár a mintaböngészőben érhető el. Töltse le a zip-fájlt, bontsa ki a letöltés után, és nyissa meg a kedvenc IDE-ben. Hozza létre és futtassa az alkalmazást, hogy az megfelelően működjön, majd állítsa le az alkalmazást.
EventSource implementálása
Néhány ezredmásodpercenként előforduló események esetén azt szeretné, hogy az eseményenkénti többletterhelés alacsony legyen (ezredmásodpercnél kevesebb). Ellenkező esetben a teljesítményre gyakorolt hatás jelentős lesz. Az esemény naplózása azt jelenti, hogy lemezre fog írni valamit. Ha a lemez nem elég gyors, az események elvesznek. Az esemény naplózásán kívül más megoldásra is szüksége van.
Nagy számú esemény kezelésekor az eseményenkénti mérték ismerete sem hasznos. Legtöbbször csak néhány statisztikai adatra van szüksége. Így lekérheti magát a statisztikát a folyamaton belül, majd egyesével megírhat egy eseményt a statisztikák jelentéséhez.EventCounter
Az alábbiakban egy példa látható egy implementálásra System.Diagnostics.Tracing.EventSource. Hozzon létre egy MinimalEventCounterSource.cs nevű új fájlt, és használja a kódrészletet forrásként:
using System.Diagnostics.Tracing;
[EventSource(Name = "Sample.EventCounter.Minimal")]
public sealed class MinimalEventCounterSource : EventSource
{
public static readonly MinimalEventCounterSource Log = new MinimalEventCounterSource();
private EventCounter _requestCounter;
private MinimalEventCounterSource() =>
_requestCounter = new EventCounter("request-time", this)
{
DisplayName = "Request Processing Time",
DisplayUnits = "ms"
};
public void Request(string url, long elapsedMilliseconds)
{
WriteEvent(1, url, elapsedMilliseconds);
_requestCounter?.WriteMetric(elapsedMilliseconds);
}
protected override void Dispose(bool disposing)
{
_requestCounter?.Dispose();
_requestCounter = null;
base.Dispose(disposing);
}
}
A EventSource.WriteEvent sor a EventSource része, és nem a része EventCounter, hanem annak a része, amely azt mutatja, hogy az eseményszámlálóval együtt naplózhat egy üzenetet.
Műveletszűrő hozzáadása
A minta forráskód egy ASP.NET Core projekt. Globálisan hozzáadhat egy műveletszűrőt , amely naplózza a kérelem teljes idejét. Hozzon létre egy logRequestTimeFilterAttribute.cs nevű új fájlt, és használja a következő kódot:
using System.Diagnostics;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc.Filters;
namespace DiagnosticScenarios
{
public class LogRequestTimeFilterAttribute : ActionFilterAttribute
{
readonly Stopwatch _stopwatch = new Stopwatch();
public override void OnActionExecuting(ActionExecutingContext context) => _stopwatch.Start();
public override void OnActionExecuted(ActionExecutedContext context)
{
_stopwatch.Stop();
MinimalEventCounterSource.Log.Request(
context.HttpContext.Request.GetDisplayUrl(), _stopwatch.ElapsedMilliseconds);
}
}
}
A műveletszűrő a kérés kezdetekor elindul Stopwatch , és a befejeződése után leáll, rögzítve az eltelt időt. A rendszer az összes ezredmásodpercet az MinimalEventCounterSource
egyszeri példányba naplózza. A szűrő alkalmazásához hozzá kell adnia azt a szűrőgyűjteményhez. A Startup.cs fájlban frissítse a metódust ConfigureServices
a szűrő belefoglalásával.
public void ConfigureServices(IServiceCollection services) =>
services.AddControllers(options => options.Filters.Add<LogRequestTimeFilterAttribute>())
.AddNewtonsoftJson();
Eseményszámláló figyelése
Egy és az egyéni műveletszűrő implementálásával EventSource hozza létre és indítsa el az alkalmazást. A metrikát a EventCounter-be naplózta, de ha nem fér hozzá a statisztikához, az nem hasznos. A statisztikák lekéréséhez engedélyeznie kell a EventCounter beállítást egy olyan időzítő létrehozásával, amely a kívánt gyakoriságot aktiválja, valamint egy figyelőt az események rögzítéséhez. Ehhez használhatja a dotnet-counters parancsot.
A dotnet-counters ps paranccsal megjelenítheti a monitorozni kívánt .NET-folyamatok listáját.
dotnet-counters ps
A parancs kimenetéből dotnet-counters ps
származó folyamatazonosító használatával megkezdheti az eseményszámláló figyelését a következő dotnet-counters monitor
paranccsal:
dotnet-counters monitor --process-id 2196 --counters Sample.EventCounter.Minimal,Microsoft.AspNetCore.Hosting[total-requests,requests-per-second],System.Runtime[cpu-usage]
Amíg a dotnet-counters monitor
parancs fut, tartsa lenyomva az F5 billentyűt a böngészőben a végpont felé irányuló folyamatos kérések indításához https://localhost:5001/api/values
. Néhány másodperc elteltével állítsa le a q billentyűt
Press p to pause, r to resume, q to quit.
Status: Running
[Microsoft.AspNetCore.Hosting]
Request Rate / 1 sec 9
Total Requests 134
[System.Runtime]
CPU Usage (%) 13
[Sample.EventCounter.Minimal]
Request Processing Time (ms) 34.5
A dotnet-counters monitor
parancs kiválóan alkalmas aktív monitorozásra. Érdemes lehet azonban ezeket a diagnosztikai metrikákat összegyűjteni a feldolgozás és elemzés után. Ehhez használja a dotnet-counters collect
parancsot. A collect
switch parancs hasonló a monitor
parancshoz, de elfogad néhány további paramétert. Megadhatja a kívánt kimeneti fájlnevet és formátumot. A diagnostics.json nevű JSON-fájlhoz használja a következő parancsot:
dotnet-counters collect --process-id 2196 --format json -o diagnostics.json --counters Sample.EventCounter.Minimal,Microsoft.AspNetCore.Hosting[total-requests,requests-per-second],System.Runtime[cpu-usage]
A parancs futtatása közben is tartsa lenyomva az F5 billentyűt a böngészőben, hogy folyamatos kéréseket küldjön a https://localhost:5001/api/values
végpontnak. Néhány másodperc elteltével állítsa le a q billentyűt. A diagnostics.json fájl meg van írva. A megírt JSON-fájl azonban nincs behúzva; az olvashatóság érdekében itt van behúzva.
{
"TargetProcess": "DiagnosticScenarios",
"StartTime": "8/5/2020 3:02:45 PM",
"Events": [
{
"timestamp": "2020-08-05 15:02:47Z",
"provider": "System.Runtime",
"name": "CPU Usage (%)",
"counterType": "Metric",
"value": 0
},
{
"timestamp": "2020-08-05 15:02:47Z",
"provider": "Microsoft.AspNetCore.Hosting",
"name": "Request Rate / 1 sec",
"counterType": "Rate",
"value": 0
},
{
"timestamp": "2020-08-05 15:02:47Z",
"provider": "Microsoft.AspNetCore.Hosting",
"name": "Total Requests",
"counterType": "Metric",
"value": 134
},
{
"timestamp": "2020-08-05 15:02:47Z",
"provider": "Sample.EventCounter.Minimal",
"name": "Request Processing Time (ms)",
"counterType": "Metric",
"value": 0
},
{
"timestamp": "2020-08-05 15:02:47Z",
"provider": "System.Runtime",
"name": "CPU Usage (%)",
"counterType": "Metric",
"value": 0
},
{
"timestamp": "2020-08-05 15:02:48Z",
"provider": "Microsoft.AspNetCore.Hosting",
"name": "Request Rate / 1 sec",
"counterType": "Rate",
"value": 0
},
{
"timestamp": "2020-08-05 15:02:48Z",
"provider": "Microsoft.AspNetCore.Hosting",
"name": "Total Requests",
"counterType": "Metric",
"value": 134
},
{
"timestamp": "2020-08-05 15:02:48Z",
"provider": "Sample.EventCounter.Minimal",
"name": "Request Processing Time (ms)",
"counterType": "Metric",
"value": 0
},
{
"timestamp": "2020-08-05 15:02:48Z",
"provider": "System.Runtime",
"name": "CPU Usage (%)",
"counterType": "Metric",
"value": 0
},
{
"timestamp": "2020-08-05 15:02:50Z",
"provider": "Microsoft.AspNetCore.Hosting",
"name": "Request Rate / 1 sec",
"counterType": "Rate",
"value": 0
},
{
"timestamp": "2020-08-05 15:02:50Z",
"provider": "Microsoft.AspNetCore.Hosting",
"name": "Total Requests",
"counterType": "Metric",
"value": 134
},
{
"timestamp": "2020-08-05 15:02:50Z",
"provider": "Sample.EventCounter.Minimal",
"name": "Request Processing Time (ms)",
"counterType": "Metric",
"value": 0
}
]
}