Pipeline Runtime Observation β FlowProxy + RingBufferObserver (v1.52.0)
Make your class partial and the generator emits a FlowProxy β always-on tracing via svc.Flow.Process() and single-trace debug via svc.Flow.Debug.Process(). Per-node output values, error types, and elapsed milliseconds for every execution.
Always-on tracing (multiple calls, full ring buffer):
using REslava.Result.Observers;
// Make the class partial β FlowProxy is generated automatically:
public partial class OrderService { ... }
var ringBuffer = new RingBufferObserver(capacity: 50);
PipelineObserver.Register(ringBuffer);
var result = svc.Flow.Process(userId, productId); // wraps the real method
PipelineObserver.Unregister();
ringBuffer.Save(); // β reslava-traces.json in bin/ β VSIX Debug panel picks it up
foreach (var trace in ringBuffer.GetTraces())
{
Console.WriteLine($"{trace.MethodName} β {(trace.IsSuccess ? "β" : "β " + trace.ErrorType)} ({trace.ElapsedMs}ms)");
foreach (var node in trace.Nodes)
Console.WriteLine($" [{node.Index}] {node.NodeId,-8}: {node.OutputValue} ({node.ElapsedMs}ms)");
}
Single-trace debug (one call, one trace, auto-saved):
svc.Flow.Debug.Process(userId, productId);
// β reslava-debug-Process.json saved to bin/
// β VSIX file watcher fires β Debug panel opens automatically
The DebugProxy creates its own RingBufferObserver(capacity: 1), captures exactly one execution, and calls Save() in the finally block β no manual setup required.
RingBufferObserver API:
var obs = new RingBufferObserver(capacity: 100); // bounded; evicts oldest on overflow
PipelineObserver.Register(obs);
// ... run pipelines ...
var traces = obs.GetTraces(); // snapshot β safe to iterate while pipelines run
obs.Clear(); // reset
obs.Save(); // β reslava-traces.json (default, VSIX auto-loads)
obs.Save("my-run"); // β reslava-my-run.json
obs.Save("/abs/path/out.json"); // β exact path (not picked up by VSIX watcher)
Scoped registration (test / per-request isolation):
using var _ = PipelineObserver.RegisterScoped(new RingBufferObserver());
// observer is automatically unregistered when the using block exits
VSIX Debug panel β βΆ Debug CodeLens (v1.53.0):
The REslava.Result Extensions VS Code extension adds a βΆ Debug CodeLens above every .Flow.Debug. call. Clicking it opens the Debug panel β trace list, node stepper, and animated replay with diagram node highlight.
The extension watches **/reslava-*.json and opens the panel automatically when any trace file appears. A file picker in the panel header lets you switch between reslava-debug-Process.json, reslava-traces.json, and any custom-named save without closing the panel.
Advanced β HTTP endpoint (long-running / remote scenarios):
For apps where file-drop isn't convenient, add REslava.Result.Diagnostics to expose traces over HTTP:
dotnet add package REslava.Result.Diagnostics
For console / worker apps:
using REslava.Result.Diagnostics;
var buffer = new RingBufferObserver();
PipelineObserver.Register(buffer);
using var host = PipelineTraceHost.Start(buffer, port: 5297);
// GET http://localhost:5297/reslava/traces β Debug panel polls here
For ASP.NET Core apps:
app.MapResultFlowTraces(buffer);
// or, if you used PipelineObserver.Register above:
app.MapResultFlowTraces(); // auto-reads from PipelineObserver.Current
The default port (5297) matches the VSIX default. Change it via VS Code Settings β resultflow.tracePort.