Expected Behaviour
Pipe file descriptors to stdout should remain stable regardless of the number of log writes, as they do with AddLambdaLogger from Amazon.Lambda.Logging.AspNetCore.
Current Behaviour
Pipe FDs to the stdout pipe grow linearly with each ILogger log call and are never released. Under sustained load this exhausts the Lambda 1024 FD limit and crashes the function with "Too many open files".
Code snippet
// Registration in Startup.cs — this alone triggers the leak
services.AddLogging(logging =>
{
logging.ClearProviders();
logging.AddPowertoolsLogger(config =>
{
config.MinimumLogLevel = LogLevel.Information;
config.Service = "test-service";
});
});
// Middleware that logs per request and monitors FDs
public async Task InvokeAsync(HttpContext context)
{
_logger.LogInformation("Request: {Path}", context.Request.Path);
var entries = Directory.GetFiles("/proc/self/fd");
var targets = entries.Select(fd =>
{
try
{
var target = new FileInfo(fd).ResolveLinkTarget(true)?.FullName ?? "unknown";
return target;
}
catch { return "unresolvable"; }
}).ToList();
var pipeCount = targets.Count(t => t.Contains("pipe:"));
_logger.LogInformation("Open FDs: {Total}, Pipes: {Pipes}", entries.Length, pipeCount);
await _next(context);
}
Possible Solution
The leak appears to be somehow related to how Powertools writes to Console.Out. The writes seem to duplicate the stdout pipe FD without closing it. The other tested logger Amazon.Lambda.Logging.AspNetCore writes to the same stdout pipe without leaks, so the issue is most likely in this implementation.
Workaround: replace AddPowertoolsLogger with AddLambdaLogger:
services.AddLogging(logging =>
{
logging.ClearProviders();
logging.AddLambdaLogger(new LambdaLoggerOptions
{
IncludeCategory = true,
IncludeLogLevel = true,
IncludeNewline = true,
});
});
Steps to Reproduce
Steps to reproduce:
- Create an ASP.NET Core Lambda using APIGatewayProxyFunction base class
- Register AddPowertoolsLogger as the only logging provider to DI container (with ClearProviders() first)
- Inject ILogger into an API controller from the DI container
- Add middleware that logs on every request and counts /proc/self/fd entries (see code snippet above)
- Deploy to Lambda or run with SAM CLI local (--warm-containers EAGER to simulate warm containers)
- Send sustained traffic — e.g., 10 concurrent clients for 30+ seconds
- Observe pipe FD count growing linearly in the logs until it hits the 1024 limit
Environment:
- AWS.Lambda.Powertools.Logging: 3.1.0
- .NET 8 (dotnet8 Lambda runtime)
- Amazon.Lambda.AspNetCoreServer: 9.2.1
- SAM CLI with --warm-containers EAGER (Originally identified while running in a cloud Lambda, replicated in SAM CLI)
- The [Logging] attribute on the handler is NOT required to trigger the leak
Powertools for AWS Lambda (.NET) version
3.1.0
AWS Lambda function runtime
dotnet8
Debugging logs
FD snapshot after a 30s of concurrent requests in SAM (abbreviated, showing the leaking pipe):
Open file descriptors: 709, sources:
/proc/self/fd/pipe:[1625223] (328) <-- grows with every log write
/proc/self/fd/pipe:[1625281] (2) <-- stable (runtime pipes)
/proc/self/fd/pipe:[1625332] (2) <-- stable
/proc/self/fd/socket:[1625283] (1) <-- stable
... ~150 DLL mappings at 2 FDs each (stable)
Same workload with AddLambdaLogger:
Open file descriptors: 389, sources:
/proc/self/fd/pipe:[1630353] (6) <-- stable, does not grow
/proc/self/fd/pipe:[1617742] (2) <-- stable
... ~150 DLL mappings at 2 FDs each (stable)
Expected Behaviour
Pipe file descriptors to stdout should remain stable regardless of the number of log writes, as they do with AddLambdaLogger from Amazon.Lambda.Logging.AspNetCore.
Current Behaviour
Pipe FDs to the stdout pipe grow linearly with each ILogger log call and are never released. Under sustained load this exhausts the Lambda 1024 FD limit and crashes the function with "Too many open files".
Code snippet
Possible Solution
The leak appears to be somehow related to how Powertools writes to
Console.Out. The writes seem to duplicate the stdout pipe FD without closing it. The other tested loggerAmazon.Lambda.Logging.AspNetCorewrites to the same stdout pipe without leaks, so the issue is most likely in this implementation.Workaround: replace AddPowertoolsLogger with AddLambdaLogger:
Steps to Reproduce
Steps to reproduce:
Environment:
Powertools for AWS Lambda (.NET) version
3.1.0
AWS Lambda function runtime
dotnet8
Debugging logs