Plugin Trace Log implementation#341
Merged
Merged
Conversation
…ted trace log Trace messages with format args are now evaluated through String.Format so invalid format strings surface during testing instead of being silently swallowed. Arg-less messages remain verbatim, matching platform behavior. Trace messages are also collected by the default tracing service factory and exposed via XrmMockupBase.TraceLog (with ClearTraceLog) so tests can assert on emitted trace output. Co-Authored-By: Claude <noreply@anthropic.com> via Conducktor <conducktor@contextand.com>
Trace messages are now grouped by the plugin execution that produced them, mirroring the plugintracelog records of a real Dynamics 365 environment. Each XrmMockupBase.PluginTraceLog entry captures the invoking type, message name, primary entity, operation type, depth, correlation id, mode, request id, execution start time, duration, the ordered list of trace messages and any exception details. PluginTrigger now times each sync/async plugin execution, captures thrown exceptions and records an entry with the execution's own trace messages. Internal XrmMockup system plugins are excluded. Configuration/secure configuration and plugin step ids are not modeled by XrmMockup and remain null. Co-Authored-By: Claude <noreply@anthropic.com> via Conducktor <conducktor@contextand.com>
The per-execution trace grouping introduced for plugins now also covers custom API executions and workflow activity executions (sync and async). A shared PluginTraceRecorder helper centralizes the timing, exception capture and trace message collection used by all three paths; CustomApiManager and WorkflowManager now route their executions through it. Custom API entries record the request name as the message and Plugin operation type; workflow entries record the workflow name as the type, WorkflowActivity operation type and the workflow's sync/async mode. Directly-invoked workflows (ExecuteWorkflowRequest, which has no plugin context) are executed but not logged. Co-Authored-By: Claude <noreply@anthropic.com> via Conducktor <conducktor@contextand.com>
Contributor
There was a problem hiding this comment.
Pull request overview
Adds first-class trace capture to XrmMockup365 so tests can assert on emitted ITracingService output, and introduces a Dynamics-like per-execution “plugin trace log” (including custom APIs and workflow activities) with timing and exception details.
Changes:
- Evaluate
ITracingService.Trace(format, args)viastring.Format(when args provided) and expose a collected flatTraceLogonXrmMockupBase. - Record grouped per-execution trace entries (
PluginTraceLog) for plugins/custom APIs/workflow activities via a sharedPluginTraceRecorder. - Extend tests and test assemblies to validate formatting behavior, flat trace collection, grouped trace metadata, and exception capture.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/XrmMockup365Test/TestTracingService.cs | Adds coverage for format-evaluation behavior, flat trace collection, and grouped per-execution trace logging (plugins/custom APIs/workflows). |
| tests/TestPluginAssembly365/Plugins/AccountTraceThrowPlugin.cs | Test plugin that traces then throws to validate exception capture in grouped trace logs. |
| tests/TestPluginAssembly365/Plugins/AccountTracePlugin.cs | Test plugin that emits trace messages to validate trace collection and ordering. |
| tests/TestPluginAssembly365/CustomApis/TraceApi.cs | Custom API emitting traces to validate grouped trace logging for custom API execution. |
| tests/TestPluginAssembly365/CodeActivities/AccountWorkflowActivity.cs | Adds a trace message to validate grouped trace logging for workflow activity execution. |
| src/XrmMockup365/XrmMockupBase.cs | Exposes TraceLog/ClearTraceLog and grouped PluginTraceLog/ClearPluginTraceLog; clears trace log on reset. |
| src/XrmMockup365/Workflow/WorkflowManager.cs | Routes workflow executions through PluginTraceRecorder and threads workflow name for logging metadata. |
| src/XrmMockup365/TracingServiceFactory.cs | Default tracing factory now records emitted messages and exposes them via TraceLog/Clear. |
| src/XrmMockup365/TracingService.cs | Implements platform-like formatting semantics, collects per-instance messages, and supports an optional sink for factory-level collection. |
| src/XrmMockup365/PluginTraceLog.cs | Introduces grouped trace-log model and operation type enum. |
| src/XrmMockup365/Plugin/PluginTrigger.cs | Wraps plugin execution with timing/exception capture and grouped trace recording; adds option to skip recording. |
| src/XrmMockup365/Plugin/PluginTraceRecorder.cs | Central helper to time execution, collect per-execution trace messages, and record grouped trace entries. |
| src/XrmMockup365/Plugin/PluginManager.cs | Excludes internal/system plugins from grouped trace logging. |
| src/XrmMockup365/Plugin/CustomApiManager.cs | Routes custom API execution through PluginTraceRecorder to produce grouped trace entries. |
| src/XrmMockup365/Internal/ICoreOperations.cs | Adds core API surface for recording grouped trace entries. |
| src/XrmMockup365/Core.cs | Stores grouped trace entries with thread-safety and clears them on environment reset. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- PluginTraceRecorder: fall back to the TargetInvocationException itself when it has no inner exception, so ExceptionDispatchInfo.Capture is never handed null (which would mask the original failure). - TracingService: expose Messages as a read-only wrapper so callers cannot cast it back to List<string> and mutate recorded trace output. - XrmMockupBase: return Array.Empty<string>() rather than allocating a new list on every TraceLog access when a custom tracing factory is configured. Co-Authored-By: Claude <noreply@anthropic.com> via Conducktor <conducktor@contextand.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Evaluate ITracingService messages via String.Format and expose collected trace log
Trace messages with format args are now evaluated through String.Format so
invalid format strings surface during testing instead of being silently
swallowed. Arg-less messages remain verbatim, matching platform behavior.
Trace messages are also collected by the default tracing service factory and
exposed via XrmMockupBase.TraceLog (with ClearTraceLog) so tests can assert on
emitted trace output.
Group trace messages per plugin execution via PluginTraceLog
Trace messages are now grouped by the plugin execution that produced them,
mirroring the plugintracelog records of a real Dynamics 365 environment. Each
XrmMockupBase.PluginTraceLog entry captures the invoking type, message name,
primary entity, operation type, depth, correlation id, mode, request id,
execution start time, duration, the ordered list of trace messages and any
exception details.
PluginTrigger now times each sync/async plugin execution, captures thrown
exceptions and records an entry with the execution's own trace messages.
Internal XrmMockup system plugins are excluded. Configuration/secure
configuration and plugin step ids are not modeled by XrmMockup and remain null.
Extend grouped trace log to custom APIs and workflow activities
The per-execution trace grouping introduced for plugins now also covers custom
API executions and workflow activity executions (sync and async). A shared
PluginTraceRecorder helper centralizes the timing, exception capture and trace
message collection used by all three paths; CustomApiManager and WorkflowManager
now route their executions through it.
Custom API entries record the request name as the message and Plugin operation
type; workflow entries record the workflow name as the type, WorkflowActivity
operation type and the workflow's sync/async mode. Directly-invoked workflows
(ExecuteWorkflowRequest, which has no plugin context) are executed but not logged.
Co-Authored-By: Claude noreply@anthropic.com via Conducktor conducktor@contextand.com