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):
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:
// 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:
- Recent traces for a service — the union filtered on
AppRoleNameplus any required tags (matched against the spanPropertiesbag), grouped into traces client-side, newest first. - One full trace — the union filtered on
OperationId == '<trace id>'; parent/child structure comes from each span'sParentId.
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.
