A canary in CRM

canaryHave you ever faced a situation when you don’t know why your Microsoft Dynamics 365 Customer Engagement system behaves the way it does, or why your own plugins behave the way they do?

If you have, this might be a good time to put a canary in your system.

- A what?
- A canary.

You know when we were manually laboring down the coal mines, it happened that drilling into the rock inadvertently let out poisonous gas. So we brought in cages with canary birds putting their life at stake, to save our coal miners’ lives. The canaries were signaling the content of the atmosphere long before the coal miners would detect something dangerous. They did this by suddenly being upside down, instead of happily chattering.

As a plugin developer of many years, I have added extra tracing to my plugins more times than I can count and sometimes even added steps for more messages than necessary, and I am sure most of you reading this post have too, in one way or another.

Plugin cluttering, no more

So I finally decided to create this one, small, lightweight plugin to log everything worth knowing from the plugin context. And then pack it into a solution, with a bunch of steps for the most common messages.

Instead of wondering what just happened, instead of cluttering my plugins with tracing code that I might remember to remove before production, I can now simply bring my canary – inject that contrast fluid – call my Snowden of CRM – to be able to dig into the hidden secrets of the messages going through the pipeline of the Microsoft Dynamics 365 system.

So what is this?

This is no rocket science. This is neither clever nor ingenious. This is simply a plugin that dumps the IPluginExecutionContext in an appetizing format. And this plugin packed together with a set of steps in a Microsoft Dynamics 365 solution.

When all you want it just that, a simple way to make the complexity of the platform understandable.

Hands on

So if you don’t want to clutter your own plugin projects, you should install this canary solution.

The solution and the source code for it is available on GitHub: http://github.com/rappen/RappCanary365

The solution is currently available for MSDyn365 8.2 and 8.1. But as mentioned, the code is there, you just have to compile it, register it in your environment and add the steps, if you want it in earlier versions. The 9.0 version is also working just fine, and will be available after GA is announced from Microsoft.

The solutions contain pre validation steps for all entities for messages: Create, Update, Delete, Assign, Associate, Disassociate, Execute, GrantAccess, RevokeAccess, Merge, Lose, QualifyLead, PickFromQueue, Route, SetState, SetStateDynamicEntity and Retrieve. I also added a post operation step for the Update message.

Steps can easily be added to expand the tracing, disabled to have the canary less chattering, or be made more detailed to pinpoint more specific events in the system.

If an unsecured configuration with value ParentContext=True is added to a plugin step, the plugins will loop back up the ladder of parent contexts to dump those too to the trace.


The results of the canary are best investigated using the Plugin Trace Viewer for XrmToolBox. Below are a couple of examples of the log it produces.


Above is a list of trace log records displayed in Plugin Trace Viewer.


First the basic execution information is displayed, such as Message, Stage etc.

Then all InputParameters are displayed. These are dynamically parsed and presented, so you don’t have to “know” what you are looking for in the context, if there is anything in there, it will be displayed in the trace log.

The same thing is done for OutpuParameters, SharedVariables, PreEntityImages and PostEntityImages.

Below is an example of the post operation update stage of the same pipeline as the example above.


What you can’t do

Unfortunately, there is no way to define steps for “all” messages. Well, from a performance perspective, this is of course a good thing. But it would be nice to be able to track everything that happens when you qualify a lead, when you add an email to a queue, or when you disable a user. You simply have to create all the steps for all the messages that you suspect are involved, and see which ones that fire.

This solution does not tell you anything about which other plugins that have fired. There is just no way to detect that from another plugin. But you can get hints, signals in that contrast fluid, if you add the parent context setting, where you can see that a create of entity B happened in a child context for an update of entity A.

Platform constraints

It is still not possible to trace the exact order of requests being fired, as we still don’t have more granularity to the time when a plugin fires than down to a full second. That is one thousand milliseconds. Given the CPU power we have today, it is just incomprehensible why we should not get more detail in the timing of plugin execution.

It is like defining my age by saying I was born sometime during the second half of the 20th century.

If this bothers you in any way, please help correct that by voting up this CRM Idea and reaching out to your nearest Microsoft representative!


The solution files can be downloaded here: https://github.com/rappen/RappCanary365/releases

Labels: , ,