-
Notifications
You must be signed in to change notification settings - Fork 478
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lambda Structured Logging Support #1747
Comments
Some other requirements for production-ready structured logging support:
|
I haven't specifically played with the new capabilities yet, but I have updated an existing lambda using .NET 8 with AoT where I use .NET's own built-in ILC : AOT analysis warning IL3050: Amazon.Lambda.RuntimeSupport.Helpers.Logging.JsonLogMessageFormatter.FormatJsonValue(Utf8JsonWriter,Object,String,MessageProperty.Directive): Using member 'System.Text.Json.JsonSerializer.Serialize<Object>(Object,JsonSerializerOptions)' which has 'RequiresDynamicCodeAttribute' can break functionality when AOT compiling. JSON serialization and deserialization might require types that cannot be statically analyzed and might need runtime code generation. Use System.Text.Json source generation for native AOT applications. [/home/runner/work/alexa-london-travel/alexa-london-travel/src/LondonTravel.Skill/LondonTravel.Skill.csproj] This is with the |
Thanks @martincostello, I'll take a look to see what we need to do. |
It would be very useful to have consistent logging between lambda startup logs and .NET ILogger logs (Microsoft.Extensions.Logging). |
@martincostello Sorry for the delay but I put out a PR to address the Native AOT warning. #1795 |
Update the packages have been release as GA and can be used for executable assembly Lambda functions today if you reference version |
Will destructuring an object using the As a motivating example, we often want to log a complex AWS object such as an SQSEvent.SQSMessage. However, we don't want to log all the properties - just a handful like the A good implementation is found in Serilog, which supports either attributing the properties on your classes, or defining a destructuring function when creating the logger. Another interesting implementation is to support a richer destructuring syntax, e.g.: logger.Log("Message received: {@TheMessage(MessageId, EventSourceArn)}", message); Note that this isn't an essential feature - it can be implemented by creating a "loggable" version of an object using an extension method or wrapper class, for example: public static object ToLoggable(this SQSEvent.SQSMessage message) => new
{
// Use a property as-is
message.MessageArn,
// Rename a property
TheIdOfTheMessage = message.MessageId,
// Construct a brand new property
MessageLength = message.Body?.Length ?? 0
} However, discoverability and ease-of-use both suffer with this approach. |
@RowlandBanks The JSON serialization is using System.Text.Json so you can use the attributes for System.Text.Json to control what to included. For example this public class User
{
public string? Name { get; set; }
[JsonIgnore]
public string? Password { get; set; }
public override string ToString()
{
return Name ?? "Noname";
}
} |
Is this logger functionality actually tied to lambda in any way? |
@Dreamescaper This an expansion of the |
I'm still waiting on the Lambda deployment for the managed runtime for the class library programming model to have access structured logging. It is the busy time of year and deployments get backed up. I did push out version 5.11.0 of Amazon.Lambda.Tools that has new switches for the |
Hey 👋🏻 (I realise I'm late to the party here :S) |
What features are you thinking for enriching? The challenging working at the Amazon.LambdaRuntimeSupport level is we have to keep it lean for cold start performance reasons and avoid any conflicts with dependencies brought in by the Lambda function. This means we can't take on dependencies like Microsoft.Extensions.Logging. |
That makes sense 👍🏻, thanks. The specific things I was thinking of was being able to add log properties for the whole scope of an invocation (request ID, user ID etc). As well as being able to flush logs only on error. Maybe both could be implemented without taking any other dependencies, but might not be worth it - I imagine that once consumers start getting past logging single lines they may already have other libs installed? |
Lambda Structured Logging Support
Status (September 5th, 2024)
Version 1.11.0 of
Amazon.Lambda.RuntimeSupport
and 2.3.0 ofAmazon.Lambda.Core
have been released with structured logging support. Lambda functions as .NET class libraries requiring the managed runtime to be updated with the new version of Amazon.Lambda.RuntimeSupport which is pending a deployment. Executable Lambda functions can get started with structured logging support but need to add<EnablePreviewFeatures>true</EnablePreviewFeatures>
to the csproj file to access the new parameterized logging API inAmazon.Lambda.Core
. Once the .NET managed runtime has been update a new version ofAmazon.Lambda.Core
will be release removing the preview flag for the logging APIs.The new logging APIs
As part of the effort to support JSON logging, new parameterized logging methods have been added to Amazon.Lambda.Core. These new APIs are the ones marked as preview, requiring the
EnablePreviewFeatures
property to be set. This will be required until the new version of Amazon.Lambda.RuntimeSupport has been deployed to the managed runtime for class-library-based Lambda functions. These new logging APIs will also function for the existing Text logging mode providing the string replacement.The following code shows the handler in the project using the parameterized logging to log the input property.
The parameterized logging statement will produce the following JSON, adding the parameters to the log statement as properties of the JSON logging.
Following the pattern of other logging libraries, exceptions can also be passed in for logging. For example, the following code will throw an exception if the input is equal to “fail”.
This produces the following JSON.
Serialization options
Formatting scalers: When using scalars like integers and doubles as logging parameters, the format can be customized by providing a format string using a suffix on the parameter name. For example,
The string after the colon in {cost:0.00} is the same as the formatString used in .NET’s composite formatting. The code above produces the following JSON logging statement.
Custom types: When using instances of custom types as parameters to logging, the ToString method is used as the value for the property. If the @ prefix is used, the object will be serialized into the JSON logging statement. For example, the code below:
Produce the following JSON document:
Collections: When using lists and dictionaries as parameters, the items in the collections are written to the JSON log using the
ToString
method. The@
prefix can be used to indicate that the items should be serialized into the JSON log message.Example JSON using
ToString
:Example JSON using serialization:
The text was updated successfully, but these errors were encountered: