使用 Azure Function 2.x 通过构造函数为 Http 触发函数注入 ILogger
Posted
技术标签:
【中文标题】使用 Azure Function 2.x 通过构造函数为 Http 触发函数注入 ILogger【英文标题】:ILogger injected via constructor for Http trigger functions with Azure Function 2.x 【发布时间】: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
【问题讨论】:
【参考方案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
。以上是关于使用 Azure Function 2.x 通过构造函数为 Http 触发函数注入 ILogger的主要内容,如果未能解决你的问题,请参考以下文章
Azure Function 1.x和VS17的Nuget问题
如何在 Azure Function 中使用 Azure Managed Identity 通过触发器访问 Service Bus?
通过 HTTP 调用 Azure Function 150 次导致异常
Azure Keyvault 通过 ARM 添加 Function MSI