Skip to content

Commit

Permalink
Merge pull request #25 from DataDog/stephenf/add-runtime-and-memorysi…
Browse files Browse the repository at this point in the history
…ze-tags

Tag enhanced metrics with runtime and memorysize
  • Loading branch information
sfirrin authored Nov 4, 2019
2 parents 6087ba6 + 141325a commit d29de3b
Show file tree
Hide file tree
Showing 7 changed files with 75 additions and 15 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

# Version 9 / 2019-11-04

- Tag layer-generated `aws.lambda.enhanced.invocations` and `aws.lambda.enhanced.errors` enhanced metrics with `runtime` and `memorysize`

# Version 8 / 2019-10-24

- Remove vendored botocore requests patching since the package has been removed from the latest botocore
Expand Down
2 changes: 1 addition & 1 deletion datadog_lambda/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# The minor version corresponds to the Lambda layer version.
# E.g.,, version 0.5.0 gets packaged into layer version 5.
__version__ = '0.8.0'
__version__ = '0.9.0'


import os
Expand Down
11 changes: 5 additions & 6 deletions datadog_lambda/metric.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
from datadog import api
from datadog.threadstats import ThreadStats
from datadog_lambda import __version__
from datadog_lambda.cold_start import get_cold_start_tag
from datadog_lambda.tags import parse_lambda_tags_from_arn
from datadog_lambda.tags import get_enhanced_metrics_tags


ENHANCED_METRICS_NAMESPACE_PREFIX = "aws.lambda.enhanced"
Expand Down Expand Up @@ -82,7 +81,7 @@ def are_enhanced_metrics_enabled():
return os.environ.get("DD_ENHANCED_METRICS", "false").lower() == "true"


def submit_invocations_metric(lambda_arn):
def submit_invocations_metric(lambda_context):
"""Increment aws.lambda.enhanced.invocations by 1
"""
if not are_enhanced_metrics_enabled():
Expand All @@ -91,11 +90,11 @@ def submit_invocations_metric(lambda_arn):
lambda_metric(
"{}.invocations".format(ENHANCED_METRICS_NAMESPACE_PREFIX),
1,
tags=parse_lambda_tags_from_arn(lambda_arn) + [get_cold_start_tag()],
tags=get_enhanced_metrics_tags(lambda_context),
)


def submit_errors_metric(lambda_arn):
def submit_errors_metric(lambda_context):
"""Increment aws.lambda.enhanced.errors by 1
"""
if not are_enhanced_metrics_enabled():
Expand All @@ -104,7 +103,7 @@ def submit_errors_metric(lambda_arn):
lambda_metric(
"{}.errors".format(ENHANCED_METRICS_NAMESPACE_PREFIX),
1,
tags=parse_lambda_tags_from_arn(lambda_arn) + [get_cold_start_tag()],
tags=get_enhanced_metrics_tags(lambda_context),
)


Expand Down
25 changes: 25 additions & 0 deletions datadog_lambda/tags.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
from platform import python_version_tuple

from datadog_lambda.cold_start import get_cold_start_tag


