Aracılığıyla paylaş


Öğretici: .NET Core'da EventCounters kullanarak performansı ölçme

Bu makale şunlar için geçerlidir: ✔️ .NET Core 3.0 SDK ve sonraki sürümler

Bu öğreticide, yüksek sıklıkta olaylarla performansı ölçmek için bir'in nasıl EventCounter kullanılabileceğini öğreneceksiniz. Çeşitli resmi .NET Core paketleri, üçüncü taraf sağlayıcılar tarafından yayımlanan kullanılabilir sayaçları kullanabilir veya izleme için kendi ölçümlerinizi oluşturabilirsiniz.

Bu öğreticide şunları yapacaksınız:

Önkoşullar

Öğreticide aşağıdakiler kullanılır:

Kaynağı alma

Örnek uygulama, izleme için temel olarak kullanılır. Örnek ASP.NET Core deposuna örnek tarayıcıdan ulaşabilirsiniz. Zip dosyasını indirir, indirdikten sonra ayıklar ve sık kullandığınız IDE'de açarsınız. Düzgün çalıştığından emin olmak için uygulamayı derleyin ve çalıştırın, ardından uygulamayı durdurun.

EventSource uygulama

Birkaç milisaniyede bir gerçekleşen olaylar için olay başına ek yükün düşük olmasını (milisaniyeden az) istersiniz. Aksi takdirde, performans üzerindeki etkisi önemli olacaktır. Bir olayı günlüğe kaydetmek, diske bir şey yazacağınız anlamına gelir. Disk yeterince hızlı değilse, olayları kaybedersiniz. Olayın günlüğe kaydedilmesi dışında bir çözüme ihtiyacınız vardır.

Çok sayıda olayla ilgilenirken, olay başına ölçüyü bilmek de yararlı değildir. Çoğu zaman tek ihtiyacınız olan bazı istatistikler. Böylece sürecin içindeki istatistikleri alabilir ve arada bir istatistikleri raporlamak için bir olay yazabilirsiniz. EventCounter Bunu yapmanız gerekir.

Aşağıda bir uygulama örneği verilmiştir System.Diagnostics.Tracing.EventSource. MinimalEventCounterSource.cs adlı yeni bir dosya oluşturun ve kaynak olarak kod parçacığını kullanın:

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

satırı EventSource.WriteEvent bölümüdür ve öğesinin EventSourceEventCounterparçası değildir, olay sayacıyla birlikte bir iletiyi günlüğe kaydedebileceğinizi göstermek için yazılmıştır.

Eylem filtresi ekleme

Örnek kaynak kodu bir ASP.NET Core projesidir. Genel olarak toplam istek süresini günlüğe kaydedecek bir eylem filtresi ekleyebilirsiniz. LogRequestTimeFilterAttribute.cs adlı yeni bir dosya oluşturun ve aşağıdaki kodu kullanın:

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

Eylem filtresi, istek başladıktan sonra bir Stopwatch başlatır ve tamamlandıktan sonra durur ve geçen süreyi yakalar. Toplam milisaniye tekil örneğe kaydedilir MinimalEventCounterSource . Bu filtrenin uygulanması için filtre koleksiyonuna eklemeniz gerekir. Startup.cs dosyasında bu filtreyi ConfigureServices dahil et içindeki yöntemini güncelleştirin.

public void ConfigureServices(IServiceCollection services) =>
    services.AddControllers(options => options.Filters.Add<LogRequestTimeFilterAttribute>())
            .AddNewtonsoftJson();

Olay sayacını izleme

uygulaması EventSource ve özel eylem filtresi ile uygulamayı derleyin ve başlatın. Ölçümü öğesine günlüğe EventCounterkaydetmişsinizdir, ancak istatistiklere erişmediğiniz sürece yararlı olmaz. İstatistikleri almak için, olayları istediğiniz sıklıkta tetikleyen bir zamanlayıcı ve olayları yakalamak için bir dinleyici oluşturarak öğesini etkinleştirmeniz EventCounter gerekir. Bunu yapmak için dotnet-counters kullanabilirsiniz.

İzlenebilen .NET işlemlerinin listesini görüntülemek için dotnet-counters ps komutunu kullanın.

dotnet-counters ps

Komutun çıkışındaki işlem tanımlayıcısını dotnet-counters ps kullanarak, aşağıdaki dotnet-counters monitor komutla olay sayacını izlemeye başlayabilirsiniz:

dotnet-counters monitor --process-id 2196 --counters Sample.EventCounter.Minimal,Microsoft.AspNetCore.Hosting[total-requests,requests-per-second],System.Runtime[cpu-usage]

dotnet-counters monitor Komut çalışırken, uç noktaya sürekli istekler göndermeye başlamak için tarayıcıda F5'ihttps://localhost:5001/api/values tutun. Birkaç saniye sonra q tuşuna basarak durdurun

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

Komutu dotnet-counters monitor etkin izleme için harikadır. Ancak, bu tanılama ölçümlerini işleme ve analiz sonrası için toplamak isteyebilirsiniz. Bunun için komutunu kullanın dotnet-counters collect . collect switch komutu komutuna monitor benzer, ancak birkaç ek parametre kabul eder. İstediğiniz çıkış dosyası adını ve biçimini belirtebilirsiniz. diagnostics.json adlı bir JSON dosyası için aşağıdaki komutu kullanın:

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]

Komut çalışırken, uç noktaya sürekli istekler göndermeye başlamak için tarayıcıda F5'ihttps://localhost:5001/api/values basılı tutun. Birkaç saniye sonra q tuşuna basarak durdurun. diagnostics.json dosyası yazılır. Ancak, yazılan JSON dosyası girintili değildir; okunabilirlik için burada girintilenmiştir.

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

Sonraki adımlar