azure-functions-host: ILogger is not injected when using new DI functionality
- Function App version: 2.0
- Microsoft.Net.Sdk.Function v. 1.0.28
- Microsoft.Azure.Functions.Extensions v.1.0.0
When using DI supplied with Function Extension nuget package, an instance of ILogger is not getting injected into dependent classes.
According to the article, we shouldn’t have to setup our own logging, because functions have default application insights logging (“For Application Insights, Functions adds Application Insights automatically for you”).
Is this intended functionality and article is inaccurate and we need to setup our logging in order to get ILogger to be injected, or is this a bug?
[assembly: FunctionsStartup(typeof(BBI.AzureDevOpsAutomation.Functions.Startup))]
namespace BBI.AzureDevOpsAutomation.Functions
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddSingleton<IService, Service>();
}
}
}
public class Service
{
private readonly ILogger _logger;
public Service(ILogger logger)
{
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
}
}
When resolving an instance of the Service, constructor is throwing an exception, because ILogger is not injected.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 4
- Comments: 38 (11 by maintainers)
@brettsam @VaclavElias if your solution has common namespace, if you just reference it in the host.json, it will cover your whole solution. for example all my project namespaces are MyCompany.SolutionName.ProjectName, so when I set host.json to this, everything gets logged.
I don’t see any issues with having to supply this configuration, because we should be controlling our log levels regardless. If you enable trace logging in dev environment, you probably don’t want to enable it in production.
@older, @brettsam it is all very cryptic, isn’t it? 😃
Finally, I made it working, tested locally only at the moment.
All you did is ok but you need to white list SampleGreeter according this (till this is fixed) https://github.com/Azure/azure-functions-host/issues/4345.
It didn’t work for me just using SampleGreeter, I had to put there whole namespace Microsoft.Azure.Functions.Samples.DependencyInjectionBasic
in your host.json
Tested it and got the same result. ILogger<T> gets injected but doesn’t log anything to application insights. I added logger to the SampleGreeter this way:
And added logging statement to the function body:
Nothing is logged from greeter, while logging from function works.
ILogger
itself isn’t a supported DI service. You need to useILogger<T>
: https://docs.microsoft.com/en-us/aspnet/core/fundamentals/logging/?view=aspnetcore-2.2#create-logs.ILogger
is the base interface, but it cannot be constructed via DI as there’s no known category. When you use anILogger<T>
, it uses the typeT
to construct a category.Just to correct myself, it doesn’t throw an exception in my case but it doesn’t log anything.
Ah yes – that’s because the only way we know how to direct the logs to that window are via the logger’s category. If it matches the form
Function.{FunctionName}.User
category, we then know which function they came from, so we can show them there. There’s likely a way to make this work, though – I’ve opened #4689 to track this.Yes, that is an unfortunate issue; sorry I forgot to point that out here.
When we first built logging, we controlled all of the logging categories so we put a filter in place to weed out things coming from other components by default. Unfortunately it also weeds out custom categories, which is becoming more prevalent with DI opening up. I’ll be addressing that soon so this filter can go away.
@alexzheludov Try asking for the type parameterized
ILogger<>
, i.e.ILogger<Service>
. That’ll work.I used this example to reproduce it, but with
Microsoft.NET.Sdk.Functions 1.0.28
andMicrosoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator 1.1.1
.Ah. No, it does not. But you shouldn’t be seeing any logs in App Insights in gov cloud. There’s a DI-based workaround in this comment: https://github.com/Azure/azure-webjobs-sdk/issues/2263#issuecomment-511998264. We have this added to the current sprint, so we hope to have this settable in the host.json soon.
Thanks @brettsam I managed to fix it myself. I was registering my dependencies in my own IServiceCollection, instead of creating a Startup class. As soon as I switched to having Startup class and using IServiceCollection provided by it, logging started to work. Although still, not everywhere. Seems that it works only from classes that exist under my Azure Function project. When I log from classes that are in other projects (and that are referenced by Azure Function project), they are not visible in log stream. I put in host.json the common part of namespace that all my projects share.
@optiks brilliant, that fixed my issue! Thanks a lot!
Have you tried
builder.Services.AddSingleton<IServiceRequestService, ServiceRequestService>(x => new ServiceRequestService(gatewayService, x.GetRequiredService<ILogger<IServiceRequestService>>()))
?