def parse_lambda_tags_from_arn(arn):
"""Generate the list of lambda tags based on the data in the arn
Args:
Expand All @@ -18,3 +23,23 @@ def parse_lambda_tags_from_arn(arn):
"account_id:{}".format(account_id),
"functionname:{}".format(function_name),
]


def get_runtime_tag():
"""Get the runtime tag from the current Python version
"""
major_version, minor_version, _ = python_version_tuple()

return "runtime:python{major}.{minor}".format(
major=major_version, minor=minor_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.invoked_function_arn) + [
get_cold_start_tag(),
"memorysize:{}".format(lambda_context.memory_limit_in_mb),
get_runtime_tag(),
]
4 changes: 2 additions & 2 deletions datadog_lambda/wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ def _before(self, event, context):
set_cold_start()

try:
submit_invocations_metric(context.invoked_function_arn)
submit_invocations_metric(context)
# Extract Datadog trace context from incoming requests
extract_dd_trace_context(event)

Expand All @@ -82,7 +82,7 @@ def __call__(self, event, context):
try:
return self.func(event, context)
except Exception:
submit_errors_metric(context.invoked_function_arn)
submit_errors_metric(context)
raise
finally:
self._after(event, context)
Expand Down
19 changes: 18 additions & 1 deletion tests/test_tags.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,19 @@
import unittest

from datadog_lambda.tags import parse_lambda_tags_from_arn
try:
from unittest.mock import patch
except ImportError:
from mock import patch

from datadog_lambda.tags import parse_lambda_tags_from_arn, get_runtime_tag


class TestMetricTags(unittest.TestCase):
def setUp(self):
patcher = patch("datadog_lambda.tags.python_version_tuple")
self.mock_python_version_tuple = patcher.start()
self.addCleanup(patcher.stop)

def test_parse_lambda_tags_from_arn(self):
self.assertListEqual(
parse_lambda_tags_from_arn(
Expand All @@ -27,3 +37,10 @@ def test_parse_lambda_tags_from_arn(self):
],
)

def test_get_runtime_tag(self):
self.mock_python_version_tuple.return_value = ("2", "7", "10")
self.assertEqual(get_runtime_tag(), "runtime:python2.7")

self.mock_python_version_tuple.return_value = ("3", "7", "2")
self.assertEqual(get_runtime_tag(), "runtime:python3.7")

25 changes: 20 additions & 5 deletions tests/test_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def setUp(self):
self.addCleanup(patcher.stop)

patcher = patch("datadog_lambda.metric.lambda_metric")
self.mock_wrapper_lambda_metric = patcher.start()
self.mock_lambda_metric = patcher.start()
self.addCleanup(patcher.stop)

patcher = patch("datadog_lambda.wrapper.extract_dd_trace_context")
Expand All @@ -57,6 +57,11 @@ def setUp(self):
self.mock_is_cold_start.return_value = True
self.addCleanup(patcher.stop)

patcher = patch("datadog_lambda.tags.python_version_tuple")
self.mock_python_version_tuple = patcher.start()
self.mock_python_version_tuple.return_value = ("2", "7", "10")
self.addCleanup(patcher.stop)

def test_datadog_lambda_wrapper(self):
@datadog_lambda_wrapper
def lambda_handler(event, context):
Expand Down Expand Up @@ -116,7 +121,7 @@ def lambda_handler(event, context):

lambda_handler(lambda_event, get_mock_context())

self.mock_wrapper_lambda_metric.assert_has_calls(
self.mock_lambda_metric.assert_has_calls(
[
call(
"aws.lambda.enhanced.invocations",
Expand All @@ -126,6 +131,8 @@ def lambda_handler(event, context):
"account_id:123457598159",
"functionname:python-layer-test",
"cold_start:true",
"memorysize:256",
"runtime:python2.7",
],
)
]
Expand All @@ -145,7 +152,7 @@ def lambda_handler(event, context):
with self.assertRaises(RuntimeError):
lambda_handler(lambda_event, get_mock_context())

self.mock_wrapper_lambda_metric.assert_has_calls(
self.mock_lambda_metric.assert_has_calls(
[
call(
"aws.lambda.enhanced.invocations",
Expand All @@ -155,6 +162,8 @@ def lambda_handler(event, context):
"account_id:123457598159",
"functionname:python-layer-test",
"cold_start:true",
"memorysize:256",
"runtime:python2.7",
],
),
call(
Expand All @@ -165,6 +174,8 @@ def lambda_handler(event, context):
"account_id:123457598159",
"functionname:python-layer-test",
"cold_start:true",
"memorysize:256",
"runtime:python2.7",
],
),
]
Expand All @@ -189,7 +200,7 @@ def lambda_handler(event, context):
lambda_event, get_mock_context(aws_request_id="second-request-id")
)

self.mock_wrapper_lambda_metric.assert_has_calls(
self.mock_lambda_metric.assert_has_calls(
[
call(
"aws.lambda.enhanced.invocations",
Expand All @@ -199,6 +210,8 @@ def lambda_handler(event, context):
"account_id:123457598159",
"functionname:python-layer-test",
"cold_start:true",
"memorysize:256",
"runtime:python2.7",
],
),
call(
Expand All @@ -209,6 +222,8 @@ def lambda_handler(event, context):
"account_id:123457598159",
"functionname:python-layer-test",
"cold_start:false",
"memorysize:256",
"runtime:python2.7",
],
),
]
Expand All @@ -226,5 +241,5 @@ def lambda_handler(event, context):
with self.assertRaises(RuntimeError):
lambda_handler(lambda_event, get_mock_context())

self.mock_wrapper_lambda_metric.assert_not_called()
self.mock_lambda_metric.assert_not_called()

0 comments on commit d29de3b

Please sign in to comment.