Adventures with App Insights: Tracking Custom Events in .NET Core Function Application

WARNING: According to this article, https://docs.microsoft.com/en-us/azure/azure-functions/functions-dotnet-dependency-injection#logging-services, is NOT A RECOMMENDED PRACTICE.

While what I have done works, according to the article, adding AddApplicationInsightsTelemetry() to the services collection “registers services that conflict with services provided by the environment.”

In a previous article, we looked at how to track custom events in Azure Application Insights from a .NET Core Web Application, in this article, we will look at how to track custom events from Azure Functions.

Azure Functions support a variety of languages, in this article we will stick with C#.

In Azure, you will need to create a Resource Group, and then create an Application Insights resource.

Create an Azure Function project in either Visual Studio or VS Code..

I named my Azure Function project, FunctionApp1, when prompted for a Trigger type, select HttpTrigger and name the class ValuesHttpTrigger.cs.

Install the NuGet Package Microsoft.ApplicationInsights.AspNetCore to add Application Insights support.

We will also need to install the NuGet Package Microsoft.Azure.Functions.Extensions to add support for dependency injection in our Azure Function project.

In the Azure Portal, navigate to your Application Insights resource and copy the Instrumentation Key.

Open the local.settings.json file.

Replace the ApplicationInsights:InstrumentationKey value with the Instrumentation Key value for your Application Insights resource.

{
  "IsEncrypted": false,
  "Values": {
    "AzureWebJobsStorage": "UseDevelopmentStorage=true",
    "FUNCTIONS_WORKER_RUNTIME": "dotnet",
    "ApplicationInsights:InstrumentationKey": "YOUR_APPLICATION_INSIGHTS_INSTRUMENTATION_KEY"
  }
}

Add a new file called Startup.cs, and past in the contents of the code snippet as follows:

using Microsoft.Azure.Functions.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection;
using System;

[assembly: FunctionsStartup(typeof(FunctionApp1.Startup))]
namespace FunctionApp1
{
    public class Startup : FunctionsStartup
    {
        public override void Configure(
            IFunctionsHostBuilder builder)
        {
            builder.Services.AddApplicationInsightsTelemetry(
                Environment.GetEnvironmentVariable("ApplicationInsights:InstrumentationKey"));
        }
    }
}

This will wire up Application Insights.

Now on to tracking some events in our Azure Functions!

Update the contents of the ValuesHttpTrigger.cs class with the contents of the code snippet that follows:

using Microsoft.ApplicationInsights;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;

namespace FunctionApp1
{
    public class ValuesHttpTrigger
    {
        readonly TelemetryClient _telemetryClient;

        public ValuesHttpTrigger(
            TelemetryClient telemetryClient)
        {
            _telemetryClient = telemetryClient;
        }

        [FunctionName("Get")]
        public IEnumerable<string> Get(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "values")] HttpRequest req)
        {
            _telemetryClient.TrackEvent(
                "Get");

            return new string[] { "value1", "value2" };
        }


        [FunctionName("GetById")]
        public string GetById(
            [HttpTrigger(AuthorizationLevel.Function, "get", Route = "values/{id}")] HttpRequest req,
            int id)
        {
            _telemetryClient.TrackEvent(
                "Get",
                new Dictionary<string, string>() { { "id", id.ToString() } });

            return "value";
        }

        [FunctionName("Post")]
        public async Task<string> Post(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = "values")] HttpRequest req)
        {
            string value =
                await new StreamReader(req.Body).ReadToEndAsync();

            _telemetryClient.TrackEvent(
               "Post",
                new Dictionary<string, string>() { { "value", value } });

            return value;
        }

        [FunctionName("Put")]
        public async Task<string> Put(
            [HttpTrigger(AuthorizationLevel.Function, "put", Route = "values/{id}")] HttpRequest req,
            int id)
        {
            string value =
                await new StreamReader(req.Body).ReadToEndAsync();

            _telemetryClient.TrackEvent(
               "Put",
                new Dictionary<string, string>() { { "id", id.ToString() }, { "value", value } });

            return value;
        }

        [FunctionName("Delete")]
        public void Delete(
            [HttpTrigger(AuthorizationLevel.Function, "delete", Route = "values/{id}")] HttpRequest req,
            int id)
        {
            _telemetryClient.TrackEvent(
                "Delete",
                new Dictionary<string, string>() { { "id", id.ToString() } });
        }
    }
}

Some background on what is going on.

The TelemetryClient is being injected, thanks to our Startup.cs configuration.

In each method we want to track, in Application Insights, the request type and any variables that were passed.

Run the Function App.

In Postman, create requests for the GETPOSTPUT and DELETE against the API methods in our Web Application.

In the Azure Portal, navigate to the Application Insights resource, and click Log Analytics.

You should see a list of your custom events.

Please note, it may take a couple of minutes for the data to actually show up in Azure Application Insights.

Thanks for reading!

Leave a Reply

Your email address will not be published.