Under Azure Functions -> MyFunction -> Monitoring -> Logs one would expect to find logs - you know, stuff we log in our application via ILogger
.
Instead one finds a mystifying list of tables availabilityResults
, browserTimings
, customEvents
, customMetrics
, dependencies
, exceptions
, pageViews
, performanceCounters
, requests
, traces
none of which is called logs and none of which contains any data we have logged. When we look at the trace
table - it seems to be framework stuff we don't really want to see:
Under Azure Functions -> MyFunction -> Logs Stream we see our logs but it's a big mess of verbose logs (even though AzureFunctionsJobHost__logging__LogLevel__Default
is set to Information
) from the Function App (not the Function) which seems inseparable via filter hence the requirement to access our logs via KQL. Why is the framework logging such trace/verbose stuff at the "Information" level including HTTP Headers?
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": false
}
},
"logLevel": {
"default": "Warning",
"Company.App": "Trace",
"Azure.Core": "Error"
}
}
}
PS: Is Company.App: "Trace"
the reason we see
Under Azure Functions -> MyFunction -> Monitoring -> Logs one would expect to find logs - you know, stuff we log in our application via ILogger
.
Instead one finds a mystifying list of tables availabilityResults
, browserTimings
, customEvents
, customMetrics
, dependencies
, exceptions
, pageViews
, performanceCounters
, requests
, traces
none of which is called logs and none of which contains any data we have logged. When we look at the trace
table - it seems to be framework stuff we don't really want to see:
Under Azure Functions -> MyFunction -> Logs Stream we see our logs but it's a big mess of verbose logs (even though AzureFunctionsJobHost__logging__LogLevel__Default
is set to Information
) from the Function App (not the Function) which seems inseparable via filter hence the requirement to access our logs via KQL. Why is the framework logging such trace/verbose stuff at the "Information" level including HTTP Headers?
host.json
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": false
}
},
"logLevel": {
"default": "Warning",
"Company.App": "Trace",
"Azure.Core": "Error"
}
}
}
PS: Is Company.App: "Trace"
the reason we see
1 Answer
Reset to default 1Why is the framework logging such trace/verbose stuff at the "Information" level including HTTP Headers?
If you use trace then it logs everything as Verbose.
Under Azure Functions -> MyFunction -> Monitoring -> Logs one would expect to find logs - you know, stuff we log in our application via
ILogger
.
The custom logging one do with Ilogger will be logged in App insights in table traces, exceptions, etc. You will not have logs table. This is how logging is done in Functions.
To only get the logs of ILogger, you can use below code:
If we use Information level, you will also get exceuting statements extra:
host.json:
{
"version": "2.0",
"logging": {
"applicationInsights": {
"samplingSettings": {
"isEnabled": true,
"excludedTypes": "Request"
},
"enableLiveMetricsFilters": true
},
"logLevel": {
"default": "Warning",
"Function.Function1": "Trace"
}
}
}
function.cs:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.Functions.Worker;
using Microsoft.Extensions.Logging;
namespace FunctionApp11
{
public class Function1
{
private readonly ILogger ri_lg;
public Function1(ILoggerFactory logger)
{
ri_lg = logger.CreateLogger<Function1>(); ;
}
[Function("Function1")]
public IActionResult Run([HttpTrigger(AuthorizationLevel.Function, "get", "post")] HttpRequest req)
{
ri_lg.LogInformation("LogInformation");
ri_lg.LogError("LogError");
ri_lg.LogWarning("LogWarning");
ri_lg.LogCritical("LogCritical");
return new OkObjectResult("Welcome to Azure Functions!");
}
}
}
program.cs:
using Microsoft.Extensions.Hosting;
using Serilog;
var host = new HostBuilder()
.ConfigureFunctionsWebApplication()
.ConfigureServices(services =>
{
Log.Logger = new LoggerConfiguration()
.CreateLogger();
})
.Build();
host.Run();
csproj:
<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="2.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http" Version="3.2.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore" Version="2.0.0" />
<PackageReference Include="Microsoft.Azure.Functions.Worker.Sdk" Version="2.0.0" />
<PackageReference Include="Serilog" Version="4.1.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>
Output:
If you use traces, you will get headers and all. If do not want the execution statements too then use Debug or Warning as Loglevel and use Log.LogDebug, Log.LogError, to only custom log.
log.LogInformation
,log.LogDebug
,log.LogWarning
and ``log.LogError` and NONE of these messages appears in the trace table - only in Log Stream. Where are OUR events visible in KQL? – Marc Commented Nov 20, 2024 at 12:11