Почему сообщения ILogger.LogTrace не отображаются в окне консоли для func.exe для приложения-функции Azure v2 - PullRequest
0 голосов
/ 07 октября 2018

В связи с недавними изменениями в версии 2 приложения-функции Azure в сентябре 2018 года код приложения-функции был изменен.Однако, похоже, что:

  • LogTrace () больше не отображаются в окне консоли (и я подозреваю, что Application Insights), и
  • categoryLevels на хостеКажется, что .json не соблюдается.

Проблема была продублирована в приложении sample ниже при вызове LogWithILogger () .Два других момента:

(1) Я отмечаю, что уровень трассировки фильтра по умолчанию кажется жестко заданным.Можно ли добавить еще один фильтр, чтобы разрешить работу LogTrace (), или LogTrace () больше не следует использовать?Если можно добавить еще один фильтр, как можно добавить необходимые объекты в приложение-функцию, чтобы разрешить это?

public static void Microsoft.Extensions.Logging.AddDefaultWebJobsFilter(this ILoggingBuilder builder)
{
    builder.SetMinimumLevel(LogLevel.None);
    builder.AddFilter((c,l) => Filter(c, l, LogLevel.Information));
}

(2) Intellisense вокруг LogLevel указывает:

  • LogLevel.Trace = 0

Журналы, которые содержат самые подробные сообщения.Эти сообщения могут содержать конфиденциальные данные приложения.Эти сообщения по умолчанию отключены и никогда не должны включаться в производственной среде.

Я ожидаю, что LogTrace можно будет использовать для окна консоли при отладке - и будет управляться настройками categoryLevel.

Итак, что нужно делать с точки зрения написания трассировочных сообщений для приложения-функции V2 с использованием ILogger?Спасибо за совет!

ОБРАЗЕЦ ПРИМЕНЕНИЯ

Function1.cs

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Azure.WebJobs.Host;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Microsoft.Azure.WebJobs.Description;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Configuration;

namespace FunctionAppTestLogging
{
    [AttributeUsage(AttributeTargets.Parameter)]
    [Binding]
    public class InjectAttribute : Attribute
    {
        public InjectAttribute(Type type)
        {
            Type = type;
        }
        public Type Type { get; }
    }

    public class WebJobsExtensionStartup : IWebJobsStartup
    {
        public void Configure(IWebJobsBuilder webjobsBuilder)
        {

            webjobsBuilder.Services.AddLogging(builder => builder.SetMinimumLevel(LogLevel.Trace).AddFilter("Function", LogLevel.Trace));
            ServiceCollection serviceCollection =  (ServiceCollection) webjobsBuilder.Services;
            IServiceProvider serviceProvider = webjobsBuilder.Services.BuildServiceProvider();

            // webjobsBuilder.Services.AddLogging();
            //  webjobsBuilder.Services.AddSingleton(new LoggerFactory());
            // loggerFactory.AddApplicationInsights(serviceProvider, Extensions.Logging.LogLevel.Information);
        }
    }

    public static class Function1
    {
        private static string _configuredLoggingLevel;

        [FunctionName("Function1")]
        public static async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]HttpRequest req, ILogger log, ExecutionContext context) // , [Inject(typeof(ILoggerFactory))] ILoggerFactory loggerFactory) //  , [Inject(typeof(ILoggingBuilder))] ILoggingBuilder loggingBuilder)
        {
            LogWithILogger(log);
            LogWithSeriLog();
            SetupLocalLoggingConfiguration(context, log);
            LogWithWrappedILogger(log);

            return await RunStandardFunctionCode(req);
        }

        private static void SetupLocalLoggingConfiguration(ExecutionContext context, ILogger log)
        {
            var config = new ConfigurationBuilder()
                            .SetBasePath(context.FunctionAppDirectory)
                            .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                            .AddEnvironmentVariables()
                            .Build();

            // Access AppSettings when debugging locally.
            string loggingLevel = config["LoggingLevel"];  // This needs to be set in the Azure Application Settings for it to work in the cloud.
            _configuredLoggingLevel = loggingLevel;
        }

        private static void LogWithWrappedILogger(ILogger log)
        {
            LogWithWrappedILoggerHelper("This is Critical information from WrappedILogger", LogLevel.Critical, log);
            LogWithWrappedILoggerHelper("This is Error information from WrappedILogger", LogLevel.Error, log);
            LogWithWrappedILoggerHelper("This is Information information from WrappedILogger", LogLevel.Information, log);
            LogWithWrappedILoggerHelper("This is Debug information from WrappedILogger", LogLevel.Debug, log);
            LogWithWrappedILoggerHelper("This is TRACE information from WrappedILogger", LogLevel.Trace, log);
        }

        private static void LogWithWrappedILoggerHelper(string message, LogLevel messageLogLevel, ILogger log)
        {
            // This works as expected - Is the host.json logger section not being respected?
            Enum.TryParse(_configuredLoggingLevel, out LogLevel logLevel);
            if (messageLogLevel >= logLevel)
            {
                log.LogInformation(message);
            }
        }

        private static void LogWithILogger(ILogger log)
        {
            var logger = log;
            // Microsoft.Extensions.Logging.Logger _logger = logger; // Logger is protected - so not accessible.

            log.LogCritical("This is critical information!!!");
            log.LogDebug("This is debug information!!!");
            log.LogError("This is error information!!!");
            log.LogInformation("This is information!!!");
            log.LogWarning("This is warning information!!!");

            log.LogTrace("This is TRACE information!! from LogTrace");
            log.Log(LogLevel.Trace, "This is TRACE information from Log", null);
        }

        private static void LogWithSeriLog()
        {
            // Code using the Serilog.Sinks.AzureTableStorage package per https://docs.microsoft.com/en-us/sandbox/functions-recipes/logging?tabs=csharp
            /*
            var serilog = new LoggerConfiguration()
            .WriteTo.AzureTableStorage(connectionString, storageTableName: tableName, restrictedToMinimumLevel: LogEventLevel.Verbose)
            .CreateLogger();
            log.Debug("Here is a debug message {message}", "with some structured content");
            log.Verbose("Here is a verbose log message");
            log.Warning("Here is a warning log message");
            log.Error("Here is an error log message");
            */
        }

        private static async Task<IActionResult> RunStandardFunctionCode(HttpRequest req)
        {
            string name = req.Query["name"];
            string requestBody = await new StreamReader(req.Body).ReadToEndAsync();
            dynamic data = JsonConvert.DeserializeObject(requestBody);
            name = name ?? data?.name;

            return name != null
                ? (ActionResult)new OkObjectResult($"Hello, {name}")
                : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
        }
    }
}

host.json

  {
  "version": "2.0",
  // The Azure Function App DOES appear to read from host.json even when debugging locally thru VS, since it complains if you do not use a valid level.
  "logger": {
    "categoryFilter": {
      "defaultLevel": "Trace", // Trace, Information, Error
      "categoryLevels": {
        "Function": "Trace"
      }
    }
  }

1 Ответ

0 голосов
/ 08 октября 2018

Для функции v2 настройка журнала в host.json имеет другой формат.

{
  "version": "2.0",
  "logging": {
    "fileLoggingMode": "debugOnly",
    "logLevel": {
      // For specific function
      "Function.Function1": "Trace",
      // For all functions
      "Function":"Trace",
      // Default settings, e.g. for host 
      "default": "Trace"
    }
  }
}
...