Skip to content

Commit f290ae3

Browse files
authored
AWS Lambda: ARN Normalization (#242)
1 parent 80affd1 commit f290ae3

File tree

5 files changed

+61
-8
lines changed

5 files changed

+61
-8
lines changed

instana/agent/aws_lambda.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def get_from_structure(self):
5353
Retrieves the From data that is reported alongside monitoring data.
5454
@return: dict()
5555
"""
56-
return {'hl': True, 'cp': 'aws', 'e': self.collector.context.invoked_function_arn}
56+
return {'hl': True, 'cp': 'aws', 'e': self.collector.get_fq_arn()}
5757

5858
def report_data_payload(self, payload):
5959
"""
@@ -65,7 +65,7 @@ def report_data_payload(self, payload):
6565
# Prepare request headers
6666
self.report_headers = dict()
6767
self.report_headers["Content-Type"] = "application/json"
68-
self.report_headers["X-Instana-Host"] = self.collector.context.invoked_function_arn
68+
self.report_headers["X-Instana-Host"] = self.collector.get_fq_arn()
6969
self.report_headers["X-Instana-Key"] = self.options.agent_key
7070
self.report_headers["X-Instana-Time"] = str(round(time.time() * 1000))
7171

instana/collector.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import threading
44

55
from .log import logger
6-
from .util import every, DictionaryOfStan
6+
from .util import every, DictionaryOfStan, normalize_aws_lambda_arn
77

88

99
if sys.version_info.major == 2:
@@ -24,6 +24,7 @@ def __init__(self, agent):
2424
self.snapshot_data = None
2525
self.snapshot_data_sent = False
2626
self.lock = threading.Lock()
27+
self._fq_arn = None
2728

2829
def start(self):
2930
if self.agent.can_send():
@@ -87,13 +88,24 @@ def collect_snapshot(self, event, context):
8788
try:
8889
plugin_data = dict()
8990
plugin_data["name"] = "com.instana.plugin.aws.lambda"
90-
plugin_data["entityId"] = self.context.invoked_function_arn
91+
plugin_data["entityId"] = self.get_fq_arn()
9192
self.snapshot_data["plugins"] = [plugin_data]
9293
except:
9394
logger.debug("collect_snapshot error", exc_info=True)
9495
finally:
9596
return self.snapshot_data
9697

98+
def get_fq_arn(self):
99+
if self._fq_arn is not None:
100+
return self._fq_arn
101+
102+
if self.context is None:
103+
logger.debug("Attempt to get qualified ARN before the context object is available")
104+
return ''
105+
106+
self._fq_arn = normalize_aws_lambda_arn(self.context)
107+
return self._fq_arn
108+
97109
def __queued_spans(self):
98110
""" Get all of the spans in the queue """
99111
span = None

instana/instrumentation/aws/triggers.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ def enrich_lambda_span(agent, span, event, context):
119119
@return: None
120120
"""
121121
try:
122-
span.set_tag('lambda.arn', context.invoked_function_arn)
122+
span.set_tag('lambda.arn', agent.collector.get_fq_arn())
123123
span.set_tag('lambda.name', context.function_name)
124124
span.set_tag('lambda.version', context.function_version)
125125

instana/util.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,3 +374,30 @@ def determine_service_name():
374374
except Exception as e:
375375
logger.debug("get_application_name: ", exc_info=True)
376376
return app_name
377+
378+
379+
def normalize_aws_lambda_arn(context):
380+
"""
381+
Parse the AWS Lambda context object for a fully qualified AWS Lambda function ARN.
382+
383+
This method will ensure that the returned value matches the following ARN pattern:
384+
arn:aws:lambda:${region}:${account-id}:function:${name}:${version}
385+
386+
@param context: AWS Lambda context object
387+
@return:
388+
"""
389+
try:
390+
arn = context.invoked_function_arn
391+
parts = arn.split(':')
392+
393+
count = len(parts)
394+
if count == 7:
395+
# need to append version
396+
arn = arn + ':' + context.function_version
397+
elif count != 8:
398+
logger.debug("Unexpected ARN parse issue: %s", arn)
399+
400+
return arn
401+
except:
402+
logger.debug("normalize_arn: ", exc_info=True)
403+

tests/platforms/test_lambda.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,13 @@
1515
from instana.instrumentation.aws.lambda_inst import lambda_handler_with_instana
1616
from instana.instrumentation.aws.triggers import read_http_query_params
1717
from instana.singletons import get_agent, set_agent, get_tracer, set_tracer
18+
from instana.util import normalize_aws_lambda_arn
1819

1920

2021
# Mock Context object
21-
class TestContext(dict):
22+
class MockContext(dict):
2223
def __init__(self, **kwargs):
23-
super(TestContext, self).__init__(**kwargs)
24+
super(MockContext, self).__init__(**kwargs)
2425
self.invoked_function_arn = "arn:aws:lambda:us-east-2:12345:function:TestPython:1"
2526
self.function_name = "TestPython"
2627
self.function_version = "1"
@@ -52,7 +53,7 @@ def setUp(self):
5253
os.environ["LAMBDA_HANDLER"] = "tests.platforms.test_lambda.my_lambda_handler"
5354
os.environ["INSTANA_ENDPOINT_URL"] = "https://localhost/notreal"
5455
os.environ["INSTANA_AGENT_KEY"] = "Fake_Key"
55-
self.context = TestContext()
56+
self.context = MockContext()
5657

5758
def tearDown(self):
5859
""" Reset all environment variables of consequence """
@@ -535,3 +536,16 @@ def test_read_query_params_with_bad_event(self):
535536
event = None
536537
params = read_http_query_params(event)
537538
self.assertEqual("", params)
539+
540+
def test_arn_parsing(self):
541+
ctx = MockContext()
542+
543+
assert(normalize_aws_lambda_arn(ctx) == "arn:aws:lambda:us-east-2:12345:function:TestPython:1")
544+
545+
# Without version should return a fully qualified ARN (with version)
546+
ctx.invoked_function_arn = "arn:aws:lambda:us-east-2:12345:function:TestPython"
547+
assert(normalize_aws_lambda_arn(ctx) == "arn:aws:lambda:us-east-2:12345:function:TestPython:1")
548+
549+
# Fully qualified already with the '$LATEST' special tag
550+
ctx.invoked_function_arn = "arn:aws:lambda:us-east-2:12345:function:TestPython:$LATEST"
551+
assert(normalize_aws_lambda_arn(ctx) == "arn:aws:lambda:us-east-2:12345:function:TestPython:$LATEST")

0 commit comments

Comments
 (0)