Skip to content

Commit dc03756

Browse files
[SVLS-4422] Support for metrics with timestamps when the Extension is present (#480)
use API to send metrics with timestamps when extension is present
1 parent 95dd5be commit dc03756

File tree

3 files changed

+37
-9
lines changed

3 files changed

+37
-9
lines changed

datadog_lambda/api.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import os
22
import logging
33
import base64
4-
from datadog_lambda.extension import should_use_extension
54

65
logger = logging.getLogger(__name__)
76
KMS_ENCRYPTION_CONTEXT_KEY = "LambdaFunctionName"
@@ -48,13 +47,10 @@ def decrypt_kms_api_key(kms_client, ciphertext):
4847

4948

5049
def init_api():
51-
if (
52-
not should_use_extension
53-
and not os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true"
54-
):
50+
if not os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true":
5551
# Make sure that this package would always be lazy-loaded/outside from the critical path
5652
# since underlying packages are quite heavy to load
57-
# and useless when the extension is present
53+
# and useless with the extension unless sending metrics with timestamps
5854
from datadog import api
5955

6056
if not api._api_key:

datadog_lambda/metric.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010

1111
from datadog_lambda.extension import should_use_extension
1212
from datadog_lambda.tags import get_enhanced_metrics_tags, dd_lambda_layer_tag
13-
from datadog_lambda.api import init_api
1413

1514
logger = logging.getLogger(__name__)
1615

1716
lambda_stats = None
17+
extension_thread_stats = None
1818

19-
init_api()
19+
flush_in_thread = os.environ.get("DD_FLUSH_IN_THREAD", "").lower() == "true"
2020

2121
if should_use_extension:
2222
from datadog_lambda.statsd_writer import StatsDWriter
@@ -28,8 +28,9 @@
2828
# end of invocation. To make metrics submitted from a long-running Lambda
2929
# function available sooner, consider using the Datadog Lambda extension.
3030
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
31+
from datadog_lambda.api import init_api
3132

32-
flush_in_thread = os.environ.get("DD_FLUSH_IN_THREAD", "").lower() == "true"
33+
init_api()
3334
lambda_stats = ThreadStatsWriter(flush_in_thread)
3435

3536
enhanced_metrics_enabled = (
@@ -57,6 +58,22 @@ def lambda_metric(metric_name, value, timestamp=None, tags=None, force_async=Fal
5758
tags = [] if tags is None else list(tags)
5859
tags.append(dd_lambda_layer_tag)
5960

61+
if should_use_extension and timestamp is not None:
62+
# The extension does not support timestamps for distributions so we create a
63+
# a thread stats writer to submit metrics with timestamps to the API
64+
global extension_thread_stats
65+
if extension_thread_stats is None:
66+
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
67+
from datadog_lambda.api import init_api
68+
69+
init_api()
70+
extension_thread_stats = ThreadStatsWriter(flush_in_thread)
71+
72+
extension_thread_stats.distribution(
73+
metric_name, value, tags=tags, timestamp=timestamp
74+
)
75+
return
76+
6077
if should_use_extension:
6178
logger.debug(
6279
"Sending metric %s value %s to Datadog via extension", metric_name, value
@@ -94,6 +111,9 @@ def write_metric_point_to_stdout(metric_name, value, timestamp=None, tags=[]):
94111
def flush_stats():
95112
lambda_stats.flush()
96113

114+
if extension_thread_stats is not None:
115+
extension_thread_stats.flush()
116+
97117

98118
def submit_enhanced_metric(metric_name, lambda_context):
99119
"""Submits the enhanced metric with the given name

tests/test_metric.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,18 @@ def test_lambda_metric_flush_to_log_with_extension(self):
4343
)
4444
del os.environ["DD_FLUSH_TO_LOG"]
4545

46+
@patch("datadog_lambda.metric.should_use_extension", True)
47+
def test_lambda_metric_timestamp_with_extension(self):
48+
patcher = patch("datadog_lambda.metric.extension_thread_stats")
49+
self.mock_metric_extension_thread_stats = patcher.start()
50+
self.addCleanup(patcher.stop)
51+
52+
lambda_metric("test_timestamp", 1, 123)
53+
self.mock_metric_lambda_stats.distribution.assert_not_called()
54+
self.mock_metric_extension_thread_stats.distribution.assert_called_with(
55+
"test_timestamp", 1, timestamp=123, tags=[dd_lambda_layer_tag]
56+
)
57+
4658
def test_lambda_metric_flush_to_log(self):
4759
os.environ["DD_FLUSH_TO_LOG"] = "True"
4860

0 commit comments

Comments
 (0)