Skip to content

Commit 1e564c9

Browse files
feat: send metrics with timestamps to the extension
This is now supported by both the go extension and bottlecap, so we can safely send metrics to the extension and not have to ship the ones with timestamps directly to the Datadog API.
1 parent b4f6c81 commit 1e564c9

File tree

2 files changed

+34
-40
lines changed

2 files changed

+34
-40
lines changed

datadog_lambda/metric.py

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -76,39 +76,25 @@ def lambda_metric(metric_name, value, timestamp=None, tags=None, force_async=Fal
7676
tags = [] if tags is None else list(tags)
7777
tags.append(dd_lambda_layer_tag)
7878

79-
if should_use_extension and timestamp is not None:
80-
# The extension does not support timestamps for distributions so we create a
81-
# a thread stats writer to submit metrics with timestamps to the API
82-
timestamp_ceiling = int(
83-
(datetime.now() - timedelta(hours=4)).timestamp()
84-
) # 4 hours ago
85-
if isinstance(timestamp, datetime):
86-
timestamp = int(timestamp.timestamp())
87-
if timestamp_ceiling > timestamp:
88-
logger.warning(
89-
"Timestamp %s is older than 4 hours, not submitting metric %s",
90-
timestamp,
91-
metric_name,
92-
)
93-
return
94-
global extension_thread_stats
95-
if extension_thread_stats is None:
96-
from datadog_lambda.api import init_api
97-
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
98-
99-
init_api()
100-
extension_thread_stats = ThreadStatsWriter(flush_in_thread)
101-
102-
extension_thread_stats.distribution(
103-
metric_name, value, tags=tags, timestamp=timestamp
104-
)
105-
return
106-
10779
if should_use_extension:
80+
if timestamp is not None:
81+
if isinstance(timestamp, datetime):
82+
timestamp = int(timestamp.timestamp())
83+
84+
timestamp_floor = int((datetime.now() - timedelta(hours=4)).timestamp())
85+
if timestamp < timestamp_floor:
86+
logger.warning(
87+
"Timestamp %s is older than 4 hours, not submitting metric %s",
88+
timestamp,
89+
metric_name,
90+
)
91+
return
92+
10893
logger.debug(
10994
"Sending metric %s value %s to Datadog via extension", metric_name, value
11095
)
11196
lambda_stats.distribution(metric_name, value, tags=tags, timestamp=timestamp)
97+
11298
else:
11399
if flush_to_logs or force_async:
114100
write_metric_point_to_stdout(

tests/test_metric.py

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import os
22
import unittest
3-
4-
from unittest.mock import patch, call
3+
from datetime import datetime, timedelta
4+
from unittest.mock import call, patch
55

66
from botocore.exceptions import ClientError as BotocoreClientError
77
from datadog.api.exceptions import ClientError
8-
from datetime import datetime, timedelta
98

10-
from datadog_lambda.metric import lambda_metric, flush_stats
11-
from datadog_lambda.api import decrypt_kms_api_key, KMS_ENCRYPTION_CONTEXT_KEY
12-
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
9+
from datadog_lambda.api import KMS_ENCRYPTION_CONTEXT_KEY, decrypt_kms_api_key
10+
from datadog_lambda.metric import flush_stats, lambda_metric
1311
from datadog_lambda.tags import dd_lambda_layer_tag
12+
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
1413

1514

1615
class TestLambdaMetric(unittest.TestCase):
@@ -53,22 +52,31 @@ def test_lambda_metric_timestamp_with_extension(self):
5352
timestamp = int((datetime.now() - delta).timestamp())
5453

5554
lambda_metric("test_timestamp", 1, timestamp)
56-
self.mock_metric_lambda_stats.distribution.assert_not_called()
57-
self.mock_metric_extension_thread_stats.distribution.assert_called_with(
58-
"test_timestamp", 1, timestamp=timestamp, tags=[dd_lambda_layer_tag]
55+
self.mock_metric_lambda_stats.distribution.assert_has_calls(
56+
[call("test_timestamp", 1, timestamp=timestamp, tags=[dd_lambda_layer_tag])]
5957
)
58+
self.mock_metric_extension_thread_stats.distribution.assert_not_called()
6059

6160
@patch("datadog_lambda.metric.should_use_extension", True)
6261
def test_lambda_metric_datetime_with_extension(self):
6362
patcher = patch("datadog_lambda.metric.extension_thread_stats")
6463
self.mock_metric_extension_thread_stats = patcher.start()
6564
self.addCleanup(patcher.stop)
6665

67-
delta = timedelta(hours=5)
66+
delta = timedelta(minutes=1)
6867
timestamp = datetime.now() - delta
6968

70-
lambda_metric("test_timestamp", 1, timestamp)
71-
self.mock_metric_lambda_stats.distribution.assert_not_called()
69+
lambda_metric("test_datetime_timestamp", 0, timestamp)
70+
self.mock_metric_lambda_stats.distribution.assert_has_calls(
71+
[
72+
call(
73+
"test_datetime_timestamp",
74+
0,
75+
timestamp=int(timestamp.timestamp()),
76+
tags=[dd_lambda_layer_tag],
77+
)
78+
]
79+
)
7280
self.mock_metric_extension_thread_stats.distribution.assert_not_called()
7381

7482
@patch("datadog_lambda.metric.should_use_extension", True)

0 commit comments

Comments
 (0)