From c12ff99edf7099d374cea12764280abc8bfcb623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Wrzeszcz?= Date: Mon, 29 Jul 2019 11:43:32 +0200 Subject: [PATCH] DynamoDB custom metrics generator. --- README.md | 4 + .../lambda-metrics-dynamodb/pom.xml | 104 +++++++++++++ .../src/main/checkstyle/java.header | 8 + .../lambda/metrics/dynamodb/Handler.java | 81 +++++++++++ .../dynamodb/model/TableMetricRequest.java | 21 +++ .../CloudWatchDynamoDbMetricGenerator.java | 96 ++++++++++++ .../src/main/resources/logback.xml | 29 ++++ .../src/site/markdown/guide/usage.md | 123 ++++++++++++++++ .../lambda-metrics-dynamodb/src/site/site.xml | 23 +++ .../lambda/metrics/dynamodb/HandlerTest.java | 85 +++++++++++ ...CloudWatchDynamoDbMetricGeneratorTest.java | 137 ++++++++++++++++++ lambda-metrics/pom.xml | 36 +++++ .../src/main/checkstyle/java.header | 8 + lambda-metrics/src/site/site.xml | 19 +++ pom.xml | 1 + 15 files changed, 775 insertions(+) create mode 100644 lambda-metrics/lambda-metrics-dynamodb/pom.xml create mode 100644 lambda-metrics/lambda-metrics-dynamodb/src/main/checkstyle/java.header create mode 100644 lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/Handler.java create mode 100644 lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/model/TableMetricRequest.java create mode 100644 lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/service/CloudWatchDynamoDbMetricGenerator.java create mode 100644 lambda-metrics/lambda-metrics-dynamodb/src/main/resources/logback.xml create mode 100644 lambda-metrics/lambda-metrics-dynamodb/src/site/markdown/guide/usage.md create mode 100644 lambda-metrics/lambda-metrics-dynamodb/src/site/site.xml create mode 100644 lambda-metrics/lambda-metrics-dynamodb/src/test/java/test/pl/wrzasq/lambda/metrics/dynamodb/HandlerTest.java create mode 100644 lambda-metrics/lambda-metrics-dynamodb/src/test/java/test/pl/wrzasq/lambda/metrics/dynamodb/service/CloudWatchDynamoDbMetricGeneratorTest.java create mode 100644 lambda-metrics/pom.xml create mode 100644 lambda-metrics/src/main/checkstyle/java.header create mode 100644 lambda-metrics/src/site/site.xml diff --git a/README.md b/README.md index fc2dbc49a..1360de2b9 100644 --- a/README.md +++ b/README.md @@ -63,6 +63,10 @@ resource. **CloudFormation** custom resource handler for setting log retention for **CloudWatch** log groups. +## [Lambda-Metrics DynamoDb](https://rafalwrzeszcz-wrzasqpl.github.io/pl.wrzasq.lambda/lambda-metrics/lambda-metrics-dynamodb/) + +**CloudWatch** custom metrics for **DynamoDb**. + # Resources - [GitHub page with API documentation](https://rafalwrzeszcz-wrzasqpl.github.io/pl.wrzasq.lambda) diff --git a/lambda-metrics/lambda-metrics-dynamodb/pom.xml b/lambda-metrics/lambda-metrics-dynamodb/pom.xml new file mode 100644 index 000000000..27a3530a3 --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/pom.xml @@ -0,0 +1,104 @@ + + + + 4.0.0 + + + lambda-metrics-dynamodb + jar + + pl.wrzasq.lambda + lambda-metrics + 1.0.31-SNAPSHOT + ../ + + + + WrzasqPl CloudWatch DynamoDb metrics + https://rafalwrzeszcz-wrzasqpl.github.io/pl.wrzasq.lambda/lambda-metrics/lambda-metrics-dynamodb/ + DynamoDb additional CloudWatch metrics. + 2019 + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + com.amazonaws:aws-xray-recorder-sdk-aws-sdk + com.amazonaws:aws-xray-recorder-sdk-aws-sdk-instrumentor + io.symphonia:lambda-logging + + + + + + org.apache.maven.plugins + maven-shade-plugin + + + + + + + + ${project.groupId} + lambda-json + ${project.version} + + + + com.amazonaws + aws-java-sdk-cloudwatch + 1.11.588 + + + + com.amazonaws + aws-java-sdk-dynamodb + 1.11.588 + + + + com.amazonaws + aws-xray-recorder-sdk-aws-sdk + 2.2.1 + + + + com.amazonaws + aws-xray-recorder-sdk-aws-sdk-instrumentor + 2.2.1 + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.9.1 + + + + io.symphonia + lambda-logging + 1.0.3 + + + + org.slf4j + slf4j-api + 1.7.26 + + + diff --git a/lambda-metrics/lambda-metrics-dynamodb/src/main/checkstyle/java.header b/lambda-metrics/lambda-metrics-dynamodb/src/main/checkstyle/java.header new file mode 100644 index 000000000..d3f4fc280 --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/src/main/checkstyle/java.header @@ -0,0 +1,8 @@ +^/\*$ +^ \* This file is part of the pl\.wrzasq\.lambda\.$ +^ \*$ +^ \* @license http://mit-license\.org/ The MIT license$ +^ \* @copyright \d{4}[0-9, -]* © by Rafał Wrzeszcz - Wrzasq\.pl\.$ +^ \*/$ + +^package pl\.wrzasq\.lambda\.metrics\.dynamodb(\..+)?;$ diff --git a/lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/Handler.java b/lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/Handler.java new file mode 100644 index 000000000..e64a86040 --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/Handler.java @@ -0,0 +1,81 @@ +/* + * This file is part of the pl.wrzasq.lambda. + * + * @license http://mit-license.org/ The MIT license + * @copyright 2019 © by Rafał Wrzeszcz - Wrzasq.pl. + */ + +package pl.wrzasq.lambda.metrics.dynamodb; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import com.amazonaws.services.cloudwatch.AmazonCloudWatchClientBuilder; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDBClientBuilder; +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.AllArgsConstructor; +import pl.wrzasq.lambda.json.ObjectMapperFactory; +import pl.wrzasq.lambda.metrics.dynamodb.model.TableMetricRequest; +import pl.wrzasq.lambda.metrics.dynamodb.service.CloudWatchDynamoDbMetricGenerator; + +/** + * CloudWatch Events request handler. + * + *

