I recently received the same request from two customers, so I felt maybe it might be a good topic to discuss here so others can take advantage of it as well. The request was as follows: The customers wanted a way to track active usage of the Views in their system to find out which ones actually got used. They can use this information to deactivate unused Views, and consolidate their list of views for each entity to only the ones needed by their users.
In order to help accomplish this goal, I'm going to use an asynchronous Service Bus plugin registered on the Retrieve message for the SavedQuery entity. This will tell us every time we retrieve a view definition, which should only happen when a user clicks a view from a view picker or through advanced find. There will also be times when the view definition has already been retrieved and is cached locally, so we'll essentially be tracking "cold loads" of Views, or the first time they are retrieved in a browser session per user.
This article will have a very similar alternative that I created for customers who prefer Log Analytics to Application Insights. The alternative uses a Logic App in Azure to grab the message from the Service Bus Queue and push the data to log analytics.
Identify views with the most traffic/requests, so that other unused views can be deleted and highly used ones can be optimized.
private static TelemetryClient telemetry = new TelemetryClient();
public static async Task<HttpResponseMessage> Run(HttpRequestMessage req, TraceWriter log)
dynamic data = await req.Content.ReadAsAsync<object>();
//log as much additional information from CRM as we can for auditing
//we can get CorrelationId, which ties directly back to the plugin
//execution and is also useful for Microsoft support to have
//UserId could also be helpful so you can tie a view retrieve directly
//back to a user in case you want to find out why they use that particular view
//giving a static Operation Name string will allow you to quickly filter
//down results to this type of operation if your Application Insights instance is heavily used
telemetry.Context.Operation.Id = data.CorrelationId.ToString();
telemetry.Context.User.Id = data.UserId.ToString();
telemetry.Context.Operation.Name = "View Accessed";
string target = data.Target.ToString();
KeyValuePair<string,object> entity = JsonConvert.DeserializeObject<KeyValuePair<string,object>>(target);
List<KeyValuePair<string,object>> entList = entity.ToList<KeyValuePair<string,object>>();
Dictionary<string,object> entDict = entList.ToDictionary(k=>k.Key,v=>v.Value);
string newJson = JsonConvert.SerializeObject(entDict);
telemetry.TrackEvent(entDict["returnedtypecode"].ToString() + " - " + entDict["name"].ToString());
return req.CreateResponse(HttpStatusCode.OK, newJson);
| where timestamp >= ago(30d)
| project name
| summarize count() by name
| order by count_ desc nulls last
| where count_ > 2
| render barchart