Working with Application Insights and NLog in Console apps (.NET)

[Application Insights](https://azure.microsoft.com/en-us/services/application-insights/" target="_blank) is a logging platform that allows the collection and, more importantly, the collation of log data from any application. It's primarily optimised and designed to work with web frameworks such as Node.js, ASP.NET (Core too) or PHP etc. You choose the language and AppInsight's got you covered. There are, however cases that you want to do some logging (and you should) from a different type of application, like an Azure WebJob or a Console App.

AppInsights works flawlessly with web frameworks because under the hood it creates an HttpHandler that intercepts request/response data. This means that developers don't need to do anything other than installing the necessary NuGet packages. Server-side monitoring can additionally be enriched with client-side data from web pages using the JavaScript module. It also comes with a great SDK that allows developers to extend the default logging with custom metrics, events etc. One reason why I find AppInsights invaluable (other than the aggregation, analytics, etc) is that it's designed to leverage existing logging frameworks, so instead of forcing developers to rip out old code and replace it with the new AppInsights API, it can be used alongside existing frameworks such as NLog and Log4Net to get even richer telemetry data.

Unlike web apps, where AppInsights work out-of-the box with no need for configuration changes needed, console apps and Azure WebJobs (glorified console apps) need a bit of work to get AppInsights to collect information. Since there's no HttpHandler on site, the following steps are needed in order to get everything working end-to-end:

  1. Install the AppInsights SDK (NuGet)
  2. Configure the telemetry key (Azure Portal)
  3. Add the appropriate custom logger adapters (NuGet)
  4. Add custom logging, if required (Code)

Install the AppInsights SDK through NuGet:

The following need to be installed using either the NuGet Package Manager or the NuGet CLI. The example below uses the CLI:

Install-Package Microsoft.ApplicationInsights
Install-Package Microsoft.ApplicationInsights.WindowsServer
Install-Package Microsoft.ApplicationInsights.Web

Installing these packages will also bring a number of other dependencies so the final packages.config may look slightly inflated. At this point, we need to add a config file to instruct the AppInsights SDK how and where to log things. For web projects, this ApplicationInsights.config file gets automatically installed and added to the solution. Since we're hijacking the process, we need to add this file manually with right-click -> New -> Text File -> ApplicationInsights.config. Then paste the following XML

<?xml version="1.0" encoding="utf-8"?>
<ApplicationInsights xmlns="http://schemas.microsoft.com/ApplicationInsights/2013/Settings">
  <InstrumentationKey></InstrumentationKey>
</ApplicationInsights>

Make sure that you set the file properties to:

  • Build Action: Content
  • Copy to Output: Copy if Newer/Copy Always

NOTE: leaving the InstrumentationKey blank still allows for telemetry to be collected and viewed locally for each debug session. Appending the key from a live AppInsights instance will automatically start logging on the cloud while still retaining the ability to view current and historical data on the local dev environment (Visual Studio)

At this point, AppInsights is ready to collect tracing and custom event information. To do this, the application needs to instantiate a TelemetryClient which can then be used to capture custom logging and tracing information. The gist below contains a working version of AppInsights

Notice that we go beyond the simple logging and we enrich the captured information with custom data using a Dictionary. There are other important things that you need to note:

  • We need to implement a .Flush() method to ensure that the telemetry data is flushed out from memory and into the AppInsights repository
  • We also need to pause for a bit in order to perform a "clean" shutdown and allow the TelemetryClient to commit the data. Flushing without a pause will fail to return any results

Running this code should produce the following results in the AppInsights View

HINT: you can get to the AppInsights Search View by going to View -> Other Windows -> Application Insights Search

Check out the enriched telemetry information in the AppInsights custom trace!

And it doesn't stop there. Once you've integrated AppInsights with your application, CodeLens starts to display inline hints about your application, such as exceptions etc. Check this screenshot out:

Adding NLog into the mix

AppInsights is designed to enrich and supplement existing logging frameworks. Whether you use [NLog](https://nlog-project.org" target="_blank) or [Serilog](https://serilog.net" target="_blank) (or any other logger), you can add the appropriate adapters to allow custom logging to propagate to AppInsights. For this example I will use NLog as an integration example.

Since we don't have NLog installed, we need to download and install the appropriate NuGet package:

Install-Package nLog

Next, we need to instruct AppInsights to "play nice" with NLog. For this to happen, we need to add the appropriate Nlog AppInsights NuGet package. The nice thing with this approach is that it will do the heavy lifting and even configure nLog for us.

Install-Package Microsoft.ApplicationInsights.NLogTarget

This will download and install the necessary and also add the config settings in the web/app.config. If we open the app.config we should see the following minimal configuration for nLog

With this in place, any NLog logs will also be sent to AppInsights. The AppInsights output can be used as the exclusive output or one of many supported by the framework. Let's put this to the test by updating the original code to add some nLog statements

If we run the application now and check the AppInsights view you should have the following output

  1. Custom event logged by AppInsights
  2. Custom dependence event (external calls) logged by AppInsights
  3. All NLog tracing automatically fed into AppInsights

Summary

AppInsights, although not originally designed to work with Console apps, can be added to any non-web project with a couple of NuGet packages and small code alterations. What I like to remind people is not how the logging takes place, but what you do with the data and telemetry once in your possession. AppInsights truly shines with an array of built-in features such as automatic aggregation, data visualisation and advance data analytics and machine learning models to highlight abnormalities in your application. Make sure you take AppInsights for a spin and find out how it can help improve your developer experience and unblock Ops from monitoring your apps more efficiently.