Search code examples
c#amazon-web-servicesaws-lambdaamazon-snscloudevents

AWS Lambda triggered by CloudWatch Log Event not receiving event object properly


I'm new to AWS. I'm writing a lambda function in C# to monitor the failed delivery of SNS messages. I encountered an issue where the first parameter passed to the FunctionHandler is empty (not null, but all its fields, like DetailType, Region, Source, Id, etc. are null).

Following is my code:

namespace SnsLogProcessor 
{

    public class EventConfig
    {
        public string TopicArn { get; set; }
        public string status { get; set; }
    }

    public void FunctionHandler(CloudWatchEvent<EventConfig> evnt, ILambdaContext context)
    {
        if (evnt != null)
        {
            if (context != null)
            {
                context.Logger.LogInformation($"Lambda triggered!");
                context.Logger.LogInformation(evnt.DetailType);
                context.Logger.LogInformation(evnt.Region);
                context.Logger.LogInformation(evnt.Source);
                context.Logger.LogInformation(evnt.Id);
                context.Logger.LogInformation(evnt.Version);
                context.Logger.LogInformation(evnt.Account);

                if (evnt.Detail != null)
                {
                    string status = evnt.Detail.status;

                    if (!string.IsNullOrEmpty(status))
                        context.Logger.LogInformation(status);
                    else context.Logger.LogInformation($"Not found.");
                }
                else context.Logger.LogInformation(evnt.ToString());
            }
        }
    }
}

And following is the output from the function after triggered:

2024-01-24T13:18:01.725-06:00 START RequestId: f24f25e6-10b3-4b63-be75-ae3174bdab70 Version: $LATEST
2024-01-24T13:18:02.106-06:00   2024-01-24T19:18:02.083Z f24f25e6-10b3-4b63-be75-ae3174bdab70 info Lambda triggered!
2024-01-24T13:18:02.107-06:00   2024-01-24T19:18:02.107Z f24f25e6-10b3-4b63-be75-ae3174bdab70 info
2024-01-24T13:18:02.107-06:00   2024-01-24T19:18:02.107Z f24f25e6-10b3-4b63-be75-ae3174bdab70 info
2024-01-24T13:18:02.107-06:00   2024-01-24T19:18:02.107Z f24f25e6-10b3-4b63-be75-ae3174bdab70 info
2024-01-24T13:18:02.107-06:00   2024-01-24T19:18:02.107Z f24f25e6-10b3-4b63-be75-ae3174bdab70 info
2024-01-24T13:18:02.107-06:00   2024-01-24T19:18:02.107Z f24f25e6-10b3-4b63-be75-ae3174bdab70 info
2024-01-24T13:18:02.107-06:00   2024-01-24T19:18:02.107Z f24f25e6-10b3-4b63-be75-ae3174bdab70 info
2024-01-24T13:18:02.107-06:00   2024-01-24T19:18:02.107Z f24f25e6-10b3-4b63-be75-ae3174bdab70 info Amazon.Lambda.CloudWatchEvents.CloudWatchEvent`1[SnsLogProcessor.EventConfig]
2024-01-24T13:18:02.164-06:00   END RequestId: f24f25e6-10b3-4b63-be75-ae3174bdab70 

I tried the code on live AWS environment and got above results. I verified my account, and the function I created, have all the permission for logs. As you can see, all the fields of the event object, including DetailType, Region, etc. are null. Thank you so very much for reading this! Any help would be greatly appreciated!


Solution

  • Your lambda is not listening to CloudWatch Events, it's listening to a CloudWatch log group. They are completely different things. The former is known as EventBridge Events these days.

    CloudWatch log stream events have this shape:

    {
        "awslogs": {
            "data": "base64-encoded gzipped JSON with log message"
        }
    }
    

    You should use the type CloudWatchLogsEvent to deserialize it:

    public async Task FunctionHandler(CloudWatchLogsEvent evnt, ILambdaContext context)
    {
        await Console.Out.WriteLineAsync(evnt.Awslogs.DecodeData());
    }