Skip to content

Create static tags once on import. #460

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Apr 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions datadog_lambda/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import logging

from datadog_lambda.extension import should_use_extension
from datadog_lambda.tags import get_enhanced_metrics_tags, tag_dd_lambda_layer
from datadog_lambda.tags import get_enhanced_metrics_tags, dd_lambda_layer_tag
from datadog_lambda.api import init_api

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

if should_use_extension:
logger.debug(
Expand Down
50 changes: 13 additions & 37 deletions datadog_lambda/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,10 @@
from datadog_lambda.cold_start import get_cold_start_tag


def _format_dd_lambda_layer_tag():
"""
Formats the dd_lambda_layer tag, e.g., 'dd_lambda_layer:datadog-python39_1'
"""
major, minor = sys.version_info[0], sys.version_info[1]
return f"dd_lambda_layer:datadog-python{major}{minor}_{__version__}"


def tag_dd_lambda_layer(tags):
"""
Used by lambda_metric to insert the dd_lambda_layer tag
"""
dd_lambda_layer_tag = _format_dd_lambda_layer_tag()
if tags:
return tags + [dd_lambda_layer_tag]
else:
return [dd_lambda_layer_tag]
_major, _minor = sys.version_info[0], sys.version_info[1]
dd_lambda_layer_tag = f"dd_lambda_layer:datadog-python{_major}{_minor}_{__version__}"
runtime_tag = f"runtime:python{_major}.{_minor}"
library_version_tag = f"datadog_lambda:v{__version__}"


def parse_lambda_tags_from_arn(lambda_context):
Expand All @@ -30,12 +17,12 @@ def parse_lambda_tags_from_arn(lambda_context):
ex: lambda_context.arn = arn:aws:lambda:us-east-1:123597598159:function:my-lambda:1
"""
# Set up flag for extra testing to distinguish between a version or alias
hasAlias = False
has_alias = False
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great catch

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks

# Cap the number of times to spli
split_arn = lambda_context.invoked_function_arn.split(":")

if len(split_arn) > 7:
hasAlias = True
has_alias = True
_, _, _, region, account_id, _, function_name, alias = split_arn
else:
_, _, _, region, account_id, _, function_name = split_arn
Expand All @@ -48,7 +35,7 @@ def parse_lambda_tags_from_arn(lambda_context):
]

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


def get_runtime_tag():
"""Get the runtime tag from the current Python version"""
major, minor = sys.version_info[0], sys.version_info[1]
return f"runtime:python{major}.{minor}"


def get_library_version_tag():
"""Get datadog lambda library tag"""
return f"datadog_lambda:v{__version__}"


def get_enhanced_metrics_tags(lambda_context):
"""Get the list of tags to apply to enhanced metrics"""
return parse_lambda_tags_from_arn(lambda_context) + [
get_cold_start_tag(),
f"memorysize:{lambda_context.memory_limit_in_mb}",
get_runtime_tag(),
get_library_version_tag(),
]
tags = parse_lambda_tags_from_arn(lambda_context)
tags.append(get_cold_start_tag())
tags.append(f"memorysize:{lambda_context.memory_limit_in_mb}")
tags.append(runtime_tag)
tags.append(library_version_tag)
return tags


def check_if_number(alias):
Expand Down
14 changes: 7 additions & 7 deletions tests/test_metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from datadog_lambda.metric import lambda_metric
from datadog_lambda.api import decrypt_kms_api_key, KMS_ENCRYPTION_CONTEXT_KEY
from datadog_lambda.thread_stats_writer import ThreadStatsWriter
from datadog_lambda.tags import _format_dd_lambda_layer_tag
from datadog_lambda.tags import dd_lambda_layer_tag


class TestLambdaMetric(unittest.TestCase):
Expand All @@ -23,12 +23,13 @@ def test_lambda_metric_tagged_with_dd_lambda_layer(self):
lambda_metric("test", 1)
lambda_metric("test", 1, 123, [])
lambda_metric("test", 1, tags=["tag1:test"])
expected_tag = _format_dd_lambda_layer_tag()
self.mock_metric_lambda_stats.distribution.assert_has_calls(
[
call("test", 1, timestamp=None, tags=[expected_tag]),
call("test", 1, timestamp=123, tags=[expected_tag]),
call("test", 1, timestamp=None, tags=["tag1:test", expected_tag]),
call("test", 1, timestamp=None, tags=[dd_lambda_layer_tag]),
call("test", 1, timestamp=123, tags=[dd_lambda_layer_tag]),
call(
"test", 1, timestamp=None, tags=["tag1:test", dd_lambda_layer_tag]
),
]
)

Expand All @@ -37,9 +38,8 @@ def test_lambda_metric_tagged_with_dd_lambda_layer(self):
def test_lambda_metric_flush_to_log_with_extension(self):
os.environ["DD_FLUSH_TO_LOG"] = "True"
lambda_metric("test", 1)
expected_tag = _format_dd_lambda_layer_tag()
self.mock_metric_lambda_stats.distribution.assert_has_calls(
[call("test", 1, timestamp=None, tags=[expected_tag])]
[call("test", 1, timestamp=None, tags=[dd_lambda_layer_tag])]
)
del os.environ["DD_FLUSH_TO_LOG"]

Expand Down
5 changes: 1 addition & 4 deletions tests/test_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from unittest.mock import patch, MagicMock


from datadog_lambda.tags import parse_lambda_tags_from_arn, get_runtime_tag
from datadog_lambda.tags import parse_lambda_tags_from_arn


def get_mock_context(
Expand Down Expand Up @@ -63,6 +63,3 @@ def test_parse_lambda_tags_from_arn_alias(self):
"resource:swf-hello-test:my_alias-1",
],
)

def test_get_runtime_tag(self):
self.assertEqual(get_runtime_tag(), "runtime:python3.12")
22 changes: 12 additions & 10 deletions tests/test_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,25 +66,27 @@ def setUp(self):
self.mock_get_cold_start_tag.return_value = "cold_start:true"
self.addCleanup(patcher.stop)

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

patcher = patch("datadog_lambda.metric.write_metric_point_to_stdout")
self.mock_write_metric_point_to_stdout = patcher.start()
self.addCleanup(patcher.stop)

patcher = patch("datadog_lambda.tags.get_library_version_tag")
self.mock_format_dd_lambda_layer_tag = patcher.start()
patcher = patch(
"datadog_lambda.tags.library_version_tag", "datadog_lambda:v6.6.6"
)
# Mock the layer version so we don't have to update tests on every version bump
self.mock_format_dd_lambda_layer_tag.return_value = "datadog_lambda:v6.6.6"
self.mock_library_version_tag = patcher.start()
self.addCleanup(patcher.stop)

patcher = patch("datadog_lambda.tags._format_dd_lambda_layer_tag")
self.mock_format_dd_lambda_layer_tag = patcher.start()
# Mock the layer version so we don't have to update tests on every version bump
self.mock_format_dd_lambda_layer_tag.return_value = (
"dd_lambda_layer:datadog-python39_X.X.X"
patcher = patch(
"datadog_lambda.metric.dd_lambda_layer_tag",
"dd_lambda_layer:datadog-python39_X.X.X",
)
# Mock the layer version so we don't have to update tests on every version bump
self.mock_dd_lambda_layer_tag = patcher.start()
self.addCleanup(patcher.stop)

def test_datadog_lambda_wrapper(self):
Expand Down