Megosztás a következőn keresztül:


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:

Előfeltételek

Az oktatóanyag a következőket használja:

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

Következő lépések