diff --git a/datadog_lambda/metric.py b/datadog_lambda/metric.py index d312e3bb..c03d9195 100644 --- a/datadog_lambda/metric.py +++ b/datadog_lambda/metric.py @@ -3,6 +3,7 @@ # This product includes software developed at Datadog (https://www.datadoghq.com/). # Copyright 2019 Datadog, Inc. +import numbers import os import time import logging @@ -55,6 +56,20 @@ def lambda_metric(metric_name, value, timestamp=None, tags=None, force_async=Fal Note that if the extension is present, it will override the DD_FLUSH_TO_LOG value and always use the layer to send metrics to the extension """ + if not metric_name or not isinstance(metric_name, str): + logger.warning( + "Ignoring metric submission. Invalid metric name: %s", metric_name + ) + return + + if not isinstance(value, numbers.Number): + logger.warning( + "Ignoring metric submission for metric '%s' because the value is not numeric: %r", + metric_name, + value, + ) + return + flush_to_logs = os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true" tags = [] if tags is None else list(tags) tags.append(dd_lambda_layer_tag) diff --git a/tests/test_metric.py b/tests/test_metric.py index 345740a4..d10a0f0d 100644 --- a/tests/test_metric.py +++ b/tests/test_metric.py @@ -92,6 +92,32 @@ def test_lambda_metric_flush_to_log(self): del os.environ["DD_FLUSH_TO_LOG"] + @patch("datadog_lambda.metric.logger.warning") + def test_lambda_metric_invalid_metric_name_none(self, mock_logger_warning): + lambda_metric(None, 1) + self.mock_metric_lambda_stats.distribution.assert_not_called() + mock_logger_warning.assert_called_once_with( + "Ignoring metric submission. Invalid metric name: %s", None + ) + + @patch("datadog_lambda.metric.logger.warning") + def test_lambda_metric_invalid_metric_name_not_string(self, mock_logger_warning): + lambda_metric(123, 1) + self.mock_metric_lambda_stats.distribution.assert_not_called() + mock_logger_warning.assert_called_once_with( + "Ignoring metric submission. Invalid metric name: %s", 123 + ) + + @patch("datadog_lambda.metric.logger.warning") + def test_lambda_metric_non_numeric_value(self, mock_logger_warning): + lambda_metric("test.non_numeric", "oops") + self.mock_metric_lambda_stats.distribution.assert_not_called() + mock_logger_warning.assert_called_once_with( + "Ignoring metric submission for metric '%s' because the value is not numeric: %r", + "test.non_numeric", + "oops", + ) + class TestFlushThreadStats(unittest.TestCase): def setUp(self):