Format of JSON not as expected
Expected Behaviour
For an object Person, that has an Address I expect to see it logged like this -
When logging using Logger.LogInformation<Person>(person, "{Name} and is {Age} years old", new object[]{person.Name, person.Age}); I expect the output to look like -
"person": {
"name": "Alan Adams",
"age": 11,
"address": {
"street": "123 Main Street",
"city": "Boston"
}
},
Current Behaviour
Instead the output is -
"name": "Alan Adams",
"age": 11,
"address": {
"street": "123 Main Street",
"city": "Boston"
},
Person is lost.
Code snippet
using Amazon.Lambda.Core;
using AWS.Lambda.Powertools.Logging;
// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class.
[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer))]
namespace ThreeSimpleWaysToLog;
public class Function
{
[Logging(LogEvent = true, LoggerOutputCase = LoggerOutputCase.CamelCase)]
public void FunctionHandler(string input, ILambdaContext context)
{
Person person = new Person { Name ="Alan Adams", Age = 11, Address = new Address{ Street = "123 Main Street", City ="Boston" } };
Logger.LogInformation<Person>(person, "{Name} and is {Age} years old", new object[]{person.Name, person.Age});
}
}
public class Person
{
public string Name {get ; set;}
public int Age { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
}
Possible Solution
I would expect the log out to look the same as it does when using like this -
Logger.AppendKey("Person", person);
Logger.LogInformation("{Name} and is {Age} years old", new object[]{person.Name, person.Age});
Logger.RemoveKeys("Person");
The output from this is -
{
"coldStart": true,
"xrayTraceId": "1-642b077d-0e615d154a66119a5585838b",
"person": {
"name": "Alan Adams",
"age": 11,
"address": {
"street": "123 Main Street",
"city": "Boston"
}
},
"functionName": "ThreeSimpleWaysToLog",
"functionVersion": "$LATEST",
"functionMemorySize": 256,
"functionArn": "arn:aws:lambda:us-east-1:694977046108:function:ThreeSimpleWaysToLog",
"functionRequestId": "5bf50f21-2c0e-4327-82df-fd0939bf6aa5",
"timestamp": "2023-04-03T17:06:07.0296164Z",
"level": "Information",
"service": "ThreeSimpleWaysToLog",
"name": "AWS.Lambda.Powertools.Logging.Logger",
"message": "Alan Adams and is 11 years old"
}
The Person is clearly shown.
Steps to Reproduce
Deploy the code provided and invoke.
AWS Lambda Powertools for .NET version
latest
AWS Lambda function runtime
dotnet6
Debugging logs
No response
@bjhogan thanks for reporting. Having a look
Related to #116
Hi @bjhogan, thanks for opening the issue. The extraKeys parameter in Logger.LogInformation(extraKeys, "message"), expect dictionary or a list of key/value pairs. So the object also be treated as a bag of key/value pair and will be logged in the root level. You can pass "person" object as value in combination with the key name to achieve the desired outcome.
var extraKeys = new { Person = person };
Logger.LogInformation(extraKeys, $"{person.Name} and is {person.Age} years old");
On a separate notes, we have already another issue https://github.com/awslabs/aws-lambda-powertools-dotnet/issues/166 to improve the documentation.