Skip to content

Application Insights Tracing

CritterWatch can query the Log Analytics workspace behind an Application Insights resource for OpenTelemetry spans when an operator opens a "View Trace" link on a DLQ entry, a saga instance, or a message-id page. Application Insights is one of several supported trace backends — see Settings → Trace Providers for the full list.

What CritterWatch needs from Azure

  • The Log Analytics workspace id (a GUID) backing your Application Insights resource — the same one the metrics integration uses; the two typically share it.
  • An identity with the Log Analytics Reader role on the workspace. Auth is DefaultAzureCredential (managed identity in Azure, developer sign-in locally); no key material is configured or persisted.
  • Your Wolverine services already shipping OTel spans via the Azure Monitor OpenTelemetry distro. CritterWatch does not enroll services into tracing — it only queries spans that are already there.

How to wire it up

In your CritterWatch host startup (typically CritterWatchBff/Program.cs):

cs
services.AddCritterWatchTraceProvider<AppInsightsTraceProvider, AppInsightsTraceProviderOptions>(
    "appinsights",
    opts =>
    {
        opts.WorkspaceId = builder.Configuration["AppInsights:WorkspaceId"]!;
    });

For sovereign clouds, set opts.Endpoint (e.g. https://api.loganalytics.azure.cn).

Per-service routing

By default a registered provider is used for every monitored service. To route a specific service somewhere else (e.g. dev services use Jaeger, prod uses Application Insights), the monitored service can declare its preferred provider in its Wolverine.CritterWatch wire-up:

cs
// In the monitored service's UseWolverine — point it at the named provider the console registered.
opts.AddCritterWatchMonitoring(critterWatchUri, systemControlUri)
    .TraceProvider("appinsights");

That string is the same name you registered in the CritterWatch host. The pushed value becomes the active binding unless the operator overrides it in Settings — see Settings → Service Bindings for the override flow.

What CritterWatch queries

One KQL query per operation, over the two workspace trace tables — AppRequests (server/incoming spans) and AppDependencies (client/outgoing spans) — unioned and joined on OperationId, which carries the W3C trace id end to end:

  1. Recent traces for a service — the union filtered on AppRoleName plus any required tags (matched against the span Properties bag), grouped into traces client-side, newest first.
  2. One full trace — the union filtered on OperationId == '<trace id>'; parent/child structure comes from each span's ParentId.

Cloud role mapping works the same as the metrics side: opts.ServiceLabelMapping["ServiceName"] = "cloud-role-name" when the two differ.

Ingest lag

The same 1–3 minute ingestion delay that applies to metrics applies to spans: a trace for a message handled seconds ago may not be queryable yet. A "View Trace" click that comes up empty right after the fact usually just needs a retry a minute later — the span isn't lost, it's in flight.

When the workspace can't be reached

Query failures degrade the same way as every other provider: recent-trace searches return empty, single-trace fetches return "not found", and the Settings page's reachability indicator goes amber (driven by the provider's health probe — a trivial workspace query). Nothing throws into the operator's face.

Free for read-only monitoring. A commercial license is required for administrative actions and the MCP server.