[object Object]

Plugin Trace Log is the diagnostic tool every Dynamics 365 plugin developer relies on, and the one that fills storage budgets fastest if left alone. The right configuration gives you signal during incidents and silence the rest of the time.

Three tracing modes

In the Power Platform admin center, environment settings expose three tracing modes:

  1. Off: no traces stored
  2. Exception: traces persisted only when a plugin throws
  3. All: traces persisted for every execution

Default to Exception for production. Switch to All only during a specific incident, then back. “All” on a busy environment can write 10 GB per day to Dataverse and trigger storage warnings within a week.

What to actually trace

Inside your plugin, write traces that future-you can act on. Bad: tracingService.Trace("here"). Good:

tracingService.Trace("Step={0} EntityId={1} CorrelationId={2}", 
    context.MessageName, context.PrimaryEntityId, context.CorrelationId);

Always include:

  • Correlation ID (lets you stitch traces across plugin steps and async jobs)
  • Primary entity ID
  • Inputs that drove a branch decision
  • External call timings (stopwatch.ElapsedMilliseconds)

Skip traces for normal happy-path branches. Trace only at decision points, error paths, and external boundaries.

Query traces efficiently

Plugin Trace Log is a Dataverse table (plugintracelog). Query it like any other:

GET /api/data/v9.2/plugintracelogs?$filter=correlationid eq {guid}&$orderby=createdon asc

Build a small browser tool or Power BI report that takes a correlation ID and returns the full trace timeline. Engineers stop opening individual rows in Advanced Find.

For incident response, filter by messagename, primaryentity, and createdon window. Add a saved system view named “Recent Plugin Failures” filtered to last 24 hours, exception rows only.

Ship to App Insights

For real observability, do not rely on Plugin Trace Log alone. Send the same trace data to Azure Application Insights via a thin wrapper:

public class TelemetryTracingService : ITracingService
{
    public void Trace(string format, params object[] args)
    {
        var msg = string.Format(format, args);
        _innerTracing.Trace(msg);
        _telemetryClient.TrackTrace(msg, SeverityLevel.Information);
    }
}

App Insights gives you Kusto queries, alerts, and 30-day retention without burning Dataverse storage. Plugin Trace Log becomes a fallback, not your primary tool.

Storage hygiene

Plugin Trace Log rows are subject to the 30-day automatic deletion job, but a busy environment in “All” mode can still hold tens of GB at any moment. Set up a bulk delete job that runs nightly and deletes rows older than 7 days. This is more aggressive than the default 30 days and keeps storage predictable.

Disable in production code paths you trust

For high-volume plugins (executing 100+ times per second), wrap the trace calls in a config check so production traces are minimal even in Exception mode:

if (_config.VerboseTracing) tracingService.Trace(...);

Toggle the config via an environment variable when you need detail.

Correlate with Application Insights

Pass the correlation ID from the plugin context as the operation_Id in App Insights. Now plugin failures, downstream HTTP calls, and Power Automate runs all stitch into one timeline. This is the difference between “something broke” and “we know exactly what broke and where.”

What to do this week: enable Exception-mode tracing in production, write a correlation-ID-driven query view, and ship one plugin’s traces to App Insights as a pilot.

[object Object]
Share