Views:

1. Overview

In this article, we will demonstrate some sample queries to analyze the performance metrics available for North52 formulas via App Insights from Azure.
To run these queries you will need to configure App Insights for your Dynamics 365 instance. 

Some helpful links:


At a basic level, you will need an Azure subscription with App Insights set up on it, then you create the data export in the Power Platform Admin Centre to that App Insights instance.

 

2. Useful Queries

2.1 dependencies table


2.1.1 Pie chart of North52 formula executions by performance bucket in the last 7 days

dependencies 
| where target has "North52.FormulaManager.Plugins" and timestamp >= startofday(ago(7d))
| project performanceBucket, customDimensions.entityName, customDimensions.stage
| summarize count() by performanceBucket
| render piechart 





2.1.2 Average duration of Formulas executions by hour

dependencies
| where ['type'] == "Plugin"
| where name has "North52.FormulaManager.Plugins"
| summarize avg(duration) by bin(timestamp, 1h)
| render timechart  




2.1.3 Average and Longest Execution of the top 20 highest execution times of North52 Formula by entity (last 7 Days)

dependencies
| where duration > 100 and target has "North52.FormulaManager.Plugins" and timestamp >= startofday(ago(7d)) and customDimensions.entityName != "none" and customDimensions.entityName !has "north52"
| top 20 by duration
| summarize MaxExecutionTime=max(duration),
    AvgExecutionTime=avg(duration)
    by EntityName = tostring(customDimensions.entityName) 




2.1.4 Percentage breakdown of North52 formula execution times
 

dependencies 
| where target has "North52.FormulaManager.Plugins"
| summarize 
    avg_duration = avg(duration),
    percentiles(duration, 10, 50, 95)


In the below result you can see that the average formula execution time was 0.75 seconds, and 50% of formula executions were completed within 58 ms




2.1.5 Percentage breakdown of North52 formula execution times by hour

dependencies
| where target has "North52.FormulaManager.Plugins"
| summarize
    avg_duration = avg(duration),
    percentiles(duration, 10, 50, 95),
    count() by bin(timestamp, 1h)


2.2 Exceptions Table

2.2.1 Show North52 exceptions and their error messages

exceptions
| where outerMessage has "North52" or customDimensions.exceptionSource has "North52"
| project timestamp, outerMessage, Entity = customDimensions.entityName, customDimensions

 
2.2.2 Show North52 exceptions by hour in a time chart

exceptions 
| where outerMessage contains "North52"
| project timestamp, outerMessage, customDimensions
| summarize count() by bin(timestamp, 1h)
| render timechart 


This query is just renders the above data table as a chart that you can use to visualise the exceptions being raised




Note: You can change the range in the bin() from 1h to 24h to see the exceptions being raised daily, instead of hourly.



2.2.3 Display entities where North52 exceptions are being raised, and the count of them

exceptions
| where outerMessage has "North52" or customDimensions.exceptionSource has "North52"
| project timestamp, outerMessage, Entity = customDimensions.entityName, customDimensions
| summarize ExceptionsCount = count() by tostring(customDimensions.entityName)
| render barchart 


3. Requests Table

3.1.1 Query of requests table showing request duration percentiles and count by name

// this query calculates request duration percentiles and count by name
let start=datetime("2023-12-05T12:03:00.000Z");
let end=datetime("2023-12-07T12:03:00.000Z");
let timeGrain=5m;

let dataset=requests
    // additional filters can be applied here
    | where timestamp > start and timestamp < end
    | where client_Type != "Browser"
;

// calculate duration percentiles and count for all requests (overall)
dataset
| summarize
    avg_duration=sum(itemCount * duration) / sum(itemCount),
    percentiles(duration, 50, 95, 99),
    count_=sum(itemCount)
| project
    operation_Name="Overall",
    avg_duration,
    percentile_duration_50,
    percentile_duration_95,
    percentile_duration_99,
    count_
| union(dataset
    // change 'operation_Name' on the below line to segment by a different property
    | summarize
        avg_duration=sum(itemCount * duration) / sum(itemCount),
        percentiles(duration, 50, 95, 99),
        count_=sum(itemCount)
        by operation_Name
    | sort by avg_duration desc, count_ desc
    )