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:
- Structured Logging: Functions supports structured logging, which means your log entries can include key-value pairs, making them easier to query and analyze.
- Log Levels: You can categorize your logs by severity (e.g., Information, Warning, Error, Critical, Debug, Trace).
- Correlation: Logs from different parts of your application or across multiple function executions can be correlated to trace a single request or workflow.
- Integration with Azure Monitor: Logs are typically sent to Azure Monitor, where you can query them using Kusto Query Language (KQL), create alerts, and build dashboards.
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'}!`
    };
};
            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:
- Critical
- Error
- Warning
- Information
- Debug
- Trace
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:
- "default": "Information"sets the default log level for all categories to- Information.
- "Host.Triggers.Http": "Debug"sets a more detailed log level specifically for HTTP trigger host logs.
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
            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#
- Log at the appropriate level: Use Informationfor general flow,Warningfor potential issues, andErrorfor actual failures. ReserveDebugandTracefor detailed troubleshooting.
- Be descriptive: Log messages should clearly explain what is happening. Include relevant data like input parameters or identifiers.
- Use structured logging: Log key-value pairs when possible to make your logs searchable and filterable.
- Avoid logging sensitive information: Be mindful of PII (Personally Identifiable Information) and other sensitive data in your logs.
- Monitor your logs: Set up alerts in Azure Monitor for critical errors or specific warning patterns.
- Keep logs concise: Avoid excessive logging that can overwhelm your logging system and increase costs.