Introducing .NET Core Support for Azure Functions

October 5, 2022

With the latest release, Instana is introducing .NET Core support for Azure Functions deployed as Docker container to further increase our customer’s observability in serverless environments.

What are Azure Functions?

Azure Functions is an on-demand cloud service that provides all the continually updated infrastructure and resources needed to run your applications. The biggest advantage of Functions is that you can focus on the pieces of code that matter the most, and the rest is handled by Functions and Azure.

How is it applied?

The feature of Functions to provide serverless computing was particularly interesting to us in terms of how Instana will work in that environment.

.NET is one of the platforms that is supported by Azure Functions.

The usual way of instrumenting .NET applications is by adding Instana’s NuGet packages into the project. Then, every collected trace would be sent to Instana’s agent and then directly to Instana’s backend.

But given the circumstances, this is not how we will use Instana in Azure Functions. Let’s see how it should work.

Problems

There are two ways of deploying Azure Functions Application to Azure, as Code using Azure App Services and as Docker container. At the moment, two requirements have to be met to make Instana work in Azure Functions. These requirements are:

  1. Your Azure Function Application is a .NET Core application and
  2. Your Azure Function Application is deployed on Azure using the Docker Container option.

Deploying Azure Functions Application as a Docker container on Azure raises the first problem. You should NOT install Instana’s NuGet packages inside the project and deploy but prepare and send all Instana library files within the container. The tracing won’t work if there are duplicated library files after the application is deployed.

On the other hand, there is the second problem – serverless computing. That means we can’t run our agent in the release environment to collect traces. The Instana’s agent will only collect metrics on the machine it is installed on, but this time without spans. As a solution for this problem, your Azure Function Application will report to Instana’s Serverless Ingress Endpoint. From there on, every collected trace will be sent to Instana’s backend through the corresponding serverless ingress endpoint.

Practical example

Please keep in mind that this example works only with .NET Core Azure Function Application deployed on Azure as a Docker container.

Let’s assume that Instana’s agent is installed on our machine and already set up for Azure. After that, we created a .NET Core Azure Functions Application.

This application has one Function called TimerFunction. The trigger for this function is Timer. This function has one method Run that is called every 5 minutes.

public class TimerFunction
{
  [FunctionName("TimerFunction")]
  public void Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer, ILogger log)
  {
    log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
  }
}

To solve the first problem, let’s introduce Instana.Tracing.Core packages to our project. Instead of directly installing NuGet packages into our project, we will download them and copy Instana.Tracing.Core library files to some patch folder that is easily accessible from Dockerfile.

Once this is done it is necessary to copy these files to the Azure release folder using the Dockerfile:

COPY "/patch/Instana.Tracing.Core.dll" "/home/site/wwwroot/bin/Instana.Tracing.Core.dll"
COPY "/patch/Instana.Tracing.Core.Common.dll" "/home/site/wwwroot/bin/Instana.Tracing.Core.Common.dll"
COPY "/patch/Instana.Tracing.Core.Instrumentation.dll" "/home/site/wwwroot/bin/Instana.Tracing.Core.Instrumentation.dll"
COPY "/patch/Instana.Tracing.Core.Transport.dll" "/home/site/wwwroot/bin/Instana.Tracing.Core.Transport.dll"
COPY "/patch/Instana.Tracing.Api.dll" "/home/site/wwwroot/bin/Instana.Tracing.Api.dll"
COPY "/patch/CoreProfiler.so" "/home/site/wwwroot/bin/instana_tracing/CoreProfiler.so"
COPY "/patch/instrumentation.json" "/home/site/wwwroot/bin/instana_tracing/instrumentation.json"

Furthermore, we should also add all necessary Instana’s environment variables to Dockerfile to make tracing work.

FROM mcr.microsoft.com/azure-functions/dotnet:3.0
ENV AzureWebJobsScriptRoot=/home/site/wwwroot \
    AzureFunctionsJobHost__Logging__Console__IsEnabled=true \
    DOTNET_STARTUP_HOOKS="/home/site/wwwroot/bin/Instana.Tracing.Core.dll" \
    CORECLR_ENABLE_PROFILING=1 \
    CORECLR_PROFILER="{cf0d821e-299b-5307-a3d8-b283c03916dd}" \
    CORECLR_PROFILER_PATH="/home/site/wwwroot/bin/instana_tracing/CoreProfiler.so" \
    INSTANA_ENDPOINT_URL="[Serverless-ingress-URL-for-your-region]" \
    INSTANA_AGENT_KEY="[Your-Instana-agent-key]"

You can also download the Docker image from this link.

INSTANA_ENDPOINT_URL will be the serverless ingress URL for your region. Reporting to the serverless ingress endpoint will solve our second problem.

Once our application is deployed and running on Azure, we wait for our spans to be generated, sent to Instana’s backend, and visible on the Stan dashboard.

Each Azure Functions (azf) span has some essential information such as Trigger type, Method name, Function name, and Runtime environment.

When some other type of trigger is used, for example, an HTTP trigger, the entry span will be an HTTP span with all corresponding HTTP information, as you can see in this example.

Again, this azf span will have all Azure Functions information just as the span that was created for TimerFunction in the previous example.

Great, we now collect and report tracing spans for .Net Core in Azure Functions. But what about metrics?

The metrics will be created and sent by the Instana agent we installed and configured for Azure on our machine. Let’s check them out on Stan’s dashboard. There is also a list of all functions that our Azure Functions Application has.

We can see the converted and processed span and metric data from our application in the Stan dashboard.

To conclude, Instana is wherever our customers are. By introducing the support for Azure Functions, we continue supporting the use cases of our customers and continue with our integration of Azure Services.

The support for .NET Core support for Azure Functions deployed as Docker container is just the beginning of the long journey called Azure Functions. Stay tuned!

For more on Instana’s support of Azure and Azure Functions, here’s some additional reading material:

Play with Instana’s APM Observability Sandbox

Start your FREE TRIAL today!

Instana, an IBM company, provides an Enterprise Observability Platform with automated application monitoring capabilities to businesses operating complex, modern, cloud-native applications no matter where they reside – on-premises or in public and private clouds, including mobile devices or IBM Z.

Control hybrid modern applications with Instana’s AI-powered discovery of deep contextual dependencies inside hybrid applications. Instana also gives visibility into development pipelines to help enable closed-loop DevOps automation.

This provides actionable feedback needed for clients as they to optimize application performance, enable innovation and mitigate risk, helping Dev+Ops add value and efficiency to software delivery pipelines while meeting their service and business level objectives.

For further information, please visit instana.com.