Skip to content

Commit

Permalink
fix: split ColdStart metric to its own EMF blob #125
Browse files Browse the repository at this point in the history
  • Loading branch information
heitorlessa committed Aug 22, 2020
1 parent c9252c7 commit d4f8a19
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 5 deletions.
10 changes: 6 additions & 4 deletions aws_lambda_powertools/metrics/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import warnings
from typing import Any, Callable

from .base import MetricManager
from .base import MetricManager, MetricUnit
from .metric import single_metric

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -167,6 +168,7 @@ def __add_cold_start_metric(self, context: Any):
global is_cold_start
if is_cold_start:
logger.debug("Adding cold start metric and function_name dimension")
self.add_metric(name="ColdStart", value=1, unit="Count")
self.add_dimension(name="function_name", value=context.function_name)
is_cold_start = False
with single_metric(name="ColdStart", unit=MetricUnit.Count, value=1, namespace=self.namespace) as metric:
metric.add_dimension(name="function_name", value=context.function_name)
metric.add_dimension(name="service", value=self.service)
is_cold_start = False
39 changes: 38 additions & 1 deletion tests/functional/test_metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@

from aws_lambda_powertools import Metrics, single_metric
from aws_lambda_powertools.metrics import MetricUnit, MetricUnitError, MetricValueError, SchemaValidationError
from aws_lambda_powertools.metrics import metrics as metrics_global
from aws_lambda_powertools.metrics.base import MetricManager


@pytest.fixture(scope="function", autouse=True)
def reset_metric_set():
metrics = Metrics()
metrics.clear_metrics()
metrics_global.is_cold_start = True # ensure each test has cold start
yield


Expand Down Expand Up @@ -112,6 +114,10 @@ def capture_metrics_output(capsys):
return json.loads(capsys.readouterr().out.strip())


def capture_metrics_output_multiple_emf_objects(capsys):
return [json.loads(line.strip()) for line in capsys.readouterr().out.split("\n") if line]


def test_single_metric_logs_one_metric_only(capsys, metric, dimension, namespace):
# GIVEN we try adding more than one metric
# WHEN using single_metric context manager
Expand Down Expand Up @@ -495,7 +501,7 @@ def lambda_handler(evt, context):

LambdaContext = namedtuple("LambdaContext", "function_name")
lambda_handler({}, LambdaContext("example_fn"))
_ = capture_metrics_output(capsys) # ignore first stdout captured
_, _ = capture_metrics_output_multiple_emf_objects(capsys) # ignore first stdout captured

# THEN ColdStart metric and function_name dimension should be logged once
lambda_handler({}, LambdaContext("example_fn"))
Expand Down Expand Up @@ -630,3 +636,34 @@ def test_serialize_metric_set_metric_definition(metric, dimension, namespace, se
assert "Timestamp" in metric_definition_output["_aws"]
remove_timestamp(metrics=[metric_definition_output, expected_metric_definition])
assert metric_definition_output == expected_metric_definition


def test_log_metrics_capture_cold_start_metric_separately(capsys, namespace, service, metric, dimension):
# GIVEN Metrics is initialized
my_metrics = Metrics(service=service, namespace=namespace)

# WHEN log_metrics is used with capture_cold_start_metric
@my_metrics.log_metrics(capture_cold_start_metric=True)
def lambda_handler(evt, context):
my_metrics.add_metric(**metric)
my_metrics.add_dimension(**dimension)

LambdaContext = namedtuple("LambdaContext", "function_name")
lambda_handler({}, LambdaContext("example_fn"))

cold_start_blob, custom_metrics_blob = capture_metrics_output_multiple_emf_objects(capsys)

# THEN ColdStart metric and function_name dimension should be logged
# in a separate EMF blob than the application metrics
assert cold_start_blob["ColdStart"] == 1
assert cold_start_blob["function_name"] == "example_fn"
assert cold_start_blob["service"] == service

# and that application metrics dimensions are not part of ColdStart EMF blob
assert "test_dimension" not in cold_start_blob

# THEN application metrics EMF blob should not have function_name dimension
assert "function_name" not in custom_metrics_blob
assert custom_metrics_blob["service"] == service
assert custom_metrics_blob["single_metric"] == metric["value"]
assert custom_metrics_blob["test_dimension"] == dimension["value"]

0 comments on commit d4f8a19

Please sign in to comment.