Monitoring non-web apps using Azure Application Insights (Part 2: Basic Instrumentation)
Tags: csharp, azure, devops, monitoring
Published: 2019-08-08 09:54:58

---
title: Monitoring non-web apps using Azure Application Insights (Part 2: Basic Instrumentation) 
published: true
description: 
tags: csharp,azure,devops,monitoring
series: Monitoring non-web apps using Azure Application Insights
cover_image: https://expecho.blob.core.windows.net/blogposts/appinsights-postbanner.png
---
Welcome to the second post of this series covering the monitoring of non-web apps using Azure Application Insights.

In the [previous post](https://dev.to/expecho/monitoring-non-website-applications-using-azure-application-insights-part-1--42oa) 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](https://expecho.blob.core.windows.net/blogposts/LiveMetricsStream-Basic.PNG
)

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](https://docs.microsoft.com/en-us/azure/azure-monitor/app/api-custom-events-metrics). 

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:

```csharp
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:

```csharp
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](https://dev.to/expecho/monitoring-non-website-applications-using-azure-application-insights-part-1--42oa) to call this method:

```csharp
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()`](https://docs.microsoft.com/en-us/azure/azure-monitor/app/api-custom-events-metrics#operation-context)

```csharp
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:

 ```csharp
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](https://expecho.blob.core.windows.net/blogposts/ai-search.png)

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

![Results in portal](https://expecho.blob.core.windows.net/blogposts/ai-search-result.png)

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](https://docs.microsoft.com/en-us/azure/azure-monitor/app/asp-net-dependencies#automatically-tracked-dependencies):

![Dependency Tracking](https://expecho.blob.core.windows.net/blogposts/ai-tracked-dependencies.png
)

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

![Live Metric Stream](https://expecho.blob.core.windows.net/blogposts/live-metrics-anim.gif
)

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 :-)