NLog: NLog in Azure Function - not working when resolved with DI
Hi,
I’ve been struggling for a while now, to use NLog in an Azure function. I got to the point where:
-
I have a Startup class in my function where I configure and register NLog to the ServiceCollection, through the loggingBuilder , using an ElasticSearch target
-
The ILogger instance that is passed to the RUN method of the function works (i.e. I see my logs in Elastic Search)
-
Further in my function I resolve a custom application service using the IServiceProvider , in the application service I have an ILogger<T> as a dependency. This is also resolved fine, and among the _loggers property I can see an instance of NLogger. But when calling the logger.LogError method, nothing happens, no exception, and I don’t see anything in ElasticSearch
My Startup.cs:
public class Startup : FunctionsStartup
{
public Startup()
{
// LogManager.Configuration = new XmlLoggingConfiguration("NLog.config");
// NLogBuilder.ConfigureNLog(LogManager.Configuration);
LoggingConfiguration config = new LoggingConfiguration();
LogManager.ThrowExceptions = true;
var elasticTarget = new ElasticSearchTarget()
{
Uri = "----the url -----",
IncludeAllProperties = true,
Fields = new List<Field>()
{
new Field()
{
Name = "host",
Layout = "${aspnet-request-host}"
},
new Field()
{
Name = "machine",
Layout = "${machinename}"
},
new Field()
{
Name = "activityid",
Layout = "${aspnet-TraceIdentifier}"
}
}
};
var bufferedElasticTarget = new BufferingTargetWrapper("ElasticSearch", elasticTarget)
{
FlushTimeout = 10000
};
config.AddTarget(bufferedElasticTarget);
var nlogElasitcSearchRule = new LoggingRule("*", NLog.LogLevel.Debug, elasticTarget);
config.LoggingRules.Add(nlogElasitcSearchRule);
NLogBuilder.ConfigureNLog(config);
LogManager.Configuration = config;
}
public override void Configure(IFunctionsHostBuilder builder)
{
try
{
var config = builder.Services.BuildServiceProvider().GetRequiredService(typeof(IConfiguration)) as IConfiguration;
var originationConfiguration = new OriginationConfiguration();
config.GetSection("OriginationConfigs").Bind(originationConfiguration);
builder.Services.AddOriginationServices(originationConfiguration);
builder.Services.AddLogging((loggingBuilder) => { loggingBuilder.AddNLog(); });
}
catch (Exception ex)
{
var abc = ex;
}
}
}
My function:
[FunctionName(nameof(PingHttpTrigger))]
public IActionResult PingHttpTrigger(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "ping")] HttpRequest req, ILogger log)
{
try
{
throw new Exception("cocomarla_exceptie");
}
catch (Exception ex)
{
// this logging works, no problem
log.LogError(ex, "error test");
}
CustomerRegisteredEvent customerRegistered = new CustomerRegisteredEvent()
{
AggregateId = Guid.NewGuid(),
EventId = Guid.NewGuid(),
Customer = new Context.Entities.Customer()
};
var customerEventHandler = _serviceProvider.GetRequiredService<IEventHandler<CustomerRegisteredEvent>>() as IEventHandler<CustomerRegisteredEvent>;
customerEventHandler.Handle(customerRegistered);
return new OkObjectResult(new { timestamp = DateTime.UtcNow });
}
And the CustomerEventHandler class:
public class CustomerEventHandler : IEventHandler<CustomerRegisteredEvent>,
IEventHandler<CustomerUpdatedEvent>
{
private ICustomerService customerService;
private ILogger<CustomerEventHandler> logger;
public CustomerEventHandler(ICustomerService customerService, ILogger<CustomerEventHandler> logger)
{
this.customerService = customerService;
this.logger = logger;
}
public void Handle(CustomerRegisteredEvent @event)
{
try
{
throw new Exception("cocomarla_exceptie");
}
catch (Exception ex)
{
// this doesn't work, no log anywhere
logger.LogError(ex, "error test");
}
// customerService.CreateCustomerProjection(@event.Customer);
}
public void Handle(CustomerUpdatedEvent @event)
{
customerService.UpdateCustomerProjection(@event.Customer);
}
}
I think there must be a conflict somewhere, because the Azure Function’s pipeline must be slightly different than the ASP.NET pipeline, so probably something doesn’t add up in the ServiceCollection… not sure.
Thoughts ? Any help would be greatly appreciated.
Thanks, Vlad
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Comments: 19 (11 by maintainers)
Update: after enabling the internal logging, I saw that NLog was missing the serviceProvider (the internal log stated: " Debug Missing serviceProvider, so no HttpContext" .
I did a couple of searches on this and it seems that the serviceProvider was not properly registered with NLog.
In an ASP.NET Core web app, this is fixed by registering NLog using the UseNLog() method on the IWebHostBuilder, but this is not available in Azure Functions, so I am using loggingBuilder.AddNLog();
Turns out, you can pass the following Options object to AddNLog:
And then the issue is fixed.
I’m thinking to leave this issue open, for some feedback from the authors… otherwise it can be closed.
Thanks