Expected Behaviour
Setting POWERTOOLS_LOG_LEVEL=Trace should cause every level (Trace, Debug, Information, Warning, Error, Critical) to emit.
Setting POWERTOOLS_LOG_LEVEL=Debug should cause every level except Trace to emit.
This should hold whether the logger is used via Logger.LogTrace(...) / Logger.LogDebug(...) or via Logger.Log(LogLevel.Trace, ...) / Logger.Log(LogLevel.Debug, ...).
Current Behaviour
Trace and Debug calls are silently dropped regardless of the POWERTOOLS_LOG_LEVEL value. Information and above always emit. Setting POWERTOOLS_LOG_LEVEL to Information / Warning / Error / Critical correctly raises the floor; setting it below Information has no effect.
Reproduced on AWS.Lambda.Powertools.Logging 3.2.1, dotnet8 Lambda, no AWS_LAMBDA_LOG_LEVEL set, no explicit Logger.Configure(...) call.
Test matrix output:
Level Pass Missing Observed
UNSET True critical,error,information,warning
Trace False debug,trace critical,error,information,warning
Debug False debug critical,error,information,warning
Information True critical,error,information,warning
Warning True critical,error,warning
Error True critical,error
Critical True critical
Code snippet
Handler used to reproduce:
[Logging(ClearState = true)]
async Task<string> Handler(string input, ILambdaContext context)
{
Logger.LogTrace("LEVELTEST trace");
Logger.LogDebug("LEVELTEST debug");
Logger.LogInformation("LEVELTEST information");
Logger.LogWarning("LEVELTEST warning");
Logger.LogError("LEVELTEST error");
Logger.LogCritical("LEVELTEST critical");
return await Task.FromResult(input);
}
Root cause is in `Internal/Helpers/LoggerFactoryHelper.cs`:
internal static ILoggerFactory CreateAndConfigureFactory(PowertoolsLoggerConfiguration configuration)
{
var factory = LoggerFactory.Create(builder =>
{
builder.AddPowertoolsLogger(config => { /* copies fields */ });
if (configuration.SamplingRate > 0)
{
builder.AddFilter(null, LogLevel.Debug);
builder.SetMinimumLevel(LogLevel.Debug);
}
else if (configuration.MinimumLogLevel != LogLevel.None)
{
builder.AddFilter(null, configuration.MinimumLogLevel);
builder.SetMinimumLevel(configuration.MinimumLogLevel);
}
// else: no SetMinimumLevel call -> factory minimum stays at Information
});
...
}
When the factory is built lazily via `LoggerFactoryHolder.GetOrCreateFactory()`, the `configuration` passed in is the default `new PowertoolsLoggerConfiguration()` with `MinimumLogLevel = LogLevel.None`. Both branches above are skipped, so `Microsoft.Extensions.Logging`'s default factory minimum (Information) takes effect.
`PowertoolsLoggerProvider.ConfigureFromEnvironment()` then reads `POWERTOOLS_LOG_LEVEL` and updates the *provider*'s `MinimumLogLevel`, but the *factory*'s level filter has already been frozen. `ILogger.IsEnabled(LogLevel.Trace|Debug)` returns false at the factory level, so the call short-circuits before reaching `PowertoolsLogger.IsEnabledForConfig`.
Possible Solution
In LoggerFactoryHelper.CreateAndConfigureFactory, when MinimumLogLevel == None, force the factory minimum to LogLevel.Trace so every level reaches the provider. Let PowertoolsLoggerProvider / PowertoolsLogger.IsEnabledForConfig do the actual filtering using the env-var-derived level (which it already does correctly).
else if (configuration.MinimumLogLevel != LogLevel.None)
{
builder.AddFilter(null, configuration.MinimumLogLevel);
builder.SetMinimumLevel(configuration.MinimumLogLevel);
}
else
{
// Pass everything through; provider handles env-var-derived level
builder.AddFilter(null, LogLevel.Trace);
builder.SetMinimumLevel(LogLevel.Trace);
}
Alternative: read POWERTOOLS_LOG_LEVEL in LoggerFactoryHolder.GetOrCreateFactory() and apply it to config.MinimumLogLevel before calling CreateAndConfigureFactory, so the existing non-None branch runs.
Steps to Reproduce
- Deploy a Lambda using
AWS.Lambda.Powertools.Logging 3.2.1 with the handler above.
- Ensure
AWS_LAMBDA_LOG_LEVEL is unset on the function.
- Set
POWERTOOLS_LOG_LEVEL=Debug and invoke. CloudWatch shows no LEVELTEST debug line.
- Set
POWERTOOLS_LOG_LEVEL=Trace and invoke. CloudWatch shows neither LEVELTEST trace nor LEVELTEST debug.
- Set
POWERTOOLS_LOG_LEVEL=Information (or higher) and invoke. Behavior is correct from Information up.
Powertools for AWS Lambda (.NET) version
latest
AWS Lambda function runtime
dotnet8
Debugging logs
Expected Behaviour
Setting
POWERTOOLS_LOG_LEVEL=Traceshould cause every level (Trace, Debug, Information, Warning, Error, Critical) to emit.Setting
POWERTOOLS_LOG_LEVEL=Debugshould cause every level except Trace to emit.This should hold whether the logger is used via
Logger.LogTrace(...)/Logger.LogDebug(...)or viaLogger.Log(LogLevel.Trace, ...)/Logger.Log(LogLevel.Debug, ...).Current Behaviour
Trace and Debug calls are silently dropped regardless of the
POWERTOOLS_LOG_LEVELvalue. Information and above always emit. SettingPOWERTOOLS_LOG_LEVELto Information / Warning / Error / Critical correctly raises the floor; setting it below Information has no effect.Reproduced on
AWS.Lambda.Powertools.Logging3.2.1, dotnet8 Lambda, noAWS_LAMBDA_LOG_LEVELset, no explicitLogger.Configure(...)call.Test matrix output:
Code snippet
Possible Solution
In
LoggerFactoryHelper.CreateAndConfigureFactory, whenMinimumLogLevel == None, force the factory minimum toLogLevel.Traceso every level reaches the provider. LetPowertoolsLoggerProvider/PowertoolsLogger.IsEnabledForConfigdo the actual filtering using the env-var-derived level (which it already does correctly).Alternative: read
POWERTOOLS_LOG_LEVELinLoggerFactoryHolder.GetOrCreateFactory()and apply it toconfig.MinimumLogLevelbefore callingCreateAndConfigureFactory, so the existing non-None branch runs.Steps to Reproduce
AWS.Lambda.Powertools.Logging3.2.1 with the handler above.AWS_LAMBDA_LOG_LEVELis unset on the function.POWERTOOLS_LOG_LEVEL=Debugand invoke. CloudWatch shows noLEVELTEST debugline.POWERTOOLS_LOG_LEVEL=Traceand invoke. CloudWatch shows neitherLEVELTEST tracenorLEVELTEST debug.POWERTOOLS_LOG_LEVEL=Information(or higher) and invoke. Behavior is correct from Information up.Powertools for AWS Lambda (.NET) version
latest
AWS Lambda function runtime
dotnet8
Debugging logs