loading...
Cover image for Monitoring non-web apps using Azure Application Insights (Part 2: Basic Instrumentation)

Monitoring non-web apps using Azure Application Insights (Part 2: Basic Instrumentation)

expecho profile image Peter Bons ・5 min read

Welcome to the second post of this series covering the monitoring of non-web apps using Azure Application Insights.

In the previous post we created an Application Insights resource using the Azure Portal and we integrated Application Insights into a simple console application. As a result we got live monitoring of our application as shown below.

Live Metric Stream

Now it is time to add instrumentation to our code. The Application Insights SDK allows these entities to be tracked:

  • Page Views

  • Exceptions

  • Requests

  • Traces

  • Dependencies

  • Metrics

  • Events

When you add Application Insights to a web application the whole tracking of page views, request, dependencies etc. is done automatically. Unfortunately, when building a Console, WPF or WinForms application we need to manually create telemetry items and send them using the SDK.

To send telemetry to Application Insights we need a TelemetryClient. There are several ways to create a telemetry item but there is one important thing to keep in mind. The real power of Application Insights is the ability to relate telemetry items. You do want to know what requests belong to what page view, what request triggered a dependency call and what was happening when an exception was thrown. We will come back to this later, let us first send some telemetry. We will extend the console application we created in the previous post.

Say we add a method like this to the Program class of the console application:

private static async Task MakeHttpRequestAsync()
{
    try
    {
        using (var httpClient = new HttpClient())
        {
            var result = await httpClient.GetStringAsync("http://www.blank.org");
            Console.WriteLine(result);
        }
    }
    catch (HttpRequestException ex)
    {
        Console.WriteLine("Error getting text.");
    }
}

Given the code above I would like Application Insights to track that the method is called and how long it takes to execute. I would also be very happy to be able to see the HttpRequestException being logged in Application Insights. Finally, I would be thrilled to know how long the call to the external dependency call to http://www.blank.org took. Also, if an exception other than an HttpRequestException occurs, I would like to mark the method call as being failed.

So, lets extend the method and use a TelemetryClient to track the various telemetry items:

private static async Task MakeHttpRequestAsync(T)
{
    var telemetryClient = new TelemetryClient(TelemetryConfiguration.Active);
    using (var operation = 
                 telemetryClient.StartOperation<RequestTelemetry>(nameof(MakeHttpRequestAsync)))
    {
        try
        {
            using (var httpClient = new HttpClient())
            {
                var result = await httpClient.GetStringAsync("http://www.blank.org");
                telemetryClient.TrackTrace($"The http call returned '{result}'");
                Console.WriteLine(result);
            }
        }
        catch (HttpRequestException ex)
        {
            telemetryClient.TrackException(ex);
            Console.WriteLine("Error getting text.");
        }
        catch
        {
            operation.Telemetry.Success = false;
            throw;
        }
    }
}

We then modify the code of the Main method in the Program class created in the previous post to call this method:

static async Task Main(string[] args)
{
    ConsoleKeyInfo keyInfo = new ConsoleKeyInfo();

    while (keyInfo.Key != ConsoleKey.Q)
    {
         await MakeHttpRequest();
         keyInfo = Console.ReadKey();
    }

    Console.WriteLine("Press any key to run again or Q to exit.");
    Console.ReadKey();
}

Let's walk through the code. We first create an instance of TelemetryClient and we initialize it with a TelemetryConfiguration.Active. This will apply the configuration as defined in the file ApplicationInsights.config.

Next, we start an operation to track the method call as a Request telemetry item in Application Insights using TelemetryClient.StartOperation()

using (var operation = 
             telemetryClient.StartOperation<RequestTelemetry>(nameof(MakeHttpRequestAsync)))

When the operation gets disposed at the end of the using block the total duration from start to end is calculated and the Request item is send to Application Insights.

Next, in addition to tracking entities like Exceptions or Requests you can also log some arbitrary text in Application Insights using a Trace telemetry item. This is done using the line telemetryClient.TrackTrace($"The http call returned '{result}'");

In case of an exception we are able to handle we can log the exception in Application Insights. This is done by calling telemetryClient.TrackException(ex);.

Finally, when an exception occurs that we cannot handle we can mark the call to the method as being failed by setting the value of the Success property of the RequestTelemetry to false. To get to the RequestTelemetry of the Operation initiated by calling TelemetryClient.StartOperation() we can use the Telemetry property:

operation.Telemetry.Success = false;

Then we re-throw the exception so the caller can deal with it.

Before launching the application, open a tab in your browser and navigate to the Live Metrics Stream in Application Insights.

Now, if we were to run the application we would see the telemetry appear in Application Insights. Note that it can take a few seconds before the Live Metrics Stream is initialized and a few more moments for telemetry items to appear in the portal:

Results in portal

If we click on the request we get a more detailed view.

Results in portal

As you can notice the telemetry items are grouped together. The portal will show you that the outgoing Http call originated from the request. That is the benefit of using `TelemetryClient.StartOperation() as opposed to doing something like telemetryClient.TrackRequest(...);. Once an operation is started all telemetry items that are sent in the scope of the operation are linked together.

Furthermore we you can see that the outgoing Http call is detected by Application Insights and automatically logged. This is done by the DependencyTrackingTelemetryModule. Application Insights can track more than http calls as seen in the docs:

Dependency Tracking

The cool thing is, the telemetry created by the application is also captured by the Live Metrics Stream!

Live Metric Stream

The bad thing however, is the amount of code involved in instrumenting an application like this. Imagine having to write this code for each and every method you want to instrument. In the next blog post I will show you a way to make life a bit easier when it comes to this so stay tuned. I promise it won't take as long as it took for me to write this second part :-)

Discussion

pic
Editor guide
Collapse
boosterch profile image
boosterch

Nice blog. Waiting for the next part :)
Do you know if it's possible to adjust the UI interface of Application Insights.
It seems very tuned to web applications?

Collapse
callindrill profile image
Jon Bruckman

Is Part 3 Coming soon? :(