Logs and Debugging
This page documents the structured-logging contract Fleans emits via [LoggerMessage] source generators. For health checks, metrics, and tracing, see Observability.
Logging contract
Section titled “Logging contract”Fleans uses [LoggerMessage] source-generated logging exclusively — no ILogger.LogInformation(...) extension-method calls. Every state mutation in WorkflowInstance and ActivityInstance emits a structured log entry via a private partial void declared on a partial class. This means:
WorkflowInstanceId. Open interactive diagram ↗- EventIds are stable — filter by EventId, not by message text.
- Field names are typed and consistent — log queries on
WorkflowInstanceIdalways hit the same field. - No format-string drift — the source generator validates the format string against the parameters at compile time.
If you author a custom-task plugin, follow the same pattern (see the adding a BPMN activity convention for the boilerplate).
EventId ranges
Section titled “EventId ranges”| Range | Component |
|---|---|
| 1000–1199 | WorkflowInstance |
| 1070–1079 | WorkflowInstance — pending events and event sub-processes |
| 1080–1089 | WorkflowInstance — complex gateway |
| 1090–1099 | WorkflowInstance — escalation |
| 1100–1109 | WorkflowInstance — transaction sub-process |
| 1110–1119 | WorkflowInstance — compensation |
| 1120 | WorkflowInstance — workflow failed: an unhandled activity failure left no active activities (Error) |
| 1131–1136 | WorkflowInstance — event store: 1131 snapshot write failed (Error; if it keeps failing the instance eventually cannot activate); 1132 read-model write failed, retrying (Warning); 1133 read model behind the event log on activation, rebuilding (Information); 1134 read model caught up after a failed write (Information); 1135 read-model retries gave up, rebuilt on the next activation (Error); 1136 reading the read-model version failed (Warning) |
| 1140 | WorkflowInstance — variables over Fleans:Variables:MaxSizeBytes rejected (Warning) |
| 1066 | UserTaskClaim rejection (Warning) |
| 2000–2099 | ActivityInstance |
| 3000–3099 | WorkflowInstanceState |
| 3030–3032 | WorkflowInstance — escalation warnings |
| 4000–4099 | Event handlers |
| 5000–5099 | WorkflowEventsPublisher |
| 9000–9099 | BpmnConverter |
| 10000–10099 | TimerCallbackGrain |
| 11200 | Fleans.Streaming.Kafka.AwsMsk — MSK IAM token refresh failed (Error); check IAM policy for kafka-cluster:Connect / WriteData / ReadData |
| 11201 | Fleans.Streaming.Kafka.AwsMsk — OAuthBearerSetTokenFailure threw after token-refresh failure (Warning); typically a shutdown race, not actionable |
For the full per-EventId deep dive and reserved bands, see docs/plans/2026-02-08-structured-workflow-logging.md.
Log-scope fields
Section titled “Log-scope fields”Every grain call is wrapped in a BeginScope by WorkflowLoggingScopeFilter (an Orleans IIncomingGrainCallFilter). The scope carries these structured fields, propagated automatically across grain boundaries via RequestContext:
| Field | Type | Set by |
|---|---|---|
WorkflowId | string | WorkflowInstance |
ProcessDefinitionId | string | WorkflowInstance |
WorkflowInstanceId | string | WorkflowInstance |
BusinessId | string | WorkflowInstance, stream handlers (script, condition, custom task) — the instance’s business id, - when none was set; not inherited by call-activity children. Lines logged outside a call from the instance (e.g. timer reminders) lack it — filter on WorkflowInstanceId for the full picture |
ActivityId | string | WorkflowInstance / ActivityInstance |
ActivityInstanceId | string | WorkflowInstance / ActivityInstance |
VariablesId | string | ActivityInstance |
In a structured-log backend (Seq, Loki, Datadog), query against these field names directly — they are emitted as JSON properties, not embedded in the message text.
Filtering by log level
Section titled “Filtering by log level”In appsettings.json, you can set per-category log levels using the standard Microsoft.Extensions.Logging configuration. For example, to suppress verbose workflow logging while keeping escalation warnings visible:
{ "Logging": { "LogLevel": { "Default": "Information", "Fleans.Application.Grains.WorkflowInstance": "Warning", "Microsoft.Orleans": "Warning" } }}This uses the standard LogLevel configuration — no additional packages or custom filter providers are needed.
Related
Section titled “Related”- Observability — health checks, metrics, OTel collector wiring.
- Orleans Dashboard — real-time cluster view.
docs/plans/2026-02-08-structured-workflow-logging.md— contributor-side logging architecture.