【问题标题】:ILogger injected via constructor for Http trigger functions with Azure Function 2.x使用 Azure Function 2.x 通过构造函数为 Http 触发函数注入 ILogger
【发布时间】:2019-07-29 16:29:51
【问题描述】:

ILogger 可以注入到函数参数中,比如下面的Token 方法。

但是,注入到构造函数参数log时,出现了下面的错误。

[07/03/2019 17:15:17] 执行“令牌”(失败, id=4e22b21f-97f0-4ab4-8f51-8651b 09aedc8) [07/03/2019 17:15:17] Microsoft.Extensions.DependencyInjection.Abstractions:无法 解析“Microsoft.Extensions.Logging.ILogger”类型的服务,而 尝试激活“功能”。

ILogger 可以注入到下面的Token 函数参数中。但是上面的错误是注入到构造函数参数log时发生的。

public class Functions
{
    private HttpClient _httpClient;
    private IAppSettings _appSettings;
    private ILogger _log;

    public Functions(HttpClient httpClient, IAppSettings appSettings  //working for these two
      , ILogger log  //not working, errors
    )
    {

        _log = log;
    }

    [FunctionName("Token")]
    public async Task<IActionResult> Token(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "Token")]
        HttpRequest httpRequest,
        ILogger log)
    {

    }
}

下面的依赖注入

[assembly: WebJobsStartup(typeof(Startup))]
namespace MyApp
{
    public class Startup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder builder)
        {
            builder.Services.AddHttpClient();
            builder.Services.AddTransient<IAppSettings, AppSettings>();     
             //builder.Services.AddLogging();  //not working
           //builder.Services.AddSingleton<ILogger>() //not working
        }
}

视觉工作室 2017

【问题讨论】:

    标签: c# azure azure-functions


    【解决方案1】:

    致电LogCategories.CreateFunctionUserCategory 解决了我的问题。完整示例:

    Azure Functions Core Tools (2.7.1158 Commit hash: f2d2a2816e038165826c7409c6d10c0527e8955b)
    Function Runtime Version: 2.0.12438.0
    

    Startup.cs

    无需添加builder.Services.AddLogging();,它会自动导入到容器中。

    using Microsoft.Azure.Functions.Extensions.DependencyInjection;
    using Microsoft.Extensions.DependencyInjection;
    
    [assembly: FunctionsStartup(typeof(MyFunctionsNamespace.Startup))]
    
    namespace MyFunctionsNamespace
    {
        public class Startup : FunctionsStartup
        {
            public override void Configure(IFunctionsHostBuilder builder)
            {
                builder.Services.AddTransient<IMyService, MyService>();
            }
        }
    }
    

    MyFunkyFunction.cs

    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.Extensions.Logging;
    
    namespace MyFunctionsNamespace
    {
        public class MyFunkyFunction
        {
            private readonly IMyService _myService;
    
            public MyFunkyFunction(IMyService myService)
            {
                _myService = myService;
            }
    
            [FunctionName("FunkyFunc")]
            public async Task<IActionResult> Run(
                [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
                HttpRequest req
                , ILogger log
            )
            {
                log.LogInformation("C# HTTP trigger function processed a request.");
    
                _myService.Do();
    
                return new OkObjectResult("Hello");
            }
        }
    }
    

    IMyService.cs

    LogCategories.CreateFunctionUserCategory 中的任何内容都可以完成这项工作。这似乎是一些 WebJob 遗留要求。

    using Microsoft.Azure.WebJobs.Logging;
    using Microsoft.Extensions.Logging;
    
    namespace MyFunctionsNamespace
    {
        public interface IMyService
        {
            void Do();
        }
    
    
        public class MyService : IMyService
        {
            private readonly ILogger _log;
    
            public MyService(ILoggerFactory loggerFactory)
            {
                // Important: Call CreateFunctionUserCategory, otherwise log entries might be filtered out
                // I guess it comes from Microsoft.Azure.WebJobs.Logging
                _log = loggerFactory.CreateLogger(LogCategories.CreateFunctionUserCategory("Common"));
            }
    
            public void Do()
            {
                _log.Log(LogLevel.Information, "Hello from MyService");
            }
        }
    }
    

    【讨论】:

    • LogCategories.CreateFunctionUserCategory() 成功了
    【解决方案2】:

    我也有这个问题。我可以通过调用 AddLogging() 来修复它:

    [assembly: WebJobsStartup(typeof(Startup))]
    namespace MyApp
    {
        public class Startup : IWebJobsStartup
        {
            public void Configure(IWebJobsBuilder builder)
            {
                builder.Services.AddHttpClient();
                builder.Services.AddTransient<IAppSettings, AppSettings>();     
                builder.Services.AddLogging();
            }
    }
    

    然后,在 Azure 函数中,我必须传递 ILoggerFactory 而不是 ILogger 并从 loggerFactory 获取 ILogger 实例:

    public class Functions
    {
        private HttpClient _httpClient;
        private IAppSettings _appSettings;
        private ILogger _log;
    
        public Functions(HttpClient httpClient, IAppSettings appSettings, ILoggerFactory loggerFactory)
        {
            _log = loggerFactory.CreateLogger<Functions>();
        }
    
        [FunctionName("Token")]
        public async Task<IActionResult> Token(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "Token")]
            HttpRequest httpRequest)
        {
               // No need to keep getting the ILogger from the Run method anymore :)
        }
    }
    

    【讨论】:

    • 这对我有用——但前提是我用loggerFactory.CreateLogger("Function.Token.User"); 实例化ILogger
    • 您无权访问 CreateLogger() 的通用版本?
    • 我想将调试级别的应用程序日志事件记录到每个函数的文件中。磁盘上的位置是/LogFiles/Application/Functions/Function/TokenFunction/2019-03-11T00-00-00Z-012345abcd.log。仅当 categoryName 以 Function. 开头并附加后缀 .User 时,Azure Functions 框架才会在此处记录。因此,如果我有 [FunctionName("Token")] 和 categoryName Function.Token.User 的记录器,我可以通过日志记录配置进行过滤。 "logging": { "logLevel": { "fileLoggingMode": "always", "Function": "Warning", "Function.Token.User": "Debug" } }
    • 通用的 CreateLogger 会创建一个 categoryName Namespace.ClassName
    猜你喜欢
    • 2022-08-22
    • 2018-12-12
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 2012-06-19
    • 2019-11-01
    • 1970-01-01
    • 2015-10-01
    相关资源
    最近更新 更多