0

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
}
Ivan Glasenberg
  • 29,865
  • 2
  • 44
  • 60
Lucas Arrefelt
  • 3,879
  • 5
  • 41
  • 71

2 Answers2

3

If you want to save the logs(via ILogger) to blob storage, you need to publish the webjobs to azure. You can follow the steps below:

1.Add b.AddAzureWebAppDiagnostics(); method(need install the nuget package Microsoft.Extensions.Logging.AzureAppServices) into builder.ConfigureLogging code block:

        builder.ConfigureLogging((context, b) =>
        {
            b.AddConsole();
            b.AddAzureWebAppDiagnostics();

            //other code
        });

2.Publish it to azure, then in azure portal -> the related app service -> App Service Logs, configure "Application Logging(blob)", screenshot as below:

enter image description here

3.After running the webjob, nav to the blob storage which is configured in step 2, you can see a new log file is generated, and all the logs(includes logs via ILogger) are in the file.

enter image description here

Ivan Glasenberg
  • 29,865
  • 2
  • 44
  • 60
  • 1
    Thanks, after adding b.AddAzureWebAppDiagnostics() everything worked out of the box as I'm used to since it was already configured in Azure. However, @Fei Han answers has a bit more nice customizations to it so I went with that solution – Lucas Arrefelt Mar 19 '20 at 14:28
2

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.

Fei Han
  • 26,415
  • 1
  • 30
  • 41
  • Thanks for your answer! I tried @IvanYang answer and it worked well out of the box. However your solution offers more customization and also works locally, but I'm not able to configure the logger with b.AddSerilog(logger: AzureBlobStorageLogger). Am I missing some extension? – Lucas Arrefelt Mar 19 '20 at 14:11
  • Ok I found the Serilog.Extensions.Hosting library, now it works well. Considering this solution offers more customization I'll mark your answer as correct! – Lucas Arrefelt Mar 19 '20 at 14:26