8
votes

ILogger injecté via le constructeur pour les fonctions de déclenchement Http avec Azure Function 2.x

ILogger peut être injecté dans le paramètre de fonction, comme la méthode Token ci-dessous.

Cependant, l'erreur ci-dessous s'est produite lorsqu'elle est injectée dans le journal du paramètre du constructeur .

[07/03/2019 17:15:17] "Token" exécuté (échec, Id = 4e22b21f-97f0-4ab4-8f51-8651b 09aedc8) [07/03/2019 17:15:17] Microsoft.Extensions.DependencyInjection.Abstractions: impossible de résoudre le service pour le type «Microsoft.Extensions.Logging.ILogger» pendant tentative d'activation des «Fonctions».

ILogger peut être injecté dans le paramètre de fonction Token ci-dessous. Mais l'erreur ci-dessus s'est produite lorsqu'elle est injectée dans le paramètre du constructeur 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
        }
}

Injection de dépendance ci-dessous

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)
    {

    }
}


0 commentaires

3 Réponses :


6
votes

J'ai également eu ce problème. J'ai pu le réparer en appelant AddLogging():

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 :)
    }
}

Et puis, dans la fonction Azure, j'ai dû passer un ILoggerFactory code> au lieu d'un ILogger et récupérez l'instance ILogger de loggerFactory:

[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();
        }
}

p>


4 commentaires

Cela fonctionne pour moi - mais seulement si j'instancie le ILogger avec loggerFactory.CreateLogger ("Function.Token.User");


Vous n'avez pas accès à la version générique de CreateLogger ()?


Je veux que l'application enregistre les événements de débogage de niveau dans un fichier par fonction. L'emplacement sur le disque est / LogFiles / Application / Functions / Function / TokenFunction / 201‌ 9-03-11T00-00-00Z-01‌ 2345abcd.log . Le framework Azure Functions se connecte ici uniquement si le categoryName commence par Function. et ajoute le suffixe .User . Donc, si j'ai [FunctionName ("Token")] et un enregistreur avec categoryName Function.Token.User , je peux filtrer via la configuration de journalisation. "logging": {"logLevel": {"fileLoggingMode": "always", "Function": "Warning", "Function.Token.User": "Debug"}}


Le CreateLogger générique créerait un categoryName Namespace.ClassName .



7
votes

L'appel de LogCategories.CreateFunctionUserCategory a résolu mon problème. Exemple complet:

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");
        }
    }
}

Startup.cs

Pas besoin d'ajouter builder.Services.AddLogging (); il est importé automatiquement dans le conteneur.

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");
        }
    }
}

MyFunkyFunction.cs

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>();
        }
    }
}

IMyService.cs

Tout ce qui se trouve dans LogCategories.CreateFunctionUserCategory fera l'affaire. Cela semble être une exigence héritée de WebJob.

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


1 commentaires

LogCategories.CreateFunctionUserCategory () a fait l'affaire



3
votes

J'ai eu le même problème. J'ai finalement trouvé que l'ajout de cet élément "logging" à mon fichier host.json l'a résolu pour moi.

{
    "version": "2.0",
    "logging": {
        "logLevel": {
            "default": "Trace"
        }
    }
}

La méthode standard de journalisation injectée par le constructeur .NET core fonctionne correctement.


0 commentaires