0
votes

I have a .NET Core 2 WebAPI application, running in AWS Lambda. I am using the Serilog AwsCloudWatch sink. I have also implemented middleware from the Datalust SerilogMiddleware example.

This all works perfectly from my development environment (logs are written to the correct CloudWatch Log Group). However, when the application runs in Lambda, no logging occurs. I have enabled Serilog SelfLog however there are no errors logged, so I don't believe it's an AWS credentials issue.

This is my logging configuration:

private Serilog.Core.Logger ConfigureLogger(IHostingEnvironment env)
{
    Serilog.Debugging.SelfLog.Enable(Console.Error);

    // Base configuration
    var logger = new LoggerConfiguration()
        .MinimumLevel.Override("Microsoft", LogEventLevel.Warning)
        .MinimumLevel.Override("System", LogEventLevel.Warning)
        .Enrich.FromLogContext()
        .Enrich.WithMachineName()
        .Enrich.WithThreadId();

    // Configure Sink: AWS CloudWatch
    var cloudWatchLogsClient = new AmazonCloudWatchLogsClient("ACCESS_KEY_ID", "SECRET_ACCESS_KEY",                                                                   RegionEndpoint.GetBySystemName(awsConfig.CloudWatchRegion));
    var logLevel = env.IsProduction() ? LogEventLevel.Information : LogEventLevel.Debug;
    logger.WriteTo.AmazonCloudWatch(new CloudWatchLogSinkOptions(env, logLevel), cloudWatchLogsClient);

    // Configure Sink: Console (only for Debug environment)
    if (env.IsDebug())
    {
        logger.WriteTo.Console(LogEventLevel.Debug);
    }

    return logger.CreateLogger();
}

This is the implementation of CloudWatchSinkOptions:

   public class CloudWatchLogSinkOptions : ICloudWatchSinkOptions
    {
        public CloudWatchLogSinkOptions(IHostingEnvironment env, LogEventLevel level = LogEventLevel.Information)
        {
            LogGroupName += env.EnvironmentName;
            MinimumLogEventLevel = level;
        }

        #region Settings

        public LogEventLevel MinimumLogEventLevel { get; set; }
        public int BatchSizeLimit { get; set; } = 100;
        public TimeSpan Period { get; set; } = TimeSpan.FromSeconds(10);
        public LogGroupRetentionPolicy LogGroupRetentionPolicy { get; set; } = LogGroupRetentionPolicy.OneYear;
        public bool CreateLogGroup { get; set; } = true;
        public string LogGroupName { get; set; } = "WebApi-ApplicationLog/";
        public ILogStreamNameProvider LogStreamNameProvider { get; set; } = new DefaultLogStreamProvider();
        public ITextFormatter TextFormatter { get; set; }= new SerilogTextFormatter();
        public byte RetryAttempts { get; set; } = 5;
        public int QueueSizeLimit { get; set; }

        #endregion


        #region Defaults

        public const LogEventLevel DefaultMinimumLogEventLevel = LogEventLevel.Information;
        public const int DefaultBatchSizeLimit = 100;
        public const bool DefaultCreateLogGroup = true;
        public const byte DefaultRetryAttempts = 5;
        public static readonly TimeSpan DefaultPeriod = TimeSpan.FromSeconds(10);

        #endregion

    }

I believe I have included all required Serilog packages:

enter image description here

And finally, I have provided Lambda with the appropriate access to CloudWatch Logs:

enter image description here

I'm not sure where to go from here. As I stated previously, this works great from by dev (Debug) environment. It just doesn't work from Lambda, and SelfLog produces no error output.

Anyone have some suggestions to resolve this? I appreciate the help!

1

1 Answers

0
votes

I'm actually looking for information myself, so I have no answer, but I suspect it makes sense that this only works locally, since the LambdaEntryPoint only calls the Startup class, it won't actually call the ConfigureLogging function as that is chained to the HostBuilder rather than called from inside Startup like we did back in the day for .NET Core 1.x.

I was wondering about this myself and I have no answer yet for how to actually do it though.