Pustaka klien diagnostik
Artikel ini berlaku untuk: ✔️ .NET Core 3.0 SDK dan versi yang lebih baru untuk aplikasi target, .NET Standard 2.0 untuk menggunakan pustaka.
Microsoft.Diagnostics.NETCore.Client
(juga dikenal sebagai pustaka klien Diagnostik) adalah pustaka terkelola yang memungkinkan Anda berinteraksi dengan runtime .NET Core (CoreCLR) untuk berbagai tugas terkait diagnostik, seperti melacak melalui EventPipe, meminta cadangan, atau melampirkan ICorProfiler
. Pustaka ini adalah pustaka cadangan di balik banyak alat diagnostik seperti penghitung dotnet, dotnet-trace, dotnet-gcdump, dotnet-dump, dan dotnet-monitor. Dengan menggunakan pustaka ini, Anda dapat menulis alat diagnostik Anda sendiri yang disesuaikan untuk skenario tertentu Anda.
Anda dapat memperoleh Microsoft.Diagnostics.NETCore.Client dengan menambahkan PackageReference
ke proyek Anda. Paket dihosting pada NuGet.org
.
Sampel di bagian berikut menunjukkan cara menggunakan pustaka Microsoft.Diagnostics.NETCore.Client. Beberapa contoh ini juga menunjukkan penguraian payload peristiwa dengan menggunakan pustaka TraceEvent .
Lampirkan ke proses dan cetak semua peristiwa GC
Cuplikan ini menunjukkan cara memulai sesi EventPipe menggunakan penyedia runtime .NET dengan kata kunci GC pada tingkat informasi. Ini juga menunjukkan cara menggunakan EventPipeEventSource
kelas yang disediakan oleh pustaka TraceEvent untuk mengurai peristiwa masuk dan mencetak namanya ke konsol secara real time.
using Microsoft.Diagnostics.NETCore.Client;
using Microsoft.Diagnostics.Tracing;
using Microsoft.Diagnostics.Tracing.EventPipe;
using Microsoft.Diagnostics.Tracing.Parsers;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
public class RuntimeGCEventsPrinter
{
public static void PrintRuntimeGCEvents(int processId)
{
var providers = new List<EventPipeProvider>()
{
new EventPipeProvider("Microsoft-Windows-DotNETRuntime",
EventLevel.Informational, (long)ClrTraceEventParser.Keywords.GC)
};
var client = new DiagnosticsClient(processId);
using (EventPipeSession session = client.StartEventPipeSession(providers, false))
{
var source = new EventPipeEventSource(session.EventStream);
source.Clr.All += (TraceEvent obj) => Console.WriteLine(obj.ToString());
try
{
source.Process();
}
catch (Exception e)
{
Console.WriteLine("Error encountered while processing events");
Console.WriteLine(e.ToString());
}
}
}
}
Menulis cadangan inti
Sampel ini menunjukkan cara memicu pengumpulan core dump menggunakan DiagnosticsClient
.
using Microsoft.Diagnostics.NETCore.Client;
public partial class Dumper
{
public static void TriggerCoreDump(int processId)
{
var client = new DiagnosticsClient(processId);
client.WriteDump(DumpType.Normal, "/tmp/minidump.dmp");
}
}
Memicu cadangan inti saat penggunaan CPU berada di atas ambang batas
Sampel ini menunjukkan cara memantau penghitung yang cpu-usage
diterbitkan oleh runtime .NET dan meminta cadangan ketika penggunaan CPU tumbuh di luar ambang tertentu.
using Microsoft.Diagnostics.NETCore.Client;
using Microsoft.Diagnostics.Tracing;
using Microsoft.Diagnostics.Tracing.EventPipe;
using Microsoft.Diagnostics.Tracing.Parsers;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
public partial class Dumper
{
public static void TriggerDumpOnCpuUsage(int processId, int threshold)
{
var providers = new List<EventPipeProvider>()
{
new EventPipeProvider(
"System.Runtime",
EventLevel.Informational,
(long)ClrTraceEventParser.Keywords.None,
new Dictionary<string, string>
{
["EventCounterIntervalSec"] = "1"
}
)
};
var client = new DiagnosticsClient(processId);
using (var session = client.StartEventPipeSession(providers))
{
var source = new EventPipeEventSource(session.EventStream);
source.Dynamic.All += (TraceEvent obj) =>
{
if (obj.EventName.Equals("EventCounters"))
{
var payloadVal = (IDictionary<string, object>)(obj.PayloadValue(0));
var payloadFields = (IDictionary<string, object>)(payloadVal["Payload"]);
if (payloadFields["Name"].ToString().Equals("cpu-usage"))
{
double cpuUsage = Double.Parse(payloadFields["Mean"].ToString());
if (cpuUsage > (double)threshold)
{
client.WriteDump(DumpType.Normal, "/tmp/minidump.dmp");
}
}
}
};
try
{
source.Process();
}
catch (Exception) {}
}
}
}
Memicu jejak CPU untuk jumlah detik tertentu
Sampel ini menunjukkan cara memicu sesi EventPipe untuk periode waktu tertentu dengan kata kunci pelacakan CLR default serta profiler sampel. Setelah itu, ia membaca aliran output dan menulis byte ke file. Pada dasarnya inilah yang dotnet-trace
menggunakan secara internal untuk menulis file pelacakan.
using Microsoft.Diagnostics.Tracing;
using Microsoft.Diagnostics.Tracing.Parsers;
using Microsoft.Diagnostics.NETCore.Client;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.Tracing;
using System.IO;
using System.Threading.Tasks;
public partial class Tracer
{
public void TraceProcessForDuration(int processId, int duration, string traceName)
{
var cpuProviders = new List<EventPipeProvider>()
{
new EventPipeProvider("Microsoft-Windows-DotNETRuntime", EventLevel.Informational, (long)ClrTraceEventParser.Keywords.Default),
new EventPipeProvider("Microsoft-DotNETCore-SampleProfiler", EventLevel.Informational, (long)ClrTraceEventParser.Keywords.None)
};
var client = new DiagnosticsClient(processId);
using (var traceSession = client.StartEventPipeSession(cpuProviders))
{
Task copyTask = Task.Run(async () =>
{
using (FileStream fs = new FileStream(traceName, FileMode.Create, FileAccess.Write))
{
await traceSession.EventStream.CopyToAsync(fs);
}
});
Task.WhenAny(copyTask, Task.Delay(TimeSpan.FromMilliseconds(duration * 1000)));
traceSession.Stop();
}
}
}
Mencetak nama proses yang menerbitkan saluran diagnostik
Sampel ini menunjukkan cara menggunakan DiagnosticsClient.GetPublishedProcesses
API untuk mencetak nama proses .NET yang menerbitkan saluran IPC diagnostik.
using Microsoft.Diagnostics.NETCore.Client;
using System;
using System.Diagnostics;
using System.Linq;
public class ProcessTracker
{
public static void PrintProcessStatus()
{
var processes = DiagnosticsClient.GetPublishedProcesses()
.Select(Process.GetProcessById)
.Where(process => process != null);
foreach (var process in processes)
{
Console.WriteLine($"{process.ProcessName}");
}
}
}
Mengurai peristiwa secara real time
Sampel ini menunjukkan contoh di mana kita membuat dua tugas, satu yang mengurai peristiwa yang ditayangkan dan EventPipeEventSource
yang membaca input konsol untuk input pengguna yang menandakan program berakhir. Jika aplikasi target keluar sebelum pengguna menekan enter, aplikasi akan keluar dengan baik. Jika tidak, inputTask
akan mengirim perintah Stop ke pipa dan keluar dengan anggun.
using Microsoft.Diagnostics.NETCore.Client;
using Microsoft.Diagnostics.Tracing;
using Microsoft.Diagnostics.Tracing.EventPipe;
using Microsoft.Diagnostics.Tracing.Parsers;
using System;
using System.Collections.Generic;
using System.Diagnostics.Tracing;
using System.Threading.Tasks;
public partial class Tracer
{
public static void PrintEventsLive(int processId)
{
var providers = new List<EventPipeProvider>()
{
new EventPipeProvider("Microsoft-Windows-DotNETRuntime",
EventLevel.Informational, (long)ClrTraceEventParser.Keywords.Default)
};
var client = new DiagnosticsClient(processId);
using (var session = client.StartEventPipeSession(providers, false))
{
Task streamTask = Task.Run(() =>
{
var source = new EventPipeEventSource(session.EventStream);
source.Clr.All += (TraceEvent obj) => Console.WriteLine(obj.EventName);
try
{
source.Process();
}
// NOTE: This exception does not currently exist. It is something that needs to be added to TraceEvent.
catch (Exception e)
{
Console.WriteLine("Error encountered while processing events");
Console.WriteLine(e.ToString());
}
});
Task inputTask = Task.Run(() =>
{
Console.WriteLine("Press Enter to exit");
while (Console.ReadKey().Key != ConsoleKey.Enter)
{
Task.Delay(TimeSpan.FromMilliseconds(100));
}
session.Stop();
});
Task.WaitAny(streamTask, inputTask);
}
}
}
Melampirkan profiler ICorProfiler
Sampel ini menunjukkan cara melampirkan ICorProfiler ke proses melalui lampirkan profiler.
using System;
using Microsoft.Diagnostics.NETCore.Client;
public class Profiler
{
public static void AttachProfiler(int processId, Guid profilerGuid, string profilerPath)
{
var client = new DiagnosticsClient(processId);
client.AttachProfiler(TimeSpan.FromSeconds(10), profilerGuid, profilerPath);
}
}
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