Azure / azure-functions-host

The host/runtime that powers Azure Functions
https://functions.azure.com
MIT License
1.92k stars 442 forks source link

Isolated .NET Host is not respecting Log Level Filters in `host.json` or App Settings #9259

Open kluhman opened 1 year ago

kluhman commented 1 year ago

I am trying to disable the Information log messages emitted by the HttpClient as they make about ~50% of all logs sent to our Application Insights and are beginning to cost quite a bit on a high volume service. I have tried creating a filter for the System.Net.Http.HttpClient category in both the host.json and in app settings, but it does not appear to be working either way. I have confirmed this filter works correctly in a standard .NET application, but does not appear to be respected by the Functions host.

I was able to reproduce this in a minimal reproduction project, all the code for this is included below.

Program.cs

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using SampleFunctions;

var host = new HostBuilder()
    .ConfigureFunctionsWorkerDefaults()
    .ConfigureServices(services =>
    {
        services.AddHttpClient<IHttpGateway, HttpGateway>();
    })
    .Build();

host.Run();

host.json

{
    "version": "2.0",
    "logging": {
        "logLevel": {
            "System.Net.Http.HttpClient": "Warning"
        }
    }
}

local.settings.json

{
    "IsEncrypted": false,
    "Values": {
        "AzureWebJobsStorage": "UseDevelopmentStorage=true",
        "FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
        "Logging": {
            "LogLevel": {
                "System.Net.Http.HttpClient": "Warning"
            }
        }
    }
}

HttpGateway.cs

namespace SampleFunctions;

public interface IHttpGateway
{
    Task GetPage();
}

public class HttpGateway : IHttpGateway
{
    private readonly HttpClient _client;

    public HttpGateway(HttpClient client) => _client = client;

    public Task GetPage() => _client.GetAsync("https://example.com");
}

TestFunction.cs

using System.Net;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;

namespace SampleFunctions;

public class TestFunction
{
    private readonly IHttpGateway _gateway;

    public TestFunction(IHttpGateway gateway) => _gateway = gateway;

    [Function("TestFunction")]
    public async Task<HttpResponseData> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequestData req)
    {
        await _gateway.GetPage();

        var response = req.CreateResponse(HttpStatusCode.OK);
        return response;
    }
}

Repro steps

Examples of log messages from HttpClient

Expected behavior

No Information level messages from HttpClient are displayed in the Console output

Actual behavior

Information level messages from HttpClient are displayed in the Console output

Known workarounds

Adding this to the host builder in Program.cs seems to have the desired effect, but requires hardcoded logging configuration rather than accepting my configuration settings.

.ConfigureLogging(logBuilder =>
{
    logBuilder.AddFilter("System.Net.Http.HttpClient", LogLevel.Warning);
})
samusaran commented 8 months ago

Hi, have you found any solutions to this?

ManelBH commented 8 months ago

I used to do the opposite and do something like:

            "LogLevel": {
                "default": "Warning",
                "My.Namespace": "Information"
            }

But in the isolated host this is no longer possible either.

xinfli commented 7 months ago

Any update for this issue?

We met similar problem that log lower than warning will not be collected by appInsights/log analytics workspace, no matter what configuration is applied in host.json.

It's really bad that we could not get logs in production environment for debug.

An ugly workaround is to log all information with LogLevel.None, since "None" is higher than "Critical" so it will be collected:

_logger.Log(LogLevel.None, "Here is the message");

Below is the configuration of our Function App:

dimula commented 7 months ago

However, by default, the Application Insights SDK adds a logging filter that instructs the logger to capture only warnings and more severe logs. If you want to disable this behavior, remove the filter rule as part of service configuration:

https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=windows#managing-log-levels

Fazer01 commented 6 months ago

Maybe this issue helps?

https://github.com/Azure/azure-functions-dotnet-worker/issues/1182

And also this one: https://github.com/Azure/azure-functions-dotnet-worker/issues/1025

rahulsingii commented 3 months ago

Seems in islotaed mode the logging configurations are not automatically loaded. So I added them manually and still maintaining the logLevel in my host.json file:-

var config = new ConfigurationBuilder()
                    .SetBasePath(Directory.GetCurrentDirectory())
                    .AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
                    .AddJsonFile("host.json", optional:true, reloadOnChange: true)
                    .AddEnvironmentVariables()
                                       .....
var host = new HostBuilder()
    .ConfigureFunctionsWebApplication()
    .ConfigureLogging((builder, logging) =>
    {
        logging.AddConfiguration(config.GetSection("logging"));
    })
    .ConfigureServices(services => {
        .....
krishnasingh1818 commented 1 month ago

am facing similar issues with recent .net9 upgrades. Appinsights are filling up with debug logs even if we have put the filters in appsettings.json. This is increasing our appinsight cost and makes troubleshooting difficult since lot of noise logs is visible. Please advise. Also does this also effect the .net8 apI side also ? am seeing some rise in logs there too.

even with this change its not working>

.ConfigureLogging((builder, logging) =>
    {
        logging.AddConfiguration(config.GetSection("logging"));
    })