Skip to content

Commit ad81d15

Browse files
authored
Create static tags once on import. (#460)
* Create lambda layer tag only once. * Only create runtime tag once. * Create library version tag just once. * Avoid extra list allocations when creating tags. * Cleaned test. * Linting.
1 parent 4cfcf7e commit ad81d15

File tree

5 files changed

+36
-60
lines changed

5 files changed

+36
-60
lines changed

datadog_lambda/metric.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
import logging
1010

1111
from datadog_lambda.extension import should_use_extension
12-
from datadog_lambda.tags import get_enhanced_metrics_tags, tag_dd_lambda_layer
12+
from datadog_lambda.tags import get_enhanced_metrics_tags, dd_lambda_layer_tag
1313
from datadog_lambda.api import init_api
1414

1515
logger = logging.getLogger(__name__)
@@ -50,7 +50,8 @@ def lambda_metric(metric_name, value, timestamp=None, tags=None, force_async=Fal
5050
and always use the layer to send metrics to the extension
5151
"""
5252
flush_to_logs = os.environ.get("DD_FLUSH_TO_LOG", "").lower() == "true"
53-
tags = tag_dd_lambda_layer(tags)
53+
tags = [] if tags is None else list(tags)
54+
tags.append(dd_lambda_layer_tag)
5455

5556
if should_use_extension:
5657
logger.debug(

datadog_lambda/tags.py

Lines changed: 13 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,10 @@
44
from datadog_lambda.cold_start import get_cold_start_tag
55

66

7-
def _format_dd_lambda_layer_tag():
8-
"""
9-
Formats the dd_lambda_layer tag, e.g., 'dd_lambda_layer:datadog-python39_1'
10-
"""
11-
major, minor = sys.version_info[0], sys.version_info[1]
12-
return f"dd_lambda_layer:datadog-python{major}{minor}_{__version__}"
13-
14-
15-
def tag_dd_lambda_layer(tags):
16-
"""
17-
Used by lambda_metric to insert the dd_lambda_layer tag
18-
"""
19-
dd_lambda_layer_tag = _format_dd_lambda_layer_tag()
20-
if tags:
21-
return tags + [dd_lambda_layer_tag]
22-
else:
23-
return [dd_lambda_layer_tag]
7+
_major, _minor = sys.version_info[0], sys.version_info[1]
8+
dd_lambda_layer_tag = f"dd_lambda_layer:datadog-python{_major}{_minor}_{__version__}"
9+
runtime_tag = f"runtime:python{_major}.{_minor}"
10+
library_version_tag = f"datadog_lambda:v{__version__}"
2411

2512

2613
def parse_lambda_tags_from_arn(lambda_context):
@@ -30,12 +17,12 @@ def parse_lambda_tags_from_arn(lambda_context):
3017
ex: lambda_context.arn = arn:aws:lambda:us-east-1:123597598159:function:my-lambda:1
3118
"""
3219
# Set up flag for extra testing to distinguish between a version or alias
33-
hasAlias = False
20+
has_alias = False
3421
# Cap the number of times to spli
3522
split_arn = lambda_context.invoked_function_arn.split(":")
3623

3724
if len(split_arn) > 7:
38-
hasAlias = True
25+
has_alias = True
3926
_, _, _, region, account_id, _, function_name, alias = split_arn
4027
else:
4128
_, _, _, region, account_id, _, function_name = split_arn
@@ -48,7 +35,7 @@ def parse_lambda_tags_from_arn(lambda_context):
4835
]
4936

5037
# Check if we have a version or alias
51-
if hasAlias:
38+
if has_alias:
5239
# If $Latest, drop the $ for datadog tag convention. A lambda alias can't start with $
5340
if alias.startswith("$"):
5441
alias = alias[1:]
@@ -66,25 +53,14 @@ def parse_lambda_tags_from_arn(lambda_context):
6653
return tags
6754

6855

69-
def get_runtime_tag():
70-
"""Get the runtime tag from the current Python version"""
71-
major, minor = sys.version_info[0], sys.version_info[1]
72-
return f"runtime:python{major}.{minor}"
73-
74-
75-
def get_library_version_tag():
76-
"""Get datadog lambda library tag"""
77-
return f"datadog_lambda:v{__version__}"
78-
79-
8056
def get_enhanced_metrics_tags(lambda_context):
8157
"""Get the list of tags to apply to enhanced metrics"""
82-
return parse_lambda_tags_from_arn(lambda_context) + [
83-
get_cold_start_tag(),
84-
f"memorysize:{lambda_context.memory_limit_in_mb}",
85-
get_runtime_tag(),
86-
get_library_version_tag(),
87-
]
58+
tags = parse_lambda_tags_from_arn(lambda_context)
59+
tags.append(get_cold_start_tag())
60+
tags.append(f"memorysize:{lambda_context.memory_limit_in_mb}")
61+
tags.append(runtime_tag)
62+
tags.append(library_version_tag)
63+
return tags
8864

8965

9066
def check_if_number(alias):

tests/test_metric.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from datadog_lambda.metric import lambda_metric
1111
from datadog_lambda.api import decrypt_kms_api_key, KMS_ENCRYPTION_CONTEXT_KEY
1212
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
13-
from datadog_lambda.tags import _format_dd_lambda_layer_tag
13+
from datadog_lambda.tags import dd_lambda_layer_tag
1414

1515

1616
class TestLambdaMetric(unittest.TestCase):
@@ -23,12 +23,13 @@ def test_lambda_metric_tagged_with_dd_lambda_layer(self):
2323
lambda_metric("test", 1)
2424
lambda_metric("test", 1, 123, [])
2525
lambda_metric("test", 1, tags=["tag1:test"])
26-
expected_tag = _format_dd_lambda_layer_tag()
2726
self.mock_metric_lambda_stats.distribution.assert_has_calls(
2827
[
29-
call("test", 1, timestamp=None, tags=[expected_tag]),
30-
call("test", 1, timestamp=123, tags=[expected_tag]),
31-
call("test", 1, timestamp=None, tags=["tag1:test", expected_tag]),
28+
call("test", 1, timestamp=None, tags=[dd_lambda_layer_tag]),
29+
call("test", 1, timestamp=123, tags=[dd_lambda_layer_tag]),
30+
call(
31+
"test", 1, timestamp=None, tags=["tag1:test", dd_lambda_layer_tag]
32+
),
3233
]
3334
)
3435

@@ -37,9 +38,8 @@ def test_lambda_metric_tagged_with_dd_lambda_layer(self):
3738
def test_lambda_metric_flush_to_log_with_extension(self):
3839
os.environ["DD_FLUSH_TO_LOG"] = "True"
3940
lambda_metric("test", 1)
40-
expected_tag = _format_dd_lambda_layer_tag()
4141
self.mock_metric_lambda_stats.distribution.assert_has_calls(
42-
[call("test", 1, timestamp=None, tags=[expected_tag])]
42+
[call("test", 1, timestamp=None, tags=[dd_lambda_layer_tag])]
4343
)
4444
del os.environ["DD_FLUSH_TO_LOG"]
4545

tests/test_tags.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from unittest.mock import patch, MagicMock
44

55

6-
from datadog_lambda.tags import parse_lambda_tags_from_arn, get_runtime_tag
6+
from datadog_lambda.tags import parse_lambda_tags_from_arn
77

88

99
def get_mock_context(
@@ -63,6 +63,3 @@ def test_parse_lambda_tags_from_arn_alias(self):
6363
"resource:swf-hello-test:my_alias-1",
6464
],
6565
)
66-
67-
def test_get_runtime_tag(self):
68-
self.assertEqual(get_runtime_tag(), "runtime:python3.12")

