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