Tracing and logging in Dataverse
How to instrument Dataverse plug-ins and flows with tracing and logging — the trace service, Application Insights integration, and what to log without leaking sensitive data.
Server-side code in Dataverse — plug-ins, custom workflows, low-code plug-ins — runs in a sandboxed environment with limited debugger access in production. The compensation is tracing and logging: instrument your code so issues are diagnosable post-hoc without reproducing them in dev. Mature teams treat instrumentation as a first-class engineering concern.
The trace service. Plug-ins receive an ITracingService from the execution context:
var tracingService = serviceProvider.GetService<ITracingService>();
tracingService.Trace("Plug-in started for entity {0}", entity.LogicalName);
Each Trace call writes a line; traces accumulate per plug-in execution.
Where traces go.
- Plug-in trace log table in Dataverse — visible in admin UI.
- Available for a configurable retention period — typically days to weeks.
- Per-execution — one trace log record per plug-in invocation.
For most diagnostic needs, this is sufficient.
Application Insights integration. For deeper observability:
- Configure App Insights for the Dataverse environment.
- Traces flow to App Insights additionally.
- Rich query, alerting, dashboarding.
App Insights is the modern, recommended approach for production Dataverse.
What to trace.
- Method entry/exit — for execution flow.
- Key decision points — branches, conditions taken.
- External API calls — request and response (minus sensitive).
- Performance markers — operation timing.
- Errors and exceptions — full context.
A balanced level — neither too sparse (can't diagnose) nor too verbose (can't see signal in noise).
What NOT to trace.
- Passwords, API keys, tokens.
- PII — full names, emails, identifiers (without business need).
- Credit card data — PCI violation.
- Health data — HIPAA violation.
Use redaction patterns: trace customer ID redacted, not customer ID 12345.
Structured tracing. Better than free-text:
tracingService.Trace("OperationName: {0}, RecordId: {1}, Duration: {2}ms",
operation, recordId, duration);
Structured patterns enable easier parsing and querying downstream.
Tracing in low-code plug-ins. Power Fx in low-code plug-ins:
Trace()function adds traces.- Log to standard plug-in trace.
- Same access patterns.
Tracing in flows.
- Each action's input/output captured automatically.
- Loop iterations tracked.
- Failures detailed.
Flow run history is the trace; no explicit Trace calls typically needed for basic flows. For complex flows, use Compose actions to log specific values.
Performance impact.
- Tracing has overhead — string formatting, write to memory.
- For high-volume code paths, minimise traces.
- Don't trace in tight loops; aggregate and trace once.
A plug-in tracing 100 lines per record × 10K records = 1M trace lines = slow.
Trace levels. Not built into Dataverse directly, but pattern:
- Error — failure.
- Warning — concerning but recoverable.
- Info — major checkpoints.
- Debug — verbose flow.
Configurable levels — Production at Warning+, Sandbox at Debug.
Application Insights query. With App Insights, you query traces in Kusto Query Language (KQL):
traces
| where customDimensions.PluginName == "MyPlugin"
| where timestamp > ago(1h)
| order by timestamp desc
Rich querying replaces digging through individual plug-in trace records.
Correlation IDs. Trace correlation across systems:
- A request entering Dataverse gets a correlation ID.
- Trace lines include it.
- External calls pass the ID.
- Receiver logs include it.
End-to-end traceability across system boundaries.
Audit vs trace. Different:
- Audit — business-relevant change records (who changed what when); for compliance.
- Trace — technical execution information; for diagnostics.
Both valuable; don't conflate.
Sensitive data handling.
- Redact before tracing —
SSN: ***-**-1234. - Hash identifiers — for correlation without exposure.
- Avoid full row dumps — trace specific fields.
Common pitfalls.
- No tracing. First production issue; nothing to look at.
- Verbose tracing. Performance hit; noise in logs.
- Sensitive data leaked. Compliance issue.
- Trace formatting expensive. Even if log not written, string formatting cost.
- Trace ignored. Logs exist but nobody looks; instrumentation wasted.
Operational rhythm.
- Daily — review error traces.
- Per incident — deep dive on relevant traces.
- Weekly — trace pattern analysis (top errors, slow operations).
- Monthly — review what's traced; adjust verbosity.
Strategic positioning. Tracing is the cheap insurance policy of server-side code. Investment in good instrumentation pays back the first time something goes wrong in production. App Insights elevates Dataverse to enterprise-grade observability. For any production deployment of meaningful scale, instrumenting plug-ins and flows is non-negotiable engineering practice. Tracing isn't optional; it's foundational. The teams that take it seriously have boring incident reviews; the teams that don't have long, painful ones.
Related guides
- Async jobs in DataverseHow Dataverse runs background work — system jobs, async plug-ins, workflow runs, and how to monitor, troubleshoot, and prevent the async backlog from getting out of hand.
- Bulk delete jobs in DataverseHow Dataverse's bulk delete handles mass record cleanup — scheduling, filters, retention policies, and the operational discipline around storage management.
- Business rules in DataverseHow business rules let you add field-level logic to forms without code — set value, lock field, show error, recommendation, and the limits of the engine.
- Business units and teams in Dataverse — a deep diveHow business units, owner teams, access teams, and Microsoft 365 group teams compose the security model in Dataverse — what each is for, how they interact, and the common design mistakes.
- Calculated and rollup columns in DataverseHow calculated columns and rollup columns work in Dataverse — what each does, the performance trade-offs, and when to use a formula column or a Power Automate flow instead.