Monsters Weekly 153 - Releasing NuGet Packages with GitHub Actions

In this continuation of Episode #152 (https://youtu.be/GBKBCr6SjPs), Dave uses the GitHub Actions release trigger to generate a release version of a NuGet package that links back to the release notes on GitHub.

Monsters Weekly 152 - GitHub Actions and .NET Core

GitHub Actions makes it really easy to setup a continuous integration build for your .NET Core projects. In this episode, Dave shows us how to configure a workflow to build and test your .NET Core projects using a GitHub Actions workflow that is triggered on commits to master or on pull requests to master.

Monsters Weekly 151 - Visual Studio Code, .NET and Linux

Building .NET Core applications on Linux is much more enjoyable when using Visual Studio Code.
In this episode, Dave takes us through the basics of building and debugging .NET Core applications on Linux using Visual Studio Code

Setting Cloud Role Name in Application Insights

Originally posted to: http://www.davepaquette.com/archive/2020/02/05/setting-cloud-role-name-in-application-insights.aspx

This post is a continuation of my series about using Application Insights in ASP.NET Core. Today we will explore the concept of Cloud Role and why it’s an important thing to get right for your application.

In any application that involves more than a single server process/service, the concept of Cloud Role becomes really important in Application Insights. A Cloud Role roughly represents a process that runs somewhere on a server or possibly on a number of servers. A cloud role made up of 2 things: a cloud role name and a cloud role instance.

Cloud Role Name

The cloud role name is a logical name for a particular process. For example, I might have a cloud role name of “Front End” for my front end web server and a name of “Weather Service” for a service that is responsible for providing weather data.

When a cloud role name is set, it will appear as a node in the Application Map. Here is an example showing a Front End role and a Weather Service role.

Application Map when Cloud Role Name is set

However, when Cloud Role Name is not set, we end up with a misleading visual representation of how our services communicate.
Application Map when Cloud Role Name is not set

By default, the application insights SDK attempts to set the cloud role name for you. For example, when you’re running in Azure App Service, the name of the web app is used. However, when you are running in an on-premise VM, the cloud role name is often blank.

Cloud Role Instance

The cloud role instance tells us which specific server the cloud role is running on. This is important when scaling out your application. For example, if my Front End web server was running 2 instances behind a load balancer, I might have a cloud role instance of “frontend_prod_1” and another instance of “frontend_prod_2”.

The application insights SDK sets the cloud role instance to the name of the server hosting the service. For example, the name of the VM or the name of the underlying compute instance hosting the app in App Service. In my experience, the SDK does a good job here and I don’t usually need to override the cloud role instance.

Setting Cloud Role Name using a Telemetry Initializer

Telemetery Initializers are a powerful mechanism for customizing the telemetry that is collected by the Application Insights SDK. By creating and registering a telemetry initializer, you can overwrite or extend the properties of any piece of telemetry collected by Application Insights.

To set the Cloud Role Name, create a class that implements ITelemetryInitializer and in the Initialize method set the telemetry.Context.Cloud.RoleName to the cloud role name for the current application.

public class CloudRoleNameTelemetryInitializer : ITelemetryInitializer
{
public void Initialize(ITelemetry telemetry)
{
// set custom role name here
telemetry.Context.Cloud.RoleName = "Custom RoleName";
}
}

Next, in the Startup.ConfigureServices method, register that telemetry initializer as a singleton.

services.AddSingleton<ITelemetryInitializer, CloudRoleNameTelemetryInitializer>();

For those who learn by watching, I have recorded a video talking about using telemetry initializers to customize application insights.

Using a Nuget Package

Creating a custom telemetry initializer to set the cloud role name is a simple enough, but it’s something I’ve done so many times that I decided to publish a Nuget package to simplify it even further.

First, add the AspNetMonsters.ApplicationInsights.AspNetCore Nuget package:

dotnet add package AspNetMonsters.ApplicationInsights.AspNetCore

Next, in call AddCloudRoleNameInitializer in your application’s Startup.ConfigureServices method:

services.AddCloudRoleNameInitializer("WeatherService");

Filtering by Cloud Role

Setting the Cloud Role Name / Instance is about a lot more than seeing your services laid out properly in the Application Map. It’s also really important when you starting digging in to the performance and failures tabs in the Application Insights portal. In fact, on most of the sections of the portal, you’ll see this Roles filter.

Roles pill

The default setting is all. When you click on it, you have the option to select any combination of your application’s role names / instances. For example, maybe I’m only interested in the FrontEnd service and WeatherService that were running on the dave_yoga920 instance.

Roles filter

These filters are extremely useful when investigating performance or errors on a specific server or within a specific service. The more services your application is made up of, the more useful and essential this filtering become. These filters really help focus in on specific areas of an application within the Application Insights portal.

Next Steps

In this post, we saw how to customize telemetry data using telemetry initializers. Setting the cloud role name is a simple customization that can help you navigate the massive amount of telemetry that application insights collects. In the next post, we will explore a more in complex example of using telemetry initializers.

Monsters Weekly 150 - Getting started with .NET Core on Linux

This episode covers the basics of getting started with .NET Core on Ubuntu Linux. We install the .NET Core SDK and write some code using only the built in text editor. That’s right, no Windows, no Visual Studio! Just the console and a text editor.

Monsters Weekly 149 - Fluent Assertions in .NET

In this week’s episode, Simon walks us through the Fluent Assertions library for .NET. Learn how fluent assertions can help make your tests more readable and how to assertion scopes can batch your assertions to make test output easier to understand.

