Open hjgraca opened 1 year ago
@hjgraca PR raised for the first pass on native AOT support. I expect this will need some discussion, especially around logging. We can't easily support Exceptions in their entirety, byte[], streams or any anoymous types. Some of the unit tests will fail based on this missing functionality but I thought I would leave it that way as a means of discussion
https://github.com/aws-powertools/powertools-lambda-dotnet/pull/341
The crux of the work is adding a new IPowerToolsSerializer, initially with 2 implementations. A default one that uses System.Text.Json, and then a source genereted one that allows users to add a custom serialization context.
This is the same way it works for the Lambda runtime itself.
We have released alpha versions for Logging and Metrics. They are now available to download from Nuget.
These are very early release versions and not recommended for production workloads, we have done our best to support all features, but you will see some warnings when trimming for AOT deployment.
We are using .NET8 AOT based lambda in development at the moment with the 1.6.0-alpha version of the PowerTools logging. We are due to go to production in around 4-6 weeks time. Do you have plans to release a production ready version of PowerTools logging with AOT support?
Hi @andy-potter-evotix thanks for using Powertools, the full support of AOT is top priority and we are working as fast as we can to ship it as soon as possible, unfortunately I cannot guarantee delivery dates, but in the next weeks we will be releasing another alpha and more stable versions. Hopefully we can get something by that time that we are confident that can go to production. Keep an eye on this issue we will update whenever we have news. If you want to reach us directly use can use the email aws-lambda-powertools-feedback@amazon.com
Again thanks for using Powertools 👍
@hjgraca I wanted to confirm - Is the Logging/Metric support for trimming officially completed/supported? I'm having some issue getting it working on my end even with the recommended changes.
@Euclidite yes it is implemented in both Logging and Metrics, Logging > 1.6.0 and Metrics > 1.7.1. What is the issue/erro you are seeing?
Here's the exception I get in the logs (which is telling me "I didn't configure something right"):
10-Oct-2024 9:34:07 AM 2024-10-10T13:34:07.448Z 9bc362e6-76bc-4f22-b004-8c5622ca8078 fail System.InvalidOperationException: Reflection-based serialization has been disabled for this application. Either use the source generator APIs or explicitly configure the 'JsonSerializerOptions.TypeInfoResolver' property.
at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_JsonSerializerIsReflectionDisabled()
at System.Text.Json.JsonSerializerOptions.ConfigureForJsonSerializer()
at System.Text.Json.JsonSerializer.GetTypeInfo(JsonSerializerOptions, Type)
at System.Text.Json.JsonSerializer.GetTypeInfo[T](JsonSerializerOptions)
at System.Text.Json.JsonSerializer.Serialize[TValue](TValue, JsonSerializerOptions )
at AWS.Lambda.Powertools.Logging.Serializers.PowertoolsLoggingSerializer.Serialize(Object, Type)
at AWS.Lambda.Powertools.Logging.Internal.PowertoolsLogger.Log[TState](LogLevel, EventId, TState, Exception, Func`3)
at Microsoft.Extensions.Logging.LoggerExtensions.Log(ILogger , LogLevel, EventId, Exception, String, Object[] )
at Microsoft.Extensions.Logging.LoggerExtensions.LogInformation(ILogger, String , Object[] )
at submit_feedback.Function.FunctionHandlerAsync(SubmitFeedbackRequest request, ILambdaContext context) in ./Function.cs:line 63
at Amazon.Lambda.RuntimeSupport.HandlerWrapper.<>c__DisplayClass14_0`1.<<GetHandlerWrapper>b__0>d.MoveNext()
--- End of stack trace from previous location ---
at Amazon.Lambda.RuntimeSupport.LambdaBootstrap.InvokeOnceAsync(CancellationToken )
Here are the relevant lines of what I have in my csproj file (Let me know if you need more context):
<PropertyGroup>
<PublishReadyToRun>true</PublishReadyToRun>
<StripSymbols>true</StripSymbols>
<PublishTrimmed>true</PublishTrimmed>
<TrimMode>partial</TrimMode>
</PropertyGroup>
<ItemGroup>
<!-- Exclude EF Core assemblies from being trimmed (not supported) -->
<TrimmerRootAssembly Include="Microsoft.EntityFrameworkCore" />
<TrimmerRootAssembly Include="Microsoft.EntityFrameworkCore.Relational" />
<TrimmerRootAssembly Include="Npgsql.EntityFrameworkCore.PostgreSQL" />
<TrimmerRootAssembly Include="EFCore.NamingConventions" />
</ItemGroup>
And here's how I've been able to minimally reproduce this:
public class Function
{
private static async Task Main()
{
await LambdaBootstrapBuilder.Create<SubmitFeedbackRequest>(
FunctionHandlerAsync,
new PowertoolsSourceGeneratorSerializer<LambdaFunctionJsonContext>())
.Build()
.RunAsync();
}
[Logging]
public static async Task FunctionHandlerAsync(SubmitFeedbackRequest request, ILambdaContext context)
{
Logger.LogInformation("Starting up!");
}
}
[JsonSerializable(typeof(SubmitFeedbackRequest))]
public partial class LambdaFunctionJsonContext : JsonSerializerContext { }
For reference, here are my package versions:
Not sure if it makes a difference but I usually build the handler in the main like so.
Func< SubmitFeedbackRequest, ILambdaContext, Task> handler = FunctionHandler;
await LambdaBootstrapBuilder.Create(handler, new PowertoolsSourceGeneratorSerializer< LambdaFunctionJsonContext >())
.Build()
.RunAsync();
I've updated my main to this:
private static async Task Main()
{
Console.WriteLine("Starting up");
Func<SubmitFeedbackRequest, ILambdaContext, Task> handler = FunctionHandlerAsync;
await LambdaBootstrapBuilder.Create(handler, new PowertoolsSourceGeneratorSerializer<LambdaFunctionJsonContext>())
.Build()
.RunAsync();
Console.WriteLine("Shutting down");
}
Unfortunately, I still get the same exception logged.
Let me know if you'd like a new ticket, or if you want to dig into it a bit first 🙂
Please open an issue, from my initial tests is because the Lambda is not returning any values. Thank you!
Use case
Historically, .NET Lambda functions have cold-start times which impact user experience, system latency, and usage costs of your serverless applications. With .NET 8, Microsoft adds support for Native AOT compilation, which speeds up performance by compiling .NET code directly to machine and operating system native code, eliminating Just-in-Time (JIT) compiling at runtime. With .NET 8 Native AOT compilation, you can improve cold-start times of your Lambda functions. To learn more about Native AOT for .NET 8, see Using Native AOT in the Dotnet GitHub repository.
Solution/User Experience
Currently Native AOT is supported in .NET 8 but only a limited number of libraries are fully compatible with native AOT in .NET 8. Lambda Powertools is not fully compatible with native AOT because of some libraries it uses (for example System.Text.Json.Serializer) which is not supported in native AOT
Proposal
All the work for this release will happen in a separate branch
aot-support
, this will allow us to publish alpha releases to Nuget. This will allow customers to get early access to the new features and optionally start applying the required changes or simply give feedback on the new items.Quick summary
The work for AOT support will be done in multiple phases beginning on supporting Logging and Metrics and continuing to the remaining utilities. We believe these two utilities will have the most work and that is the reason we are starting from there.
Legend for
Status
column:Potential challenges
Tackling AOT trim warnings will be the most time consuming tasks, for this reason if some unforeseen blocker comes up we might decide to reprioritize and exclude some issues from the milestone.
Acknowledgment