dotnet-diagnostics-core 0.32.1

dotnet add package dotnet-diagnostics-core --version 0.32.1
                    
NuGet\Install-Package dotnet-diagnostics-core -Version 0.32.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="dotnet-diagnostics-core" Version="0.32.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="dotnet-diagnostics-core" Version="0.32.1" />
                    
Directory.Packages.props
<PackageReference Include="dotnet-diagnostics-core" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add dotnet-diagnostics-core --version 0.32.1
                    
#r "nuget: dotnet-diagnostics-core, 0.32.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package dotnet-diagnostics-core@0.32.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=dotnet-diagnostics-core&version=0.32.1
                    
Install as a Cake Addin
#tool nuget:?package=dotnet-diagnostics-core&version=0.32.1
                    
Install as a Cake Tool

dotnet-diagnostics-core

The transport-agnostic .NET diagnostics engine behind the dotnet-diagnostics-mcp MCP server and the dotnet-diagnostics-cli. It attaches to a live .NET process over the runtime diagnostic IPC socket and turns raw EventPipe / ClrMD / TraceEvent streams into structured results. Those normal paths require no target code changes or prior instrumentation. The explicit exception is MethodParameterCaptureUseCases: it performs a privileged dynamic attach of vendored dotnet-monitor profilers plus a startup hook and temporarily ReJIT-instruments an allowlist of methods; hosts must expose that sensitive capability only behind an explicit authorization policy.

This package exists so other hosts can call the same engine in-process, without shelling out to a tool. The first such consumer is the BenchmarkDotNet diagnoser (dotnet-diagnostics-benchmarkdotnet).

dotnet add package dotnet-diagnostics-core

Consumer target frameworks: net8.0, net9.0, net10.0. Platform: the engine attaches over the diagnostic IPC socket; live ClrMD memory readers (heap/thread snapshots, method bytes, module bytes) additionally need CAP_SYS_PTRACE on Linux and the same UID as the target. Process dumps write through diagnostic IPC and do not require that kernel capability. See the repo docs for the deployment matrix.

Supported public surface (Pattern B — curated facade)

⚠️ Pre-1.0 / unstable. While this package is versioned 0.x it carries no SemVer API stability guarantee. Only the entry points listed below are intended for external use; every other public type is an implementation detail that will be internalized incrementally and may change or disappear without a major-version bump. Depend on the facade, not on the plumbing.

The supported entry points are the static use-case classes; each method returns a DiagnosticResult<T> envelope (success payload, DiagnosticError, and NextActionHints):

Use-case class What it does
ProcessInspectionUseCases Discover .NET processes; process / capability / container / runtime-config / triage views.
EventCollectionUseCases EventPipe collection: counters, exceptions, GC, GC DATAS, logs, JIT, threadpool, contention, db, activities, event-source, event catalog.
HeapInspectionUseCases Live or dump heap walk + drilldown handles.
ProcessDumpUseCases Write a process dump (Mini / Triage / WithHeap / Full).
ByteMaterializationUseCases Stream module (PE/PDB) or dump bytes.
MethodParameterCaptureUseCases Explicit dynamic-profiler capture of allowlisted method parameters on supported CoreCLR targets.
IDiagnosticSession / ICounterSessionFactory Attach typed callbacks, start, cancel, and stop a bounded live EventCounter session; terminal status reports EventPipe loss and dropped observations.
ComposedDiagnosticSession Combine live sessions with finite captures behind one bounded, typed callback dispatcher.

Supporting types that are part of the facade because the use-cases return or accept them:

  • DiagnosticResult / DiagnosticResult<T>, DiagnosticError, NextActionHint — the result envelope.
  • The per-collector snapshot/result records returned by the use-cases (e.g. CounterSnapshot, GcSummary, ContentionSnapshot, …).

Live counter sessions are separate from finite EventCollectionUseCases snapshots. Attach one or more typed handlers before starting; the Core dispatcher invokes matching callbacks serially in registration order. Event sequence numbers are assigned before bounded queue insertion, so gaps reveal drops; the queue (maximum capacity 16,384) drops new observations when full and reports the total in DiagnosticSessionCompletion. Session options validate positive process IDs and intervals, cap provider lists at 64 names of at most 256 characters each, and reject queue capacities outside the documented bound before opening EventPipe. The live CounterSession.DroppedObservations property exposes the running count. Use StopAsync, DisposeAsync, or the cancellation token passed to StartAsync to stop and drain the session.

await using var session = counterSessions.CreateSession(processId);
using var subscription = session.Attach<CounterObservation>((observation, cancellationToken) =>
{
    Console.WriteLine($"{observation.Sequence}: {observation.Counter.Name}={observation.Counter.Value}");
    return ValueTask.CompletedTask;
});

await session.StartAsync(cancellationToken);
var completion = await session.Completion;

IDiagnosticSession is the common lifecycle and typed event attachment contract. Event-specific session factories can publish additional DiagnosticSessionEvent record types without changing existing finite collector APIs. Live counters and the IStreaming*Collector interfaces for exceptions, activities, monitor contention, GC, logs, JIT, ThreadPool, startup, database activity, networking, Kestrel, crash-guard exceptions, generic EventSource events, EventSource catalog metadata, in-flight request lifecycle events, memory trend samples, and process-resource samples publish typed observations incrementally. GC DATAS post-processing, CPU/allocation samplers, point-in-time readers, and other offline aggregations remain finite operations; add them with AddCapture to publish their typed terminal result rather than implying live observations their collectors do not expose. Stopping cancels capture producers; callbacks continue draining the bounded queue. The callback cancellation token is canceled if handler delivery exceeds the shutdown wait budget.

