Notes on the argument passed to a lambda that is subscribed to a log group subscription

August 17, 2024

Input shape is { "awslogs" : { "data" : <String> }}

The data string is a base64 encoded of a gzipped JSON data. For example, if the data is in the file t, on the command line, you could extract the JSON like this:

base64 -d -i t | gunzip -c - | jq .

There is one such messages for each CloudWatch “log stream.”

Some background on CloudWatch log terminology, courtesy of Sandro Volpicella’s post on CloudWatch:

An example

The following Java lambda, subscribed to all events for a log group,

package echo;

import java.util.Map;

public final class Echo {

	public static Object handle(Object xs) {
		System.out.println("echo: " + xs.toString());
		return Map.of
			( "statusCode", 200
			, "headers", Map.of("Content-type", "text/plain")
			, "body", "OK"
			);
	}
}

logs the following event to it’s log group:

echo: {awslogs={data=H4sIAAAAAAAA/62TW08bMRCF/8rKqsTLJpkZX8bjtyDSCqnQKkn7QhDybhy0VW7d3UAp4r9XuSAoAqlIfbTneOacT+N7tUhNE6/T+G6dVFAn/XH/6mwwGvU/DVSuVrfLVKugGK03qMmwOJWr+er6U73arFVQvXjb9OZxUUxj7zq1i7tqvReM2jrFhQqKgEwPfA/5UXDx4XN/PBiNL723ZBkSoLcGUhG1YZmRj4BSsksqV82maMq6WrfVavmxmrepblS4UP35fHCTlm2jLnfTDodwca+qqQpKe2OMJnIM3hsvxAa1oNNI6DR7x5rZegcaUERrZiENTCpXbbVITRsXaxWQSQtosEBO54+oVFCn56fjq9G4Pxxnw81y+yL7nuqmWi1D9iPexEDYvSGYtC+qWX94HrJYL0O8bcIeW9g0nRSbtoMh1Ht5IHRiytIQFzbaacmFcGRxvkQdY1FKaZAlFTNHwGJLrcVH2QoK9qV1k6V6yF+i8AjstNYkjARIVoTAgREGcsaBA02ADkFYo7dvoWCC5ygOFNLPTWra02nIxMNsOk3S0X6WOsYjdwSg6ID4ON1SjgBPtA6r8LphtoRkvLNixBp2wCLOaBQHTNZuA7PzWjRqg/CGYQSQ54YPSxiyo9lqVcT6KM+O2HQdd5G7KLI9/0uGozx7goIaX40g4IzWlsQzedniR2GWHWhryLEF8uzYWUZn8a0IaP6KMDg/eS/x/+Durc/x0t1w8PXL+1di0p5s6tjulsKQ7zrJFs2kPa7m8zTNntf2hbO0WNV32aj6nUKG5LOz40l7Fn9lh8K3Ju0m7+5Pl1X7vIc1XQe7Nlsulw9/ANU3sU4HBQAA}}

Putting the value of awslogs.data into the file t, running the following command extracts the JSON:

# base64 -d -i t | gunzip -c - | jq .
{
  "messageType": "DATA_MESSAGE",
  "owner": "715841324796",
  "logGroup": "/aws/lambda/getmyip",
  "logStream": "2024/08/17/getmyip[$LATEST]8852570e018540eba3479f28a019c76e",
  "subscriptionFilters": [
    "AllEvents"
  ],
  "logEvents": [
    {
      "id": "38444322670884892741391631216378673775860301993377923072",
      "timestamp": 1723903050263,
      "message": "INIT_START Runtime Version: java:21.v20\tRuntime Version ARN: arn:aws:lambda:us-east-1::runtime:21694cc427b5a5dc7b97a7968c13aabc9c4179ebf620795c3398a97968b78c56\n"
    },
    {
      "id": "38444322681076333297120125992060497026460603201610973185",
      "timestamp": 1723903050720,
      "message": "START RequestId: 980fdde9-38fe-4817-900b-098ad9230a00 Version: $LATEST\n"
    },
    {
      "id": "38444322687521248659495476079964319607255979676839313410",
      "timestamp": 1723903051009,
      "message": "getmyip: 'foobar', '74.67.17.199', '980fdde9-38fe-4817-900b-098ad9230a00', 1723903050131\n"
    },
    {
      "id": "38444322690643352987289763319779320165426750287676571651",
      "timestamp": 1723903051149,
      "message": "END RequestId: 980fdde9-38fe-4817-900b-098ad9230a00\n"
    },
    {
      "id": "38444322690643352987289763319779320165426750287676571652",
      "timestamp": 1723903051149,
      "message": "REPORT RequestId: 980fdde9-38fe-4817-900b-098ad9230a00\tDuration: 428.69 ms\tBilled Duration: 429 ms\tMemory Size: 128 MB\tMax Memory Used: 98 MB\tInit Duration: 454.60 ms\t\n"
    }
  ]
}

Cloud Development Kit (CDK) code to set this up



        //
        //                  Define the echo lambda.
        //

        LogGroup lg = LogGroup.Builder.create(this, "EchoLogGroup")
            .logGroupName("/aws/lambda/echo")
            .retention(RetentionDays.FIVE_DAYS)
            .removalPolicy(RemovalPolicy.DESTROY)
            .build();

        Function f = Function.Builder.create(this, "EchoFunction")
            .functionName("echo")
            .runtime(Runtime.JAVA_21)
            .handler("echo.Echo::handle")
            .logGroup(lg)
            .code(Code.fromAsset("../target/echo.jar"))
            .build();

        //
        //                  Define the getmyip lambda.  (We will subscribe to this.)
        //

        LogGroup lg1 = LogGroup.Builder.create(this, "GetMyIpLogGroup")
            .logGroupName("/aws/lambda/getmyip")
            .retention(RetentionDays.FIVE_DAYS)
            .removalPolicy(RemovalPolicy.DESTROY)
            .build();
        
        Function f1 = Function.Builder.create(this, "GetMyIpFunction")
            .functionName("getmyip")
            .runtime(Runtime.JAVA_21)
            .handler("getmyip.GetMyIp::handle")
            .logGroup(lg1)
            .code(Code.fromAsset("../target/getmyip.jar"))
            .build();



        //
        //                  Subscribe echo to all getmyip events.
        //

        SubscriptionFilter.Builder.create(this, "Subscription")
            .logGroup(lg1)
            .destination(new LambdaDestination(f))
            .filterPattern(FilterPattern.allEvents())
            .filterName("AllEvents")
            .build();

Tags: aws lambda