Search code examples
azureasp.net-coreazure-storageazure-webjobsazure-webjobssdk

ASP.NET Core Azure WebJob not logging to Azure Storage


Previously when I've created Azure webjobs in .NET, it has automatically configured logging to a text file on Azure storage on path /azure-webjobs-hosts/output-logs/.txt. However now when I'm working with .NET Core and version 3.0.14 of the Webjobs SDK, it no longer has this behavior by default.

Logging to console and also Application Insights works well with my current setup, however I do want text file logging on Azure Storage as well via the binded ILogger. I've followed official guides on how to configure it, but it all points to storage queues and I'm not sure that is a good approach and how to tweak it.

Configuration code:

static async Task Main(string[] args)
{
    var config = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddEnvironmentVariables()
        .Build();

    builder.UseEnvironment("development");
    builder.ConfigureWebJobs(b =>
    {
        b.AddAzureStorageCoreServices();
        b.AddAzureStorage();
    });
    builder.ConfigureLogging((context, b) =>
    {
        b.AddConsole();

        string instrumentationKey = context.Configuration["ApplicationInsightsKey"];
        if (!string.IsNullOrEmpty(instrumentationKey))
        {
            b.AddApplicationInsightsWebJobs(o => o.InstrumentationKey = instrumentationKey);
        }

    });
    builder.ConfigureServices(s => s.AddSingleton<IConfigurationRoot>(config));

    var host = builder.Build();
    using (host)
    {
        var jobHost = host.Services.GetService(typeof(IJobHost)) as JobHost;

        await host.StartAsync();
        await jobHost.CallAsync("Run");
        await host.StopAsync();
    }
}

Job code:

[NoAutomaticTrigger]
public async Task Run(ILogger logger)
{
    logger.LogInformation("I want this text in console as well as on Azure Storage");

    // ..logic
}

Solution

  • I do want text file logging on Azure Storage as well via the binded ILogger.

    The Serilog.Sinks.AzureBlobStorage can help write logs to Azure Blob Storage, and which would work well both on azure and local.

    In Program.cs

    builder.ConfigureLogging((context, b) =>
    {
        b.AddConsole();
    
        var configuration = new ConfigurationBuilder()
        .AddJsonFile("appsettings.json")
        .Build();
    
        var AzureBlobStorageLogger = new LoggerConfiguration()
            .ReadFrom.Configuration(configuration)
            .CreateLogger();
    
        b.AddSerilog(logger: AzureBlobStorageLogger);
    });
    

    In appsettings.json

    {
      "Serilog": {
        "Using": [
          "Serilog.Sinks.AzureBlobStorage"
        ],
        "WriteTo": [
          {
            "Name": "AzureBlobStorage",
            "Args": {
              "connectionString": "{your_connectionString_here}",
              "storageContainerName": "azure-webjobs-hosts",
              "storageFileName": "output-logs/{yyyy}/{MM}/{dd}/log.txt"
            }
          }
        ]
      },
      //other settings
      //...
    }
    

    Besides, as @IvanYang mentioned, you can also achieve it by adding Azure diagnostics logger, but this provider only works when the project runs in the Azure environment. It does not write logs to Azure Blob Storage when we run webjob on local.