无法使用通过 DI 提供的 ILogger 实例 [英] Unable to use ILogger instance provided via DI

查看:26
本文介绍了无法使用通过 DI 提供的 ILogger 实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

本质上,我有两种不同的方式获取 ILogger 实例.一个工作得很好,另一个没有.

Essentially, there are two different ways I get ILogger instances. One works perfectly fine, the other doesn't.

我有一个这样的 Azure 函数:

I have an Azure Function like this:

class AzureFunctionClass {

     private readonly ISomeClass _someclass;

     public AzureFunctionClass(ISomeClass someClass){
          _someclass = someClass;
     }

     public Task<IActionResult> AzureFunction(ILogger log){
             log.LogInformation("This works, I see this message when run");
             _someclass.ExecuteMethod();
     }
}

另一个类,不包含 Azure 函数,如下所示:

Another class, not containing Azure functions, like this:

class SomeClass : ISomeClass {

     private readonly ILogger<SomeClass> _log;

     public SomeClass(ILogger log){
           _log = log;
     }

     public void ExecuteMethod(){
           _log.LogInformation("This doesn't crash so _log isn't null, but it 
                                doesn't write anything");
     }
}

Startup.cs:

Startup.cs:

class Startup : IWebJobsStartup {

     public void Configure(IWebJobsBuilder builder){
          builder.Services.AddScoped<ISomeClass, SomeClass>();
          builder.Services.AddTransient(typeof(ILogger<>), typeof(Logger<>));
          builder.Services.AddScoped<ILogger<SomeClass>, Logger<SomeClass>>();
     }
}

不,恐怕 AzureFunctionClass 不能将其 ILogger 实例作为参数传递给 ISomeClass.我还到处寻找日志文件,例如在 Azure 存储资源管理器中,看看它是否可能只是没有写入 Azure 门户控制台.我发现的每个日志文件都有上述工作案例的日志,但没有一个有其他案例的日志.

And no, I'm afraid that AzureFunctionClass cannot just pass its ILogger instance to ISomeClass as a parameter. I've also looked everywhere for log files, such as in Azure Storage Explorer, to see if it's possibly just not writing to the Azure Portal console. Every log file I found had logs for the working case described above, and none of them had logs for the other case.

推荐答案

目前,函数运行时有一个错误,因为它过滤掉任何创建的类别没有的日志't 以字符串 Function..

At present, the function runtime has a bug due to which it filters out any log that is created with a category that doesn't start with string Function..

查看这些 GitHub 问题:

See these GitHub issues:

在函数方法中注入的记录器由函数运行时完成,该函数运行时创建类别设置为 Function..User 的记录器.所以这会被正确记录.但是注入构造函数的记录器是由 asp.net 核心 DI 框架完成的,它将记录器的类别名称设置为 Type.FullName(在您的示例中,类型是 SomeClass).因为它的全名不是以 Function 开头,所以用这个类别记录的行会被过滤掉.

The logger injected in the function method is done by the function runtime which creates the logger with category set to Function.<FunctionName>.User. So this gets logged properly. But the logger that is injected into the constructor is done by the asp.net core DI framework, which sets the category name for the logger as Type.FullName (type in your example case is SomeClass). Because it's fullname doesn't start with Function, the lines logged with this category are filtered out.

有两种方法可以解决这个问题.

There are two ways to workaround this.

选项 1:更改 host.json 以不过滤来自命名空间的日志

{
  "version": "2.0",
  "logging": {
    "logLevel": {
      "<YourNameSpace>": "Information"
    }
  }
}

选项 2:在您的构造函数中注入 ILoggerFactory,并创建一个类别不会被过滤的记录器

class SomeClass : ISomeClass {

     private readonly ILogger _log;

     public SomeClass(ILoggerFactory loggerFactory){  // Note that we inject ILoggerFactory
           this._log = loggerFactory.CreateLogger(
            LogCategories.CreateFunctionUserCategory(this.GetType().FullName));  // Must use CreateFunctionUserCategory to create the log category name otherwise the log gets filtered out.
     }

     public void ExecuteMethod(){
           _log.LogInformation("This should get logged correctly.");
     }
}

请注意,ILogger 已被函数运行时注册到 DI 框架中(如 NKosi 的回答中所述),因此可以删除这些行.

Note that, ILogger is already registered into DI framework by the function runtime (as mentioned in NKosi's answer), so those lines can be removed.

这篇关于无法使用通过 DI 提供的 ILogger 实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