- 4 minutes to read

How To Start Logging With Microsoft.Extensions.Logging.ILogger in Azure Functions

New 2.0.35

Info

This document applies to Nodinite Serilog sinks version >= 2.0.35 and demonstrates how to use the Microsoft.Extensions.Logging.ILogger interface for logging in Azure Functions (.NET 8+ with the isolated worker model). This approach is ideal for customers with existing codebases, as it allows you to add Nodinite logging with minimal code changes.

If you want to log using the "native" Serilog Logger, see 'How To Start Logging With Serilog'.

Nodinite's logging solution empowers system integration experts to achieve robust, structured, and centralized logging with minimal friction. By leveraging the standard ILogger interface, you can seamlessly integrate Nodinite's advanced logging capabilities into your Azure Functions or any .NET application. This method is highly recommended for both new and existing projects, as it enables you to benefit from Nodinite's unique selling points:

  • Integrate effortlessly with existing codebases—just update configuration and dependencies
  • Centralize and search logs for compliance, troubleshooting, and monitoring
  • Support multiple sinks (Blob, Event Hub, File, Log API, Service Bus, etc.)
  • Add advanced metadata and correlation for end-to-end traceability
  • Ensure full compatibility with DevOps and automation pipelines
  • Structured logging: Use structured log messages with named properties to enable powerful filtering, analytics, and machine-readable insights. Semantic logging makes it easy to correlate events, extract business context, and automate monitoring or alerting. This approach is especially valuable for large-scale, distributed, or regulated environments where traceability and data mining are essential.

Below you'll find a step-by-step example of how to configure and use Nodinite logging with Microsoft.Extensions.Logging.ILogger in Azure Functions using the isolated worker model.

There are three different settings examples available (appsettings.json); the rest of the code examples below are the same regardless of which method you choose.

Info

The Settings section is documented on a shared page. Read more at 'Settings Section (appsettings.json)'

Required NuGet packages

To enable Serilog Logging, add the required NuGet packages to your project. You can do this using the NuGet Package Manager in Visual Studio or by editing the .csproj file directly:

Dependencies in Project (.csproj)

Update the version when you update the NuGet packages. The versions below are examples. Always update to the latest version.

    <ItemGroup>
        ...
        <PackageReference Include="Nodinite.Serilog.AzureBlobStorageSink" Version="2.0.36" />
        <PackageReference Include="Serilog.AspNetCore" Version="9.0.0" />
  </ItemGroup>

Startup file (Program.cs)

using Microsoft.Azure.Functions.Worker.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
using Serilog.Settings.Configuration;

var builder = Host.CreateDefaultBuilder(args)
    .ConfigureFunctionsWebApplication()
    .ConfigureServices(services =>
    {
        // Add any additional services here
    })
    .ConfigureAppConfiguration(config =>
    {
        config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);
        config.AddEnvironmentVariables(); // Optional
    })
    .UseSerilog((context, configuration) =>
    {
        configuration.ReadFrom.Configuration(context.Configuration,
            new ConfigurationReaderOptions
            {
                SectionName = "Serilog",
            });
    });

// Application Insights isn't enabled by default. See https://aka.ms/AAt8mw4.
// builder.Services
//     .AddApplicationInsightsTelemetryWorkerService()
//     .ConfigureFunctionsApplicationInsights();

builder.Build().Run();

Log (Function.cs)

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;

namespace IsolatedWorkerExample.Functions
{
    public class MyFunction
    {
        private readonly ILogger<Function1> _logger;

        public Function1(ILogger<Function1> logger)
        {
            _logger = logger;
        }

        [Function("Function1")]
        public async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route=null)] HttpRequest req)
        {
            _logger.LogInformation("Function1");

            string name = req.Query["name"];

            var value = req.Headers.ContainsKey("clientTrackingId");

            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;
            
            var body = JsonConvert.SerializeObject(new { Id = 1 });
            
            string responseMessage = string.IsNullOrEmpty(name)
                ? "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."
                : $"Hello, {name}. This HTTP triggered function executed successfully.";

            if (req.Headers.ContainsKey("x-ms-client-tracking-id"))
            {
                Microsoft.Extensions.Primitives.StringValues id;
                req.Headers.TryGetValue("x-ms-client-tracking-id", out id);

                if (string.IsNullOrWhiteSpace(id[0]))
                {
                    _logger.LogInformation("{LogText} {ApplicationInterchangeId} {InputMessage} {OriginalMessageType} {Color}", "Hello from Function (without interchange id)", Guid.NewGuid(), body, "TestMessage#1.0", "Blue");
                }
                else
                {
                    _logger.LogInformation("{LogText} {ApplicationInterchangeId} {Body} {OriginalMessageType} {Color}", "Hello from Function", id[0], body, "TestMessage#1.0", "Blue");
                }
            }

            return new OkObjectResult(responseMessage);
        }
    }
}

Next Step

'How To Start Logging With Serilog'

Logging
Log Events
JSON Log Event
PickupService