Required environment variables:

+ * + *
+ *
METRICS_NAMESPACE
+ *
Namespace to use for CloudWatch metrics.
+ *
+ * + *

Recommended memory: 256MB.

+ */ +@AllArgsConstructor +public class Handler { + /** + * Metrics namespace to use. + */ + private static final String METRICS_NAMESPACE = System.getenv("METRICS_NAMESPACE"); + + /** + * JSON handler. + */ + private ObjectMapper objectMapper; + + /** + * DynamoDB metrics generator. + */ + private CloudWatchDynamoDbMetricGenerator metricGenerator; + + /** + * Default constructure. + */ + public Handler() { + this( + ObjectMapperFactory.createObjectMapper(), + new CloudWatchDynamoDbMetricGenerator( + AmazonDynamoDBClientBuilder.standard().build(), + AmazonCloudWatchClientBuilder.standard().build(), + Handler.METRICS_NAMESPACE + ) + ); + } + + /** + * Handles invocation. + * + * @param inputStream Request input. + * @param outputStream Output stream. + * @throws IOException When JSON loading/dumping fails. + */ + public void handle(InputStream inputStream, OutputStream outputStream) throws IOException { + try { + TableMetricRequest request = this.objectMapper.readValue(inputStream, TableMetricRequest.class); + + this.metricGenerator.generateMetrics(request.getTableName()); + } finally { + outputStream.close(); + } + } +} diff --git a/lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/model/TableMetricRequest.java b/lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/model/TableMetricRequest.java new file mode 100644 index 000000000..4a3e39920 --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/model/TableMetricRequest.java @@ -0,0 +1,21 @@ +/* + * This file is part of the pl.wrzasq.lambda. + * + * @license http://mit-license.org/ The MIT license + * @copyright 2019 © by Rafał Wrzeszcz - Wrzasq.pl. + */ + +package pl.wrzasq.lambda.metrics.dynamodb.model; + +import lombok.Data; + +/** + * Request specifying subject table. + */ +@Data +public class TableMetricRequest { + /** + * DynamoDb table name. + */ + private String tableName; +} diff --git a/lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/service/CloudWatchDynamoDbMetricGenerator.java b/lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/service/CloudWatchDynamoDbMetricGenerator.java new file mode 100644 index 000000000..b95d8f6c8 --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/src/main/java/pl/wrzasq/lambda/metrics/dynamodb/service/CloudWatchDynamoDbMetricGenerator.java @@ -0,0 +1,96 @@ +/* + * This file is part of the pl.wrzasq.lambda. + * + * @license http://mit-license.org/ The MIT license + * @copyright 2019 © by Rafał Wrzeszcz - Wrzasq.pl. + */ + +package pl.wrzasq.lambda.metrics.dynamodb.service; + +import com.amazonaws.services.cloudwatch.AmazonCloudWatch; +import com.amazonaws.services.cloudwatch.model.Dimension; +import com.amazonaws.services.cloudwatch.model.MetricDatum; +import com.amazonaws.services.cloudwatch.model.PutMetricDataRequest; +import com.amazonaws.services.cloudwatch.model.StandardUnit; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.model.TableDescription; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * CloudWatch metrics handler. + */ +public class CloudWatchDynamoDbMetricGenerator { + /** + * Logger. + */ + private Logger logger = LoggerFactory.getLogger(CloudWatchDynamoDbMetricGenerator.class); + + /** + * AWS DynamoDB client. + */ + private AmazonDynamoDB dynamoDb; + + /** + * AWS CloudWatch client. + */ + private AmazonCloudWatch cloudWatch; + + /** + * Metrics namespace to use. + */ + private String namespace; + + /** + * Initializes object. + * + * @param dynamoDb DynamoDB client. + * @param cloudWatch CloudWatch client. + * @param namespace Metrics namespace. + */ + public CloudWatchDynamoDbMetricGenerator(AmazonDynamoDB dynamoDb, AmazonCloudWatch cloudWatch, String namespace) { + this.dynamoDb = dynamoDb; + this.cloudWatch = cloudWatch; + this.namespace = namespace; + } + + /** + * Table metrics generator. + * + * @param tableName Table name. + */ + public void generateMetrics(String tableName) { + this.logger.info("Generating metrics for table: {}.", tableName); + + TableDescription table = this.dynamoDb.describeTable(tableName).getTable(); + + this.putSingleMetric(tableName, "ItemCount", table.getItemCount(), StandardUnit.None); + this.putSingleMetric(tableName, "TableSizeBytes", table.getTableSizeBytes(), StandardUnit.Bytes); + } + + /** + * Saves single metric value in CloudWatch. + * + * @param tableName DynamoDB table name. + * @param metricName Metric name. + * @param value Metric value. + * @param unit Metric unit. + */ + private void putSingleMetric(String tableName, String metricName, double value, StandardUnit unit) { + this.cloudWatch.putMetricData( + new PutMetricDataRequest() + .withNamespace(this.namespace) + .withMetricData( + new MetricDatum() + .withMetricName(metricName) + .withValue(value) + .withUnit(unit) + .withDimensions( + new Dimension() + .withName("TableName") + .withValue(tableName) + ) + ) + ); + } +} diff --git a/lambda-metrics/lambda-metrics-dynamodb/src/main/resources/logback.xml b/lambda-metrics/lambda-metrics-dynamodb/src/main/resources/logback.xml new file mode 100644 index 000000000..27f1ea8bc --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/src/main/resources/logback.xml @@ -0,0 +1,29 @@ + + + + + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n%ex{full} + + + + + + + + + + + + + + + + + diff --git a/lambda-metrics/lambda-metrics-dynamodb/src/site/markdown/guide/usage.md b/lambda-metrics/lambda-metrics-dynamodb/src/site/markdown/guide/usage.md new file mode 100644 index 000000000..2f9c8f46e --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/src/site/markdown/guide/usage.md @@ -0,0 +1,123 @@ + + +# Usage + +This **Lambda** package generates metrics for **DynamoDB** table recording items count and table storage size. + +**Note:** **DynamoDB** updates items count and storage size roughly every six hours, so there is no point in computing +this metric more often. + +## Required permissions + +`lambda-metrics-dynamodb` Lambda needs following permissions: + +- `dynamodb:DescribeTable` (at least to tables you want to analyze), +- `cloudwatch:PutMetricData`. + +Additionally you may want to add following policies to it's role: + +- `arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole` (if you want to see **CloudWatch** logs of +resource handler execution); +- `arn:aws:iam::aws:policy/AWSXrayWriteOnlyAccess` (if you want more detailed tracing, package is built with +**X-Ray** instrumentor). + +## Environment variables + +- `METRICS_NAMESPACE`: metrics to be used for storing metrics. + +## Metrics + +- `ItemCount`: number of items in the table; +- `TableSizeBytes`: amount of bytes used by table. + +## Dimensions + +- `TableName`: name of DynamoDB table. + +# Example + +```yaml + DynamoDbMetricsRole: + Type: "AWS::IAM::Role" + Properties: + AssumeRolePolicyDocument: + Statement: + - + Action: "sts:AssumeRole" + Effect: "Allow" + Principal: + Service: + - "lambda.amazonaws.com" + ManagedPolicyArns: + - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + Policies: + - + PolicyName: "AllowDescribingDynamoDbTable" + PolicyDocument: + Version: "2012-10-17" + Statement: + - + Action: + - "dynamodb:DescribeTable" + Effect: "Allow" + Resource: + - !GetAtt "TableA.Arn" + - !GetAtt "TableB.Arn" + - + PolicyName: "AllowRecordingMetrics" + PolicyDocument: + Version: "2012-10-17" + Statement: + - + Action: + - "cloudwatch:PutMetricData" + Effect: "Allow" + Resource: + - "*" + + DynamoDbMetrics: + Type: "AWS::Lambda::Function" + Properties: + Runtime: "java8" + Code: + # put your source bucket + S3Bucket: "your-bucket" + S3Key: "lambda-metrics-dynamodb-1.0.31-standalone.jar" + Handler: "pl.wrzasq.lambda.metrics.dynamodb.Handler::handle" + MemorySize: 256 + Description: "DynamoDB metrics generator." + Timeout: 300 + TracingConfig: + Mode: "Active" + Role: !GetAtt "DynamoDbMetricsRole.Arn" + + MetricsTrigger: + Type: "AWS::Events::Rule" + DependsOn: + - "DynamoDbMetrics" + Properties: + ScheduleExpression: "rate(6 hours)" + State: "ENABLED" + Targets: + - + Arn: !GetAtt "DynamoDbMetrics.Arn" + Id: "tableA" + Input: !Sub "{\"tableName\": \"${TableA}\"}" + - + Arn: !GetAtt "DynamoDbMetrics.Arn" + Id: "tableB" + Input: !Sub "{\"tableName\": \"${TableB}\"}" + + AuthorizerLambdaHeartbeatPermission: + Type: "AWS::Lambda::Permission" + Properties: + FunctionName: !Ref "DynamoDbMetrics" + Action: "lambda:InvokeFunction" + Principal: "events.amazonaws.com" + SourceArn: !GetAtt "MetricsTrigger.Arn" +``` diff --git a/lambda-metrics/lambda-metrics-dynamodb/src/site/site.xml b/lambda-metrics/lambda-metrics-dynamodb/src/site/site.xml new file mode 100644 index 000000000..6d5cf9464 --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/src/site/site.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + diff --git a/lambda-metrics/lambda-metrics-dynamodb/src/test/java/test/pl/wrzasq/lambda/metrics/dynamodb/HandlerTest.java b/lambda-metrics/lambda-metrics-dynamodb/src/test/java/test/pl/wrzasq/lambda/metrics/dynamodb/HandlerTest.java new file mode 100644 index 000000000..4e7efab7e --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/src/test/java/test/pl/wrzasq/lambda/metrics/dynamodb/HandlerTest.java @@ -0,0 +1,85 @@ +/* + * This file is part of the pl.wrzasq.lambda. + * + * @license http://mit-license.org/ The MIT license + * @copyright 2019 © by Rafał Wrzeszcz - Wrzasq.pl. + */ + +package test.pl.wrzasq.lambda.metrics.dynamodb; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import pl.wrzasq.lambda.metrics.dynamodb.Handler; +import pl.wrzasq.lambda.metrics.dynamodb.model.TableMetricRequest; +import pl.wrzasq.lambda.metrics.dynamodb.service.CloudWatchDynamoDbMetricGenerator; + +@ExtendWith(MockitoExtension.class) +public class HandlerTest { + @Mock + private ObjectMapper objectMapper; + + @Mock + private InputStream inputStream; + + @Mock + private OutputStream outputStream; + + @Mock + private CloudWatchDynamoDbMetricGenerator metricGenerator; + + @Test + public void handle() throws IOException { + // for code coverage + new Handler(); + + String tableName = "test"; + + Handler handler = new Handler( + this.objectMapper, + this.metricGenerator + ); + + TableMetricRequest request = new TableMetricRequest(); + request.setTableName(tableName); + + Mockito + .when(this.objectMapper.readValue(this.inputStream, TableMetricRequest.class)) + .thenReturn(request); + + handler.handle(this.inputStream, this.outputStream); + + Mockito + .verify(this.metricGenerator) + .generateMetrics(tableName); + } + + @Test + public void handleCloseOnError() throws IOException { + Handler handler = new Handler( + this.objectMapper, + this.metricGenerator + ); + + Mockito + .when(this.objectMapper.readValue(this.inputStream, TableMetricRequest.class)) + .thenThrow(IOException.class); + + Assertions.assertThrows( + IOException.class, + () -> handler.handle(this.inputStream, this.outputStream), + "Handler.handle() should expose exception." + ); + + Mockito.verifyZeroInteractions(this.metricGenerator); + Mockito.verify(this.outputStream).close(); + } +} diff --git a/lambda-metrics/lambda-metrics-dynamodb/src/test/java/test/pl/wrzasq/lambda/metrics/dynamodb/service/CloudWatchDynamoDbMetricGeneratorTest.java b/lambda-metrics/lambda-metrics-dynamodb/src/test/java/test/pl/wrzasq/lambda/metrics/dynamodb/service/CloudWatchDynamoDbMetricGeneratorTest.java new file mode 100644 index 000000000..5e1c43e63 --- /dev/null +++ b/lambda-metrics/lambda-metrics-dynamodb/src/test/java/test/pl/wrzasq/lambda/metrics/dynamodb/service/CloudWatchDynamoDbMetricGeneratorTest.java @@ -0,0 +1,137 @@ +/* + * This file is part of the pl.wrzasq.lambda. + * + * @license http://mit-license.org/ The MIT license + * @copyright 2019 © by Rafał Wrzeszcz - Wrzasq.pl. + */ + +package test.pl.wrzasq.lambda.metrics.dynamodb.service; + +import java.util.List; + +import com.amazonaws.services.cloudwatch.AmazonCloudWatch; +import com.amazonaws.services.cloudwatch.model.MetricDatum; +import com.amazonaws.services.cloudwatch.model.PutMetricDataRequest; +import com.amazonaws.services.cloudwatch.model.StandardUnit; +import com.amazonaws.services.dynamodbv2.AmazonDynamoDB; +import com.amazonaws.services.dynamodbv2.model.DescribeTableResult; +import com.amazonaws.services.dynamodbv2.model.TableDescription; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentCaptor; +import org.mockito.Captor; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; +import pl.wrzasq.lambda.metrics.dynamodb.service.CloudWatchDynamoDbMetricGenerator; + +@ExtendWith(MockitoExtension.class) +public class CloudWatchDynamoDbMetricGeneratorTest { + @Mock + private AmazonDynamoDB dynamoDb; + + @Mock + private AmazonCloudWatch cloudWatch; + + @Captor + private ArgumentCaptor putMetricDataRequest; + + @Test + public void generateMetrics() { + String tableName = "Orders"; + String namespace = "Test/DynamoDB"; + + long itemCount = 10; + long tableSizeBytes = 256; + + CloudWatchDynamoDbMetricGenerator metricGenerator = new CloudWatchDynamoDbMetricGenerator( + this.dynamoDb, + this.cloudWatch, + namespace + ); + + TableDescription table = new TableDescription() + .withItemCount(itemCount) + .withTableSizeBytes(tableSizeBytes); + + Mockito + .when(this.dynamoDb.describeTable(tableName)) + .thenReturn(new DescribeTableResult().withTable(table)); + + metricGenerator.generateMetrics(tableName); + + Mockito + .verify(this.cloudWatch, Mockito.times(2)) + .putMetricData(this.putMetricDataRequest.capture()); + + List requests = this.putMetricDataRequest.getAllValues(); + + Assertions.assertEquals( + namespace, + requests.get(0).getNamespace(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should put metrics in specified namespace." + ); + Assertions.assertEquals( + namespace, + requests.get(1).getNamespace(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should put metrics in specified namespace." + ); + + MetricDatum metric = requests.get(0).getMetricData().get(0); + + Assertions.assertEquals( + itemCount, + metric.getValue(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should save count of documents in table." + ); + Assertions.assertEquals( + StandardUnit.None.toString(), + metric.getUnit(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should pick metric unit." + ); + Assertions.assertEquals( + "ItemCount", + metric.getMetricName(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should set metric name." + ); + Assertions.assertEquals( + "TableName", + metric.getDimensions().get(0).getName(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should set table name dimension." + ); + Assertions.assertEquals( + tableName, + metric.getDimensions().get(0).getValue(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should set table name as dimension value." + ); + + metric = requests.get(1).getMetricData().get(0); + + Assertions.assertEquals( + tableSizeBytes, + metric.getValue(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should save table storage size." + ); + Assertions.assertEquals( + StandardUnit.Bytes.toString(), + metric.getUnit(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should pick metric unit." + ); + Assertions.assertEquals( + "TableSizeBytes", + metric.getMetricName(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should set metric name." + ); + Assertions.assertEquals( + "TableName", + metric.getDimensions().get(0).getName(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should set table name dimension." + ); + Assertions.assertEquals( + tableName, + metric.getDimensions().get(0).getValue(), + "CloudWatchDynamoDbMetricGenerator.generateMetrics() should set table name as dimension value." + ); + } +} diff --git a/lambda-metrics/pom.xml b/lambda-metrics/pom.xml new file mode 100644 index 000000000..3c32bc8ae --- /dev/null +++ b/lambda-metrics/pom.xml @@ -0,0 +1,36 @@ + + + + 4.0.0 + + + lambda-metrics + pom + + pl.wrzasq.lambda + lambda + 1.0.31-SNAPSHOT + ../ + + + + WrzasqPl Lambda - CloudWatch Metrics + https://rafalwrzeszcz-wrzasqpl.github.io/pl.wrzasq.lambda/lambda-metrics/ + Custom CloudWatch metrics resource handlers container. + 2019 + + + + lambda-metrics-dynamodb + + diff --git a/lambda-metrics/src/main/checkstyle/java.header b/lambda-metrics/src/main/checkstyle/java.header new file mode 100644 index 000000000..7a72697ed --- /dev/null +++ b/lambda-metrics/src/main/checkstyle/java.header @@ -0,0 +1,8 @@ +^/\*$ +^ \* This file is part of the pl\.wrzasq\..lambda\.$ +^ \*$ +^ \* @license http://mit-license\.org/ The MIT license$ +^ \* @copyright \d{4}[0-9, -]* © by Rafał Wrzeszcz - Wrzasq\.pl\.$ +^ \*/$ + +^package pl\.wrzasq\.lambda\.metrics(\..+)?;$ diff --git a/lambda-metrics/src/site/site.xml b/lambda-metrics/src/site/site.xml new file mode 100644 index 000000000..d46a4c1da --- /dev/null +++ b/lambda-metrics/src/site/site.xml @@ -0,0 +1,19 @@ + + + + + + + + + diff --git a/pom.xml b/pom.xml index a26830516..29167847b 100644 --- a/pom.xml +++ b/pom.xml @@ -123,5 +123,6 @@ lambda-dynamodb lambda-edgedeploy lambda-json + lambda-metrics