tests/test_wrapper.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,25 +66,27 @@ def setUp(self):
6666
self.mock_get_cold_start_tag.return_value = "cold_start:true"
6767
self.addCleanup(patcher.stop)
6868

69-
patcher = patch("sys.version_info", (3, 9, 10))
70-
self.mock_python_version_tuple = patcher.start()
69+
patcher = patch("datadog_lambda.tags.runtime_tag", "runtime:python3.9")
70+
self.mock_runtime_tag = patcher.start()
7171
self.addCleanup(patcher.stop)
7272

7373
patcher = patch("datadog_lambda.metric.write_metric_point_to_stdout")
7474
self.mock_write_metric_point_to_stdout = patcher.start()
7575
self.addCleanup(patcher.stop)
7676

77-
patcher = patch("datadog_lambda.tags.get_library_version_tag")
78-
self.mock_format_dd_lambda_layer_tag = patcher.start()
77+
patcher = patch(
78+
"datadog_lambda.tags.library_version_tag", "datadog_lambda:v6.6.6"
79+
)
7980
# Mock the layer version so we don't have to update tests on every version bump
80-
self.mock_format_dd_lambda_layer_tag.return_value = "datadog_lambda:v6.6.6"
81+
self.mock_library_version_tag = patcher.start()
82+
self.addCleanup(patcher.stop)
8183

82-
patcher = patch("datadog_lambda.tags._format_dd_lambda_layer_tag")
83-
self.mock_format_dd_lambda_layer_tag = patcher.start()
84-
# Mock the layer version so we don't have to update tests on every version bump
85-
self.mock_format_dd_lambda_layer_tag.return_value = (
86-
"dd_lambda_layer:datadog-python39_X.X.X"
84+
patcher = patch(
85+
"datadog_lambda.metric.dd_lambda_layer_tag",
86+
"dd_lambda_layer:datadog-python39_X.X.X",
8787
)
88+
# Mock the layer version so we don't have to update tests on every version bump
89+
self.mock_dd_lambda_layer_tag = patcher.start()
8890
self.addCleanup(patcher.stop)
8991

9092
def test_datadog_lambda_wrapper(self):

0 commit comments

Comments
 (0)