Learn more at https://fluentassertions.com/

Getting the Most Out of Application Insights for .NET (Core) Apps

Originally posted to: http://www.davepaquette.com/archive/2020/01/20/getting-the-most-out-of-application-insights-for-net-core-apps.aspx

Application Insights is a powerful and surprisingly flexible application performance monitoring (APM) service hosted in Azure. Every time I’ve used Application Insights on a project, it has opened the team’s eyes to what is happening with our application in production. In fact, this might just be one of the best named Microsoft products ever. It literally provides insights into your applications.

Application Map provides a visual representation of your app's dependencies

Application Insights has built-in support for .NET, Java, Node.js, Python, and Client-side JavaScript based applications. This blog post is specifically about .NET applications. If you’re application is built in another language, head over to the docs to learn more.

Codeless Monitoring vs Code-based Monitoring

With codeless monitoring, you can configure a monitoring tool to run on the server (or service) that is hosting your application. The monitoring tool will monitor running processes and collect whatever information is available for that particular platform. There is built in support for Azure VM and scale sets, Azure App Service, Azure Cloud Services, Azure Functions, Kubernetes applications and On-Premises VMs. Codeless monitoring is a good option if you want to collect information for applications that have already been built and deployed, but you are generally going to get more information using Code-based monitoring.

With code-based monitoring, you add the Application Insights SDK. The steps for adding the SDK are well document for ASP.NET Core, ASP.NET, and .NET Console applications so I don’t need to re-hash that here.

If you prefer, I have recorded a video showing how to add Application Insights to an existing ASP.NET Core application.

Telemetry

Once you’ve added the Application Insights SDK to your application, it will start collecting telemetry data at runtime and sending it to Application Insights. That telemetry data is what feeds the UI in the Application Insights portal. The SDK will automatically collection information about your dependencies calls to SQL Server, HTTP calls and calls to many popular Azure Services. It’s the dependencies that often are the most insightful. In a complex system it’s difficult to know exactly what dependencies your application calls in order to process an incoming request. With App Insights, you can see exactly what dependencies are called by drilling in to the End-to-End Transaction view.

End-to-end transaction view showing an excess number of calls to SQL Server

In addition to dependencies, the SDK will also collect requests, exceptions, traces, customEvents, and performanceCounters. If your application has a web front-end and you add the JavaScript client SDK, you’ll also find pageViews and browserTimings.

Separate your Environments

The SDK decides which Application Insights instance to send the collected telemetry based on the configured Instrumentation Key.

In the ASP.NET Core SDK, this is done through app settings:

{
"ApplicationInsights": {
"InstrumentationKey": "ccbe3f84-0f5b-44e5-b40e-48f58df563e1"
}
}

When you’re diagnosing an issue in production or investigating performance in your production systems, you don’t want any noise from your development or staging environments. I always recommend creating an Application Insights resource per environment. In the Azure Portal, you’ll find the instrumentation key in the top section of the Overview page for your Application Insights resource. Just grab that instrumentation key and add it to your environment specific configuration.

Use a single instance for all your production services

Consider a micro-services type architecture where your application is composed of a number of services, each hosted within it’s own process. It might be tempting to have each service point to a separate instance of Application Insights.

Contrary to the guidance of separating your environments, you’ll actually get the most value from Application Insights if you point all your related production services to a single Application Insights instance. The reason for this is that Application Insights automatically correlates telemetry so you can track a particular request across a series of separate services. That might sound a little like magic but it’s not actually as complicated as it sounds.

It’s this correlation that allows the Application Map in App Insights to show exactly how all your services interact with each other.

Application Map showing multiple services

It also enables the end-to-end transaction view to show a timeline of all the calls between your services when you are drilling in to a specific request.

This is all contingent on all your services sending telemetry to the same Application Insights instance. The Application Insights UI in the Azure Portal has no ability to display this visualizations across multiple Application Insights instances.

You don’t need to be on Azure

I’ve often heard developers say “I can’t use Application Insights because we’re not on Azure”. Well, you don’t need to host your application on Azure to use Application Insights. Yes, you will need an Azure subscription for the Application Insights resource, but your application can be hosted anywhere. That includes your own on-premise services, AWS or any other public/private cloud.

Next Steps

Out of the box, Application Insights provides a tremendous amount of value but I always find myself having to customize a few things to really get the most out of the telemetry. Fortunately, the SDK provides some useful extension points. My plan is to follow up this post with a few more posts that go over those customizations in detail. I also have started to create a NuGet package to simplify those customizations so stay tuned!

The Monsters Weekly - Episode 148 - WebWindow

In this week’s episode, we explore Steve Sanderson’s latest experiment: WebWindow. What is WebWindow, when might we use it, and why are we so darn excited about it?

https://blog.stevensanderson.com/2019/11/18/2019-11-18-webwindow-a-cross-platform-webview-for-dotnet-core/
https://github.com/SteveSandersonMS/WebWindow

The Monsters Weekly - Episode 147 - Runtime View Compilation in Development Environment

As of ASP.NET Core 3 Razor views are pre-compiled by default. This is great for performance in a staging or production environment but can really show things down in a developer environment because it requires us to restart the app anytime we make a change to a razor file. In this episode, Monster Dave shows us how to re-enable runtime view compilation in development environments.

The Monsters Weekly - Episode 146 - WebForms Dependency Injection

Dependency injection is a way to make your code more pluggable and thus more testable. In this video we attempt (and succeed) to add some dependency injection to an ASP.NET WebForms app just like Grandma use to make..