Configure Azure Blob ConnectionString from Azure KeyVault with NLog

Viewed 63

I am trying to set the target connectiostring value of nlog.config file from appsettings.json of the application. I was able to do it in .Net 5.0 but same is not working with .net 6.0, Seems like here we only have Program.cs file and no Startup.cs.

I am not able to identify the proper place in Program.cs of .net 6.0 probably to run the code which is running on .net 5.0.

Can anyone please check and advise the same?

Error Snap: enter image description here

Program.cs:

//initialize logger 
var logger = NLog.LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); //getting error at this line

UpdateNLogConfig(builder.Configuration, builder.Environment);

static void UpdateNLogConfig(IConfiguration configuration, IHostEnvironment env)
{
    var storageConnectionString = configuration.GetSection("abc-defg-sa-conn").Get<string>();
    GlobalDiagnosticsContext.Set("StorageConnectionString", storageConnectionString);
    var configFile = "nlog.config";
    LogManager.Configuration = LogManager.LoadConfiguration(configFile).Configuration;
}

nlog.config:

<target xsi:type="AzureBlobStorage"
      name="azure"
      layout="${layout}"
      connectionString="${gdc:item=StorageConnectionString}"
      container="ssystemslogs"              
      blobName="${date:universalTime=true:format=yyyy-MM-dd}/${date:universalTime=true:format=HH}.log" >            
</target>
1 Answers

You need to acquire the ConnectionString from Azure KeyVault before you load the NLog Logging Configuration.

Maybe skip using LoadConfigurationFromAppSettings() and instead just rely on UseNLog():

var builder = WebApplication.CreateBuilder(args);
builder.Configuration.AddAzureKeyVault(secretClient, ...);

builder.Logging.ClearProviders();
builder.Host.UseNLog();

And then use ${configsetting} in NLog.config:

<target xsi:type="AzureBlobStorage"
      name="azure"
      layout="${layout}"
      connectionString="${configsetting:abc-defg-sa-conn}"
      container="ssystemslogs"              
      blobName="${date:universalTime=true:format=yyyy-MM-dd}/${date:universalTime=true:format=HH}.log" >            
</target>

Alternative consider using Managed ClientIdentity together with ServiceUrl, where the application-identity has the blob-permission assigned (Avoids the need to use SecretClient to lookup connection-string)

See also: https://github.com/JDetmar/NLog.Extensions.AzureStorage/blob/master/src/NLog.Extensions.AzureBlobStorage/README.md

Related