I am writing Azure functions in dotnet 8 using v4 dotnet-isolated.
When Deployed to Azure I want to log custom trace messages at level "Debug" and above to application insights. When debugging locally I want to see all my custom logs at level 'Trace' and above.
I would also like the deployed log level to be changeable through configuration so that once the function has been deployed a while it can be easily changed to Information and then Warning.
I will include my code further down, but here is a summary of what I have done so far:
This all works very well when running locally. I get trace messages coming through in the console. I can change the value in local.settings.json and the logs are filtered as expected. I can remove the local settings entry and then I get Debug and above locally and I can also change the level in host.json and logs are filtered as expected.
It becomes a problem when I actually publish to azure. In azure I get all logs, including trace always. Adding AzureFunctionsJobHost__logging__logLevel__function has no effect, nor does changing the logging values in host.json. host.json with a log level of "Error" still logs Trace to Critical in application insights.
I've checked the host.json file and the correct one is deployed.
The only thing that seems to effect log levels once deployed is the logger.SetMinimumLevel() The deployed code in azure always logs to that level and above.
Why?
{
"version": "2.0",
"logging": {
"logLevel": {
"function": "Debug"
},
"applicationInsights": {
"samplingSettings": {
"isEnabled": false,
"excludedTypes": "Request"
},
"enableLiveMetricsFilters": true
}
}
}
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services => {
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
})
.ConfigureLogging(logging =>
{
logging.SetMinimumLevel(LogLevel.Trace); //this controls the minimum log level allowed in config (you still need to set in config, usually to Information)
logging.Services.Configure<LoggerFilterOptions>(options =>
{
LoggerFilterRule? defaultRule = options.Rules.FirstOrDefault(rule => rule.ProviderName == "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
if (defaultRule is not null)
{
options.Rules.Remove(defaultRule);
}
});
})
.Build();
host.Run();
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Azure.Functions.Worker.Http;
using Microsoft.Extensions.Logging;
namespace Basl
{
public class TestLogging
{
private readonly ILogger<TestLogging> _logger;
public TestLogging(ILogger<TestLogging> logger)
{
_logger = logger;
}
[Function("TestLogging")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
{
_logger.LogTrace("This is a TRACE log message");
_logger.LogDebug("This is a DEBUG log message");
_logger.LogInformation("This is a INFORMATION log message");
_logger.LogWarning("This is a WARNING log message");
_logger.LogError("This is a ERROR log message");
_logger.LogCritical("This is a CRITICAL log message");
return new OkObjectResult($"Log Messages tested at {DateTime.UtcNow.ToString()}");
}
}
}
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<OutputType>Exe</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.Azure.Functions.Worker" Version="1.21.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.1.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="1.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="1.16.4" />
<PackageReference Include="Microsoft.ApplicationInsights.WorkerService" Version="2.22.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.ApplicationInsights" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<ItemGroup>
<Using Include="System.Threading.ExecutionContext" Alias="ExecutionContext" />
</ItemGroup>
</Project>
host.json with a log level of "Error" still logs Trace to Critical in application insights.
By using below code and configuration getting logs below log level which mentioned in host.json.
host.json:
{
"version": "2.0",
"logging": {
"logLevel": {
"Function.Function1": "Debug"
},
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
},
"enableLiveMetricsFilters": true
}
}
}
Function1.cs:
public class Function1
{
private readonly ILogger<Function1> _logger;
public Function1(ILogger<Function1> logger)
{
_logger = logger;
}
[Function("Function1")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
{
_logger.LogTrace("This is a TRACE log message");
_logger.LogDebug("This is a DEBUG log message");
_logger.LogInformation("This is a INFORMATION log message");
_logger.LogWarning("This is a WARNING log message");
_logger.LogError("This is a ERROR log message");
_logger.LogCritical("This is a CRITICAL log message");
_logger.LogInformation("C# HTTP trigger function processed a request.");
return new OkObjectResult("Welcome to Azure Functions!");
}
}
Program.cs:
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
services.AddApplicationInsightsTelemetryWorkerService();
services.ConfigureFunctionsApplicationInsights();
services.Configure<LoggerFilterOptions>(options =>
{
LoggerFilterRule toRemove = options.Rules.FirstOrDefault(rule => rule.ProviderName
== "Microsoft.Extensions.Logging.ApplicationInsights.ApplicationInsightsLoggerProvider");
if (toRemove is not null)
{
options.Rules.Remove(toRemove);
}
});
})
.ConfigureAppConfiguration((hostContext, config) =>
{
config.AddJsonFile("host.json", optional: true);
})
.ConfigureLogging((hostingContext, logging) =>
{
logging.AddApplicationInsights(console =>
{
console.IncludeScopes = true;
});
logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging"));
})
.Build();
host.Run();



Output:


If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With