Skip to content

Bug: Log messages not being output as structured content #932

@j-d-ha

Description

@j-d-ha

Expected Behaviour

When using the logger, the output should be just a JSON object containing the log message information. It should NOT have other info added to the front of the output before the JSON log message, such as a timestamp, trace ID, and log level.

As an example, this is what I would expect the log output to be:
Image

Current Behaviour

I am working with an executable assembly lambda and noticed some issues with logging. Here is my current setup:

  • Executable assembly lambda with top-level statements
  • Using HostApplicationBuilder with Powertools logger registered as singleton
  • Handler method on DI-registered service with injected logger
  • Service with handler is pulled from DI container and passed to LambdaBootstrapBuilder.Create() on startup

As part of my lambda setup, I am pulling the logger from the DI container after building the Host, and I am logging a startup message, which is properly formatted. Here is an example:
Image

When I invoke the lambda, the log message that the handler logs is getting improperly formatted. Rather than being only a JSON object, it's getting prefixed with timestamp, trace ID, and log level, just like I would expect if I had used Console.WriteLine() to output something.
Image

I ran some different tests and found the following:

  • If I don't pull out the logger from the DI container and log during startup, I don't see this issue.
  • If I switch the log type from Text to JSON, the message that's getting logged out is escaped JSON:
Image

Happy to provide any other info needed and run other tests!

Code snippet

using Amazon.Lambda.Core;
using Amazon.Lambda.RuntimeSupport;
using Amazon.Lambda.Serialization.SystemTextJson;
using AWS.Lambda.Powertools.Logging;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

var builder = Host.CreateApplicationBuilder();

builder.Services.AddSingleton<Service>();

builder.Services.AddSingleton<ILogger>(_ =>
    LoggerFactory
        .Create(options =>
            options.AddPowertoolsLogger(config => config.Service = "top-level-function-demo")
        )
        .CreatePowertoolsLogger()
);

var host = builder.Build();

var service = host.Services.GetRequiredService<Service>();

// comment out bellow to get expected behavior
var logger = host.Services.GetRequiredService<ILogger>();
logger.LogInformation("Starting lambda");

await LambdaBootstrapBuilder
    .Create(service.Handler, new DefaultLambdaJsonSerializer())
    .Build()
    .RunAsync();

public class Service
{
    private readonly ILogger _logger;

    public Service(ILogger logger)
    {
        _logger = logger;
    }

    public string Handler(ILambdaContext context)
    {
        var myMessage = new MyMessage("hello there!");
        _logger.LogInformation("This is a test message {@MyMessage}", myMessage);

        return "Hello world!";
    }

    private record MyMessage(string text);
}

Possible Solution

I believe this issue is related to the issue here.

Steps to Reproduce

  • Deploy the code added above as a lambda.
  • Invoke the lambda.
  • Check CloudWatch logs.
  • Comment out the code pulling the logger out of the DI container and logging on startup and redeploy the lambda.
  • Invoke the lambda.
  • Check cloud watch logs and messages should look as expected.

Powertools for AWS Lambda (.NET) version

AWS.Lambda.Powertools.Logging 2.0.0

AWS Lambda function runtime

dotnet8

Debugging logs

Metadata

Metadata

Assignees

Labels

area/loggingCore logging utilitybugUnexpected, reproducible and unintended software behaviourpending-releaseFix or implementation already in dev waiting to be released

Type

No type

Projects

Status

✅ Done

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions