Tutorial: Mengukur performa menggunakan EventCounters di .NET Core
Artikel ini berlaku untuk: ✔️ .NET Core 3.0 SDK dan versi yang lebih baru
Dalam tutorial ini, Anda akan mempelajari bagaimana dapat EventCounter digunakan untuk mengukur performa dengan frekuensi peristiwa yang tinggi. Anda dapat menggunakan penghitung yang tersedia yang diterbitkan oleh berbagai paket .NET Core resmi, penyedia pihak ketiga, atau membuat metrik Anda sendiri untuk pemantauan.
Dalam tutorial ini, Anda akan:
- EventSourceMenerapkan .
- Pantau penghitung dengan penghitung dotnet.
Prasyarat
Tutorial ini menggunakan:
- .NET Core 3.1 SDK atau versi yang lebih baru.
- penghitung dotnet untuk memantau penghitung peristiwa.
- Sampel aplikasi target debug untuk didiagnosis.
Dapatkan sumbernya
Aplikasi sampel akan digunakan sebagai dasar untuk pemantauan. Sampel ASP.NET repositori Core tersedia dari browser sampel. Anda mengunduh file zip, mengekstraknya setelah diunduh, dan membukanya di IDE favorit Anda. Bangun dan jalankan aplikasi untuk memastikan bahwa aplikasi berfungsi dengan baik, lalu hentikan aplikasi.
Menerapkan EventSource
Untuk peristiwa yang terjadi setiap beberapa milidetik, Anda mungkin ingin overhead per peristiwa rendah (kurang dari milidetik). Jika tidak, dampak pada performa akan signifikan. Mencatat peristiwa berarti Anda akan menulis sesuatu ke disk. Jika disk tidak cukup cepat, Anda akan kehilangan peristiwa. Anda memerlukan solusi selain mencatat peristiwa itu sendiri.
Saat berhadapan dengan sejumlah besar peristiwa, mengetahui ukuran per peristiwa juga tidak berguna. Sebagian besar waktu yang Anda butuhkan hanyalah beberapa statistik dari itu. Jadi Anda bisa mendapatkan statistik dalam proses itu sendiri dan kemudian menulis peristiwa sekali-sekali untuk melaporkan statistik, itulah yang EventCounter akan dilakukan.
Di bawah ini adalah contoh cara mengimplementasikan System.Diagnostics.Tracing.EventSource. Buat file baru bernama MinimalEventCounterSource.cs dan gunakan cuplikan kode sebagai sumbernya:
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);
}
}
Baris EventSource.WriteEvent adalah EventSource bagian dan bukan bagian EventCounterdari , itu ditulis untuk menunjukkan bahwa Anda dapat mencatat pesan bersama dengan penghitung peristiwa.
Menambahkan filter tindakan
Kode sumber sampel adalah proyek ASP.NET Core. Anda dapat menambahkan filter tindakan secara global yang akan mencatat total waktu permintaan. Buat file baru bernama LogRequestTimeFilterAttribute.cs, dan gunakan kode berikut:
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);
}
}
}
Filter tindakan dimulai saat Stopwatch permintaan dimulai, dan berhenti setelah selesai, menangkap waktu yang berlalu. Total milidetik dicatat ke MinimalEventCounterSource
instans singleton. Agar filter ini diterapkan, Anda perlu menambahkannya ke koleksi filter. Dalam file Startup.cs , perbarui metode di sertakan ConfigureServices
filter ini.
public void ConfigureServices(IServiceCollection services) =>
services.AddControllers(options => options.Filters.Add<LogRequestTimeFilterAttribute>())
.AddNewtonsoftJson();
Memantau penghitung peristiwa
Dengan implementasi pada EventSource dan filter tindakan kustom, buat dan luncurkan aplikasi. Anda mencatat metrik ke EventCounter, tetapi kecuali Anda mengakses statistik dari metrik tersebut, metrik tersebut tidak berguna. Untuk mendapatkan statistik, Anda perlu mengaktifkan EventCounter dengan membuat timer yang diaktifkan sesering yang Anda inginkan, serta pendengar untuk menangkap peristiwa. Untuk melakukannya, Anda dapat menggunakan penghitung dotnet.
Gunakan perintah ps penghitung dotnet untuk menampilkan daftar proses .NET yang dapat dipantau.
dotnet-counters ps
Dengan menggunakan pengidentifikasi proses dari output dotnet-counters ps
perintah, Anda dapat mulai memantau penghitung peristiwa dengan perintah berikut dotnet-counters monitor
:
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
Saat perintah berjalan, tahan F5 di browser untuk mulai mengeluarkan permintaan berkelanjutan ke https://localhost:5001/api/values
titik akhir. Setelah beberapa detik berhenti dengan menekan q
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
Perintah dotnet-counters monitor
ini sangat bagus untuk pemantauan aktif. Namun, Anda mungkin ingin mengumpulkan metrik diagnostik ini untuk pemrosesan dan analisis pasca. Untuk itu, gunakan dotnet-counters collect
perintah . Perintah collect
switch mirip monitor
dengan perintah , tetapi menerima beberapa parameter tambahan. Anda dapat menentukan nama dan format file output yang diinginkan. Untuk file JSON bernama diagnostics.json gunakan perintah berikut:
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]
Sekali lagi, saat perintah sedang berjalan, tahan F5 di browser untuk mulai mengeluarkan permintaan berkelanjutan ke https://localhost:5001/api/values
titik akhir. Setelah beberapa detik berhenti dengan menekan q. File diagnostics.json ditulis. Namun, file JSON yang ditulis tidak diindentasi; untuk keterbacaan, itu diindentasi di sini.
{
"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
}
]
}
Langkah berikutnya
Saran dan Komentar
https://aka.ms/ContentUserFeedback.
Segera hadir: Sepanjang tahun 2024 kami akan menghentikan penggunaan GitHub Issues sebagai mekanisme umpan balik untuk konten dan menggantinya dengan sistem umpan balik baru. Untuk mengetahui informasi selengkapnya, lihat:Kirim dan lihat umpan balik untuk