Use ComposedDiagnosticSession when one consumer needs multiple capture families in one lifecycle. Add live sessions with AddSession; add existing finite collector/use-case calls with AddCapture. Each finite operation publishes exactly one DiagnosticSessionCaptureResult<TCapture> event containing its statically typed result. For windowed collectors that expose observations, use AddStreamingCapture: it publishes each typed observation as a DiagnosticSessionObservation<TObservation> and then the same typed terminal result. Point-in-time operations remain a single result event. Capture operations run concurrently, and all events share the composed session's bounded queue and monotonic sequence. Collectors with multiple observation types can use AddEventCapture and publish each type as its own DiagnosticSessionEvent.

For example, attach a CounterObservation handler and a DiagnosticSessionObservation<ManagedExceptionEvent> handler, add the live counter session with AddSession, and add IStreamingExceptionCollector.CollectStreamingAsync with AddStreamingCapture. Both capture families then share one start/stop lifecycle and callback queue; the exception snapshot is also delivered as a DiagnosticSessionCaptureResult<ExceptionSnapshot>.

Finite operations and evidence recording

AddCapture<T> accepts any existing asynchronous collector result without a family-specific adapter. Use it for GC DATAS post-processing, CPU/allocation/off-CPU/native samplers, CPU-efficiency sampling, method-parameter capture, dump/heap/thread inspection, requests-now, and other point-in-time operations. The callback gets the original result, including handles and partial/error/cancellation information when the capture returns a DiagnosticResult<T>. A completed session means its producers and callback delivery finished; it does not turn a failed diagnostic envelope into a successful diagnostic result.

await using var session = new ComposedDiagnosticSession(pid);
using var subscription =
    session.Attach<DiagnosticSessionCaptureResult<DiagnosticResult<GcDatasSnapshot>>>((item, token) =>
    {
        Console.WriteLine(item.Result.Summary);
        return ValueTask.CompletedTask;
    });
session.AddDiagnosticCapture("datas", "GC tuning", token =>
    EventCollectionUseCases.CollectGcDatas(datasCollector, processResolver, handleStore,
        processId: pid, durationSeconds: 10, cancellationToken: token));
await session.StartAsync(cancellationToken);
var completion = await session.Completion;

Named AddCapture(kind, name, ...), AddStreamingCapture(kind, name, ...), and AddEventCapture(kind, name, ...) sources enter separate child routes when started inside an existing evidence-recording scope. Use AddDiagnosticCapture for use-case envelopes: it records the structured error, cancellation flag, and typed payload without persisting the envelope as an arbitrary object. The raw named overloads expect snapshot/artifact results, not DiagnosticResult<T> envelopes. Without an active recording scope, named sources remain ephemeral and never open SQLite themselves.

For durable composition, execute StartAsync and await Completion inside a DurableCaptureUseCases.CaptureAsync operation using the existing batch parent kind. Capture kinds and retained artifact types must be supported by the durable codec; a session does not make unsupported operations persistable. Collectors continue using their existing bounded, redacted observation projections. Final typed child results are retained independently of callback delivery, so a full session queue can drop even a terminal callback without losing that producer's recorded snapshot. DiagnosticSessionCompletion.DroppedObservations measures callback-queue loss, not SQLite record loss; the durable capture's quality metadata reports recording/source loss separately.

Plain unnamed sources and AddSession do not establish child recording routes. A child live counter session does not currently record its callbacks through this bridge; use a named finite counter capture for durable counter evidence. No generic callback-to-JSON or callback-to-SQLite serializer is introduced.

Example

using DotnetDiagnostics.Core.UseCases;

// Snapshot EventCounters for ~5s from a target PID.
DiagnosticResult<CounterSnapshot> result =
    await EventCollectionUseCases.SnapshotCounters(processId: pid, durationSeconds: 5);

if (result.IsSuccess)
{
    foreach (var hint in result.Hints)
        Console.WriteLine(hint.Message);
}

Not in scope for this package

  • The MCP tool surface, HTTP transport and bearer auth live in dotnet-diagnostics-mcp.
  • The one-shot / REPL command line lives in dotnet-diagnostics-cli.

License

MIT — see the repository.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on dotnet-diagnostics-core:

Package Downloads
dotnet-diagnostics-benchmarkdotnet

A BenchmarkDotNet IDiagnoser for net8.0/net9.0/net10.0 benchmark projects that attaches the dotnet-diagnostics engine in-process to a benchmark's child process and captures EventPipe perf indicators (GC, contention, thread pool, exceptions, JIT, counters, …) as JSON artifacts plus a per-run "biggest offenders" report. Tag benchmark methods with [DiagnosticKind] and add [DotnetDiagnosticsDiagnoser] to the benchmark class.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.32.1 52 10/22/2026
0.31.0 109 10/16/2026
0.30.0 123 10/15/2026
0.29.0 128 10/13/2026
0.28.0 292 9/30/2026
0.27.0 158 9/18/2026
0.26.0 142 9/17/2026
0.25.0 737 8/28/2026
0.24.0 1,213 8/19/2026
0.23.0 156 8/13/2026
0.22.0 151 8/1/2026
0.21.0 151 7/30/2026
0.20.0 144 7/29/2026
0.19.0 146 7/21/2026
0.18.0 143 7/20/2026
0.17.0 153 7/7/2026
0.16.0 148 7/2/2026
0.15.0 156 7/2/2026
0.14.0 183 6/11/2026
0.13.0 150 6/10/2026
Loading failed