使用 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的主要内容,如果未能解决你的问题,请参考以下文章