Monitoring Dynamics 365 Business Central AL Functions Performance with App Insights

Dmitry Katson

Topic: Development

Date: 12 Apr 2020

Recently I was involved in the project to build a Dynamics 365 Business Central App, which gathered all inventory information from Purchase to Sale, including transfers, production orders, etc. in one place, with one goal – to understand the profitability of each line in each purchase order.

Besides the comprehensive business logic, I was limited with the next:

  • every day the company generated about 100K inventory transactions;
  • we didn’t have access to SQL to measure performance (hosted in a private cloud);
  • the calculation window was limited to 2 hours.

After building the app we found that executing on production data takes about 40 hours, and we had to reduce the execution time up to 2 hours at least … and the only tool to measure performance was … intuition 🙂.

So, I’ve got an idea to use Azure App Insights Service to see what’s happening and where we can improve.

Where to start

To be honest, App Insights service was new to me, so I started with this blog: Monitoring your extension in the cloud with Application Insights.

This one helped me to understand the main terminology, and get an overview of Azure App Insights REST API, with the AL framework from https://github.com/microsoft/BCTech/tree/master/samples/AppInsights/App.

However, the way how Microsoft prepared SDK, seemed a bit complicated for me and I found a nice addition to that here:

and the nice Wrapper on the top of Microsoft Azure App Insights AL SDK: https://github.com/mynavblog/ApplicationInsights.

But still, that didn’t give me a simple thing – measure the duration time of the custom AL function, so I decided to make a wrapper on a wrapper :).

Measure duration time of function execution

Let’s create a simple example. Like… how much time would it take to drink a beer… theoretically :).

Step 1. Clone repo

Here you will get all needed for the simplified App Insights AL SDK, together with special functions to measure duration.

Step 2. Add dependency to your Extension

To make the process easier for you, and not to add new objects into your extension, it’s better to add a dependency.

Step 3. Measure function duration time

Assume that we have a function

And each function has some business logic

To measure the execution time of the main DrinkBeer) function we simply add 3 lines of code

StartFunctionExecution() – will start the counter. In the parameter, you can pass any text value. This value you will see in the App Insights Portal later.

InitKey() – you should pass here the key from your AppInsights Portal

TrackExecutionTime() – here you stop the counter and send the execution time to the AppInsights Service.

Start and Track functions should have the same input value. That’s important.

With these three lines of code, you have measured the execution time of the DrinkBeer function and send it to the AppInsights. By default, the duration will be in milliseconds.

Step 4. See results in the Application Insights portal

To run this function, I created a report that calls this codeunit.

And added a loop in the main codeunit.

Publish and run the report.

Let’s have a look at the App Insights Portal.

 

You see that the total duration is 14065 ms.

Possible Adjustments

Our DrinkBeer function consist of 5 different functions: TakeBottle(), OpenBottle(), TakeSip(), ThrowBottle(), Relax();

 It will make sense sometime to measure the duration of each function. To get this, simply follow the same logic as described before.

Run and see the result in the App Insights

Take a look at the results.

The first time we ran the drinkBeer function it took 14k ms. But the second time we run it (last row) it took almost 16k ms.

2 additional seconds took us to send the duration to the app insights from the additional 5 functions. So, be careful with that!

As you can see TakeASip is the most time-consuming part here.

Include additional function metrics to the telemetry

You can go to the TakeASip function and add an additional metric to pass to the AppInsights, like the bottle size 🙂.

Just remember – the metric is something that could be measured in values (decimal or integer).

And run the report once again

You can add as many metrics as you need in any function, where you track duration.

Include additional function property to the telemetry

You can include additional property to the function, like beer name.

Just remember – the property is something that could be described in the text.

And run the report once again

You can add as many properties as you need in any function, where you track duration.

Application Insights Dashboards

As a complementary thing, you can create nice charts

And add them to the dashboard

P.S

With implementing App Insights logging into our real app, we were able to find the most time-consuming functions and make refactoring – decreasing the total execution time from 40h to 2h.

The source code

https://github.com/dkatson/Blog-Monitoring-AL-functions-performance-with-App-Insights

https://github.com/dkatson/ApplicationInsights