Poznámka:
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Tento článek se vztahuje na: ✔️ .NET Core 3.0 SDK a novější verze pro cílové aplikace, .NET Standard 2.0 pro použití knihovny.
Microsoft.Diagnostics.NETCore.Client (také známá jako klientská knihovna Diagnostiky) je spravovaná knihovna, která umožňuje interakci s .NET Core runtime (CoreCLR) pro různé úlohy související s diagnostikou, jako je sledování pomocí EventPipe, požadování výpisu nebo připojení ICorProfiler. Tato knihovna je podpůrnou knihovnou za mnoha diagnostickými nástroji, jako jsou dotnet-counters, dotnet-trace, dotnet-gcdump, dotnet-dump a dotnet-monitor. Pomocí této knihovny můžete napsat vlastní diagnostické nástroje přizpůsobené konkrétnímu scénáři.
Microsoft.Diagnostics.NETCore.Client můžete získat přidáním PackageReference do projektu. Balíček je hostovaný na NuGet.orgserveru .
Ukázky v následujících částech ukazují, jak používat knihovnu Microsoft.Diagnostics.NETCore.Client. Některé z těchto příkladů také ukazují parsování datových částí událostí pomocí knihovny TraceEvent .
Připojení k procesu a vytištění všech událostí GC
Tento fragment kódu ukazuje, jak spustit relaci EventPipe pomocí zprostředkovatele modulu runtime .NET s klíčovým slovem GC na informační úrovni. Ukazuje také, jak použít EventPipeEventSource třídu poskytovanou knihovnou TraceEvent k analýze příchozích událostí a tisku jejich názvů do konzoly v reálném čase.
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());
}
}
}
}
Vytvoření výpisu paměti jádra
Tato ukázka ukazuje, jak aktivovat kolekci výpisu paměti jádra pomocí 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");
}
}
Spustit výpis jádra, když využití procesoru překročí prahovou hodnotu
Tento příklad ukazuje, jak monitorovat cpu-usage čítač publikovaný modulem runtime .NET a vyžádat si výpis, pokud využití procesoru překročí určitou prahovou hodnotu.
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) {}
}
}
}
Aktivace trasování procesoru pro daný počet sekund
Tato ukázka ukazuje, jak aktivovat relaci EventPipe po určitou dobu pomocí výchozího klíčového slova trasování CLR a ukázkového profileru. Potom přečte výstupní datový proud a zapíše bajty do souboru. V podstatě se jedná o to, co dotnet-trace interně používá k zápisu trasovacího souboru.
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();
}
}
}
Tisk názvů procesů, které zveřejnily diagnostický kanál
Tato ukázka ukazuje, jak pomocí DiagnosticsClient.GetPublishedProcesses rozhraní API vytisknout názvy procesů .NET, které publikovaly kanál IPC diagnostiky.
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}");
}
}
}
Parsování událostí v reálném čase
Tato ukázka představuje příklad, kdy vytvoříme dva úkoly: jeden, který analyzuje události přicházející v reálném čase pomocí EventPipeEventSource, a druhý, který čte vstup z konzoly, aby rozpoznal vstup uživatele signalizující ukončení programu. Pokud se cílová aplikace ukončí předtím, než uživatel stiskne klávesu Enter, aplikace se řádně ukončí.
inputTask V opačném případě se příkaz Zastavit odešle do kanálu a elegantně ukončí.
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);
}
}
}
Připojení profileru ICorProfiler
Tato ukázka ukazuje, jak připojit ICorProfiler k procesu prostřednictvím připojení profileru.
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);
}
}