Observability
LogicGrid is built to be observed. Every agent, every admin, every tool call, every retry, every cent spent — they all flow through a single event bus you can subscribe to. The framework ships two ready-made subscribers: a logger for human-readable console output and a trace for after-the-fact analysis.
Three pillars
| Pillar | What it gives you | Lives in |
|---|---|---|
Events — IAgentEventBus | The raw stream. 22 strongly-typed events you can subscribe to. | LogicGrid.Core.Events |
Logging — LogicGridLogger + ILogSink | Console line per event, configurable verbosity, multiple sink targets. | LogicGrid.Core.Logging |
Tracing — AgentRunTrace | A read-after-run object: spans, token usage, cost, retries, tool calls. | LogicGrid.Core.Tracing |
Zero-boilerplate setup
AgentContext exposes two fluent extensions that wire everything for
you. They share an event bus internally — call one, both, or neither.
using LogicGrid.Core.Agents;
using LogicGrid.Core.Logging;
var ctx = new AgentContext()
.WithLogging(new LogicGridLoggerOptions { ShowLlmMessages = false })
.WithTracing(out var trace);
var result = await agent.RunAsync("Capital of France?", ctx);
// Inspect the trace after the run completes
Console.WriteLine($"Tokens : {trace.TotalTokenUsage.TotalTokens}");
Console.WriteLine($"Cost : ${trace.TotalCost.TotalCostUsd:0.0000}");
Console.WriteLine($"Calls : {trace.TotalLlmCalls}");
09:14:02.118 [INF] [a3f2c891] [Helper] started | input: Capital of France?
09:14:03.402 [INF] [a3f2c891] [Helper] completed | output: Paris. | 1284ms | 18 tokens
Tokens : 18
Cost : $0.0000
Calls : 1
WithLogging(options, sinks…) attaches a LogicGridLogger that
writes to ConsoleSink by default. Pass JsonSink(file) (or your
own ILogSink) for structured logging — see
Log sinks.
WithTracing(out var trace) attaches a fresh AgentRunTrace that
adopts the run identity from the first RunStartedEvent it sees.
After RunAsync completes, read fields off trace. See
Tracing.
External correlation
If your platform already has a request ID (an Activity ID, a Sentry
trace ID, a job ID from your queue), pass it as the second argument
to AgentContext and every log line + trace gets stamped with it.
var ctx = new AgentContext(
originalTask: "summarise daily report",
runId: "job-7421")
.WithLogging()
.WithTracing(out var trace);
09:14:02.118 [INF] [job-7421] Run started — admin: Reports | task: summarise daily report
Where to next
- Events — every event the framework publishes, when, and what's on it.
- Log sinks —
ConsoleSink,JsonSink, custom sinks (Serilog, NLog, ELK). - Logger options — every flag on
LogicGridLoggerOptionswith default and effect. - Tracing — the shape of
AgentRunTrace, spans, and how to ship traces to your APM. - Cost & budget —
MaxBudgetUsd,BudgetWarningEvent,BudgetExceededException.