Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
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 level informasional. Ini juga menunjukkan cara menggunakan kelas EventPipeEventSource yang disediakan oleh pustaka TraceEvent untuk mem-parsing event yang masuk dan mencetak nama-nama event ke konsol secara waktu nyata.
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 untuk memantau penghitung cpu-usage yang diterbitkan oleh runtime .NET dan meminta pencatatan saat penggunaan CPU meningkat 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) {}
}
}
}
Mengaktifkan pelacakan CPU selama sejumlah 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 memublikasikan 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 memproses peristiwa yang datang secara langsung dengan EventPipeEventSource dan satu lagi yang membaca input konsol untuk sinyal pengguna yang menandakan berakhirnya program. 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);
}
}
}
Pasang profiler ICorProfiler
Contoh ini menunjukkan cara melampirkan ICorProfiler ke proses melalui pelekatan 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);
}
}