Logging in Azure Functions

Effective logging is crucial for debugging, monitoring, and understanding the behavior of your Azure Functions. Azure Functions provides several built-in mechanisms and integrates with Azure Monitor for comprehensive logging capabilities.

Overview of Logging#

When you write code for Azure Functions, you can leverage the built-in logging abstractions. These abstractions allow you to write logs that are automatically collected and made available for analysis.

Key aspects of logging include:

Writing Logs in Your Function#

The primary way to write logs in Azure Functions is by using the ILogger instance available in your function context.

C# Example#


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

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))
        {
            _logger.LogWarning("Parameter 'name' is missing in the request.");
            // You might return a bad request response here
        }
        else
        {
            _logger.LogInformation($"Processing request for name: {name}");
            // Your business logic here
            _logger.LogDebug($"Finished processing for {name}.");
        }

        // Example of logging an exception
        try
        {
            throw new InvalidOperationException("Simulating an error.");
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "An unexpected error occurred.");
        }
    }
}
            

JavaScript (Node.js) Example#


module.exports = async function (context, req) {
    context.log('JavaScript HTTP trigger function processed a request.');

    const name = (req.query.name || (req.body && req.body.name));

    if (name) {
        context.log.info(`Processing request for name: ${name}`);
        context.log.verbose('Detailed information about the process.');
        // Your business logic here
        context.log.debug('Debug information.');
    } else {
        context.log.warn('Parameter "name" is missing in the request.');
        // You might return a bad request response here
    }

    // Example of logging an exception
    try {
        throw new Error('Simulating an error.');
    } catch (error) {
        context.log.error('An unexpected error occurred.', error);
    }

    context.res = {
        body: `Hello, ${name || 'World'}!`
    };
};
            
Tip: When using Node.js, the context.log object provides methods for different log levels (log.info, log.warn, log.error, log.debug, log.verbose).

Logging Levels#

Azure Functions supports the following standard logging levels, from most severe to least severe:

The log level configured for your function app determines which logs are sent to your logging destination. For example, if your log level is set to Warning, only messages with a level of Warning or higher (Error, Critical) will be recorded.

Configuring Log Levels#

You can configure the default log level for your function app in the host.json file.


{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "default": "Information",
      "Host.Triggers.Http": "Debug"
    }
  }
}
            

In this example:

You can set specific log levels for different categories of your application.

Viewing and Querying Logs#

Logs generated by Azure Functions are typically sent to Azure Monitor Logs (Log Analytics workspace). You can access and query these logs using the Azure portal.

Using Azure Monitor Logs#

Navigate to your Function App in the Azure portal, then go to Logs under the Monitoring section.

Here are some common KQL queries:

All Logs from a Function App#


AppTraces
| where AppName == 'YourFunctionAppName'
| order by TimeGenerated desc
            

HTTP Trigger Requests#


AppRequests
| where AppName == 'YourFunctionAppName'
| where Type == 'HttpTrigger'
| order by Timestamp desc
            

Function Execution Logs (Information and above)#


AppTraces
| where AppName == 'YourFunctionAppName'
| where SeverityLevel >= 2 // 2 = Information
| order by TimeGenerated desc
            

Finding Errors or Warnings#


AppTraces
| where AppName == 'YourFunctionAppName'
| where SeverityLevel in (3, 4) // 3 = Warning, 4 = Error
| order by TimeGenerated desc
            
Note: The exact table names and column names might vary slightly depending on your Azure Functions runtime and configuration. The primary tables to look for are AppTraces, AppRequests, and AppExceptions.

Correlation ID#

Azure Functions automatically generates a correlation ID for each function execution. This ID is included in all log messages associated with that execution, allowing you to trace the entire flow of a single request through your function and any downstream services it might interact with.

When you write logs using ILogger or context.log, the correlation ID is usually automatically included. You can also explicitly include it in structured log data.

Best Practices for Logging#