Monitor Azure Functions with C#

This document explains how to monitor your Azure Functions written in C#. Monitoring is crucial for understanding the health, performance, and usage of your serverless applications. We'll cover key tools and techniques including Application Insights, logging, and distributed tracing.

Note: Application Insights is the recommended monitoring solution for Azure Functions. It provides a comprehensive set of tools for detecting, diagnosing, and understanding the performance of your live application.

Using Application Insights

Application Insights is an extensible Application Performance Management (APM) service for web applications. It's integrated with Azure Functions to provide rich metrics and logging capabilities.

Setting up Application Insights

When you create an Azure Function App, you can optionally associate it with an Application Insights instance. If you didn't do this during creation, you can link an existing or new Application Insights resource to your Function App through the Azure portal. Ensure the APPINSIGHTS_INSTRUMENTATIONKEY or APPLICATIONINSIGHTS_CONNECTION_STRING application setting is configured in your Function App.

Key Telemetry Data

Viewing Telemetry in Application Insights

Navigate to your Application Insights resource in the Azure portal to access the monitoring data:

Structured Logging with C#

Azure Functions in C# leverage the built-in logging framework, which integrates seamlessly with Application Insights. You can use the ILogger interface to emit various levels of log messages.

Basic Logging

Inject ILogger into your function and use its methods:


using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;

public class MyFunction
{
    private readonly ILogger _logger;

    public MyFunction(ILogger logger)
    {
        _logger = logger;
    }

    [Function("MyHttpTrigger")]
    public void Run(
        [HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
    {
        _logger.LogInformation("C# HTTP trigger function processed a request.");

        string name = req.Query["name"];
        if (string.IsNullOrEmpty(name))
        {
            name = "world";
        }

        _logger.LogWarning("Processing request for name: {Name}", name); // Structured logging

        string responseMessage = $"Hello, {name}!";
        var response = req.CreateResponse(System.Net.HttpStatusCode.OK);
        response.WriteString(responseMessage);

        _logger.LogInformation("Response sent for name: {Name}", name);
        return response;
    }
}
            

Log Levels

Common log levels include:

You can configure the minimum log level captured in your Function App's host.json file.

Structured Logging

Using the named placeholder syntax ({Name}) in your log messages allows Application Insights to parse and index these values, making them searchable and filterable in KQL queries.

Distributed Tracing

Distributed tracing helps you understand the flow of requests across multiple services and functions. Azure Functions, when integrated with Application Insights, automatically generates correlation IDs for distributed tracing.

How it Works

When a function is triggered by another service (e.g., an HTTP request, a queue message), Application Insights attempts to propagate context information. This allows you to trace a single transaction end-to-end.

Viewing Traces

In Application Insights, navigate to the Application Map to visualize the dependencies and flow between your functions and other services. You can also use the Transaction Search to find specific traces and drill down into their individual operations and logs.

Tip: For custom tracing scenarios or when integrating with services that don't automatically propagate context, consider using the ITelemetryInitializer and ITelemetryProcessor interfaces in Application Insights to enrich telemetry or implement custom correlation logic.

Custom Metrics

While Application Insights provides many built-in metrics, you can also send custom metrics to track specific business-related values or operational insights unique to your function.


using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using Microsoft.Azure.WebJobs.Extensions.OpenTelemetry.Quantities; // For Units

public class MyCustomMetricFunction
{
    private readonly ILogger _logger;
    private readonly TelemetryClient _telemetryClient; // Assuming TelemetryClient is configured

    public MyCustomMetricFunction(ILogger logger, TelemetryClient telemetryClient)
    {
        _logger = logger;
        _telemetryClient = telemetryClient;
    }

    [Function("ProcessOrder")]
    public void ProcessOrder(
        [QueueTrigger("orders")] string orderMessage)
    {
        _logger.LogInformation("Processing order: {OrderMessage}", orderMessage);

        // Simulate order processing
        var orderDetails = System.Text.Json.JsonSerializer.Deserialize(orderMessage);

        // Send a custom metric
        _telemetryClient.TrackMetric("OrdersProcessed", 1, new Dictionary<string, string> {
            { "OrderType", orderDetails.Type }
        });

        _logger.LogInformation("Order processed successfully.");
    }

    public class Order
    {
        public string Id { get; set; }
        public string Type { get; set; }
        public decimal Amount { get; set; }
    }
}
            

These custom metrics can be visualized and alerted on in the Metrics Explorer.

Alerting

Configure alerts in Application Insights to notify you when specific conditions are met, such as high error rates, increased latency, or low success percentages. This allows for proactive issue resolution.

Creating Alerts

In your Application Insights resource, go to Alerts and click New alert rule. You can define conditions based on metrics or log queries.

Important: Proactive monitoring and timely alerting are essential for maintaining the reliability and availability of your Azure Functions.

By leveraging Application Insights and structured logging, you can gain deep insights into the behavior of your C# Azure Functions, enabling efficient troubleshooting and performance optimization.