Skip to content

Commit 88eeaee

Browse files
committed
skip logs where keys dont exist
1 parent c6e7b2a commit 88eeaee

2 files changed

Lines changed: 49 additions & 12 deletions

File tree

aws/logs_monitoring/enhanced_lambda_metrics.py

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,9 @@ def parse_metrics_from_json_report_log(log_message):
289289
metrics = []
290290

291291
for record_key, metric_name in RUNTIME_METRICS_BY_RECORD_KEY.items():
292-
metric_point_value = record_metrics[record_key]
292+
metric_point_value = record_metrics.get(record_key)
293+
if metric_point_value is None:
294+
continue
293295

294296
if metric_name in METRIC_ADJUSTMENT_FACTORS:
295297
metric_point_value *= METRIC_ADJUSTMENT_FACTORS[metric_name]
@@ -301,9 +303,10 @@ def parse_metrics_from_json_report_log(log_message):
301303
)
302304
)
303305

304-
tags = [
305-
f"{MEMORY_ALLOCATED_FIELD_NAME}:{record_metrics[MEMORY_ALLOCATED_RECORD_KEY]}"
306-
]
306+
tags = []
307+
memory_allocated = record_metrics.get(MEMORY_ALLOCATED_RECORD_KEY)
308+
if memory_allocated is not None:
309+
tags.append(f"{MEMORY_ALLOCATED_FIELD_NAME}:{memory_allocated}")
307310

308311
init_duration = record_metrics.get(INIT_DURATION_RECORD_KEY)
309312
if init_duration:
@@ -317,15 +320,19 @@ def parse_metrics_from_json_report_log(log_message):
317320
else:
318321
tags.append("cold_start:false")
319322

320-
metrics.append(
321-
DatadogMetricPoint(
322-
f"{ENHANCED_METRICS_NAMESPACE_PREFIX}.{ESTIMATED_COST_METRIC_NAME}",
323-
calculate_estimated_cost(
324-
record_metrics[BILLED_DURATION_RECORD_KEY],
325-
record_metrics[MEMORY_ALLOCATED_RECORD_KEY],
326-
),
323+
# Billed duration only available for On-Demand Lambda functions, for Managed Instances,
324+
# billed duration is no longer available.
325+
billed_duration = record_metrics.get(BILLED_DURATION_RECORD_KEY)
326+
if billed_duration is not None and memory_allocated is not None:
327+
metrics.append(
328+
DatadogMetricPoint(
329+
f"{ENHANCED_METRICS_NAMESPACE_PREFIX}.{ESTIMATED_COST_METRIC_NAME}",
330+
calculate_estimated_cost(
331+
billed_duration,
332+
memory_allocated,
333+
),
334+
)
327335
)
328-
)
329336

330337
if record.get("status") == "timeout":
331338
metrics.append(

aws/logs_monitoring/tests/test_enhanced_lambda_metrics.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,23 @@ class TestEnhancedLambdaMetrics(unittest.TestCase):
8686
},
8787
}
8888
)
89+
managed_instances_metrics_json_report = json.dumps(
90+
{
91+
"time": "2026-01-08T18:22:35.343Z",
92+
"type": "platform.report",
93+
"record": {
94+
"requestId": "4f423807-598d-47ae-9652-4f7ee31d4d10",
95+
"metrics": {
96+
"durationMs": 2.524,
97+
},
98+
"spans": [
99+
{"name": "responseLatency", "start": "2026-01-08T18:22:35.342Z", "durationMs": 0.642},
100+
{"name": "responseDuration", "start": "2026-01-08T18:22:35.343Z", "durationMs": 0.075},
101+
],
102+
"status": "success",
103+
},
104+
}
105+
)
89106

90107
def test_parse_lambda_tags_from_arn(self):
91108
verify_as_json(
@@ -129,6 +146,19 @@ def test_parse_metrics_from_timeout_json_report_log(self):
129146
parsed_metrics = parse_metrics_from_json_report_log(self.timeout_json_report)
130147
verify_as_json(parsed_metrics)
131148

149+
def test_parse_metrics_from_partial_metrics_json_report_log(self):
150+
"""Test that JSON report logs with partial/incomplete metrics don't raise KeyError"""
151+
parsed_metrics = parse_metrics_from_json_report_log(self.managed_instances_metrics_json_report)
152+
# Should only return metrics that are present (duration in this case)
153+
# Should not raise KeyError for missing billedDurationMs, maxMemoryUsedMB, memorySizeMB
154+
assert len(parsed_metrics) == 1 # Only duration metric
155+
assert parsed_metrics[0].name == "aws.lambda.enhanced.duration"
156+
# Duration should be converted from ms to seconds (2.524 * 0.001 = 0.002524)
157+
assert parsed_metrics[0].value == 0.002524
158+
# Tags should include cold_start:false but NOT memorysize since it's missing
159+
assert "cold_start:false" in parsed_metrics[0].tags
160+
assert not any(tag.startswith("memorysize:") for tag in parsed_metrics[0].tags)
161+
132162
def test_create_out_of_memory_enhanced_metric(self):
133163
go_out_of_memory_error = "fatal error: runtime: out of memory"
134164
self.assertEqual(

0 commit comments

Comments
 (0)