Skip to content

Commit a15982f

Browse files
feat(event_source): Add support for policyLevel field in CloudWatch Logs event and parser (aws-powertools#3624)
Adding new policyLevel field
1 parent a7ebb3d commit a15982f

File tree

5 files changed

+72
-1
lines changed

5 files changed

+72
-1
lines changed

aws_lambda_powertools/utilities/data_classes/cloud_watch_logs_event.py

+5
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,11 @@ def message_type(self) -> str:
5858
"""
5959
return self["messageType"]
6060

61+
@property
62+
def policy_level(self) -> Optional[str]:
63+
"""The level at which the policy was enforced."""
64+
return self.get("policyLevel")
65+
6166
@property
6267
def log_events(self) -> List[CloudWatchLogsLogEvent]:
6368
"""The actual log data, represented as an array of log event records.

aws_lambda_powertools/utilities/parser/models/cloudwatch.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import logging
44
import zlib
55
from datetime import datetime
6-
from typing import Type, Union
6+
from typing import Optional, Type, Union
77

88
from pydantic import BaseModel, Field, validator
99

@@ -25,6 +25,7 @@ class CloudWatchLogsDecode(BaseModel):
2525
logStream: str
2626
subscriptionFilters: List[str]
2727
logEvents: List[CloudWatchLogsLogEvent]
28+
policyLevel: Optional[str] = None
2829

2930

3031
class CloudWatchLogsData(BaseModel):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"awslogs": {
3+
"data": "eNqFj0+LwjAQxe9+ipCzh7Yb1z+30o0ixO3SdhdEpNR2kEDblCTuIuJ33yS1i4dFL0Nmfi/vzVxGCOEGlCqOkJ07wAuE38IszDc0TcMVxWMrED8tSIv84IVMXqezuXn0qBbHlRSnzlINSrOhH2iqJRTNHb4NHFengyol7zQX7ZLXGqQyyp2T9j3eD0b0G1rtsBkgdHHVIF5Zc7B0XfnO1801N3fporGr+YR4hATz2dTzvD/F7W77fUeTJE72aMml0sjGo4E69XX8IDR4Huo/Ck2hFG31X6qp/f2dqHl5ZiawxgscRlH8+Z7ljH5Rln/EbB1t8ej6C87if5I="
4+
}
5+
}

tests/unit/data_classes/test_cloud_watch_logs_event.py

+29
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ def test_cloud_watch_trigger_event():
1919
assert json_logs_data.log_stream == "testLogStream"
2020
assert json_logs_data.subscription_filters == ["testFilter"]
2121
assert json_logs_data.message_type == "DATA_MESSAGE"
22+
assert json_logs_data.policy_level is None
2223

2324
assert log_event.get_id == "eventId1"
2425
assert log_event.timestamp == 1440442987000
@@ -27,3 +28,31 @@ def test_cloud_watch_trigger_event():
2728

2829
event2 = CloudWatchLogsEvent(load_event("cloudWatchLogEvent.json"))
2930
assert parsed_event.raw_event == event2.raw_event
31+
32+
33+
def test_cloud_watch_trigger_event_with_policy_level():
34+
raw_event = load_event("cloudWatchLogEventWithPolicyLevel.json")
35+
parsed_event = CloudWatchLogsEvent(raw_event)
36+
37+
decompressed_logs_data = parsed_event.decompress_logs_data
38+
assert parsed_event.decompress_logs_data == decompressed_logs_data
39+
40+
json_logs_data = parsed_event.parse_logs_data()
41+
assert parsed_event.parse_logs_data().raw_event == json_logs_data.raw_event
42+
log_events = json_logs_data.log_events
43+
log_event = log_events[0]
44+
45+
assert json_logs_data.owner == "123456789123"
46+
assert json_logs_data.log_group == "testLogGroup"
47+
assert json_logs_data.log_stream == "testLogStream"
48+
assert json_logs_data.subscription_filters == ["testFilter"]
49+
assert json_logs_data.message_type == "DATA_MESSAGE"
50+
assert json_logs_data.policy_level == "ACCOUNT_LEVEL_POLICY"
51+
52+
assert log_event.get_id == "eventId1"
53+
assert log_event.timestamp == 1440442987000
54+
assert log_event.message == "[ERROR] First test message"
55+
assert log_event.extracted_fields is None
56+
57+
event2 = CloudWatchLogsEvent(load_event("cloudWatchLogEventWithPolicyLevel.json"))
58+
assert parsed_event.raw_event == event2.raw_event

tests/unit/parser/test_cloudwatch.py

+31
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,37 @@ def test_handle_cloudwatch_trigger_event_no_envelope():
6363
assert parsed_event.awslogs.decoded_data.logStream == raw_event_decoded["logStream"]
6464
assert parsed_event.awslogs.decoded_data.subscriptionFilters == raw_event_decoded["subscriptionFilters"]
6565
assert parsed_event.awslogs.decoded_data.messageType == raw_event_decoded["messageType"]
66+
assert parsed_event.awslogs.decoded_data.policyLevel is None
67+
68+
assert len(parsed_event.awslogs.decoded_data.logEvents) == 2
69+
70+
log_record: CloudWatchLogsLogEvent = parsed_event.awslogs.decoded_data.logEvents[0]
71+
raw_log_record = raw_event_decoded["logEvents"][0]
72+
assert log_record.id == raw_log_record["id"]
73+
convert_time = int(round(log_record.timestamp.timestamp() * 1000))
74+
assert convert_time == raw_log_record["timestamp"]
75+
assert log_record.message == raw_log_record["message"]
76+
77+
log_record: CloudWatchLogsLogEvent = parsed_event.awslogs.decoded_data.logEvents[1]
78+
raw_log_record = raw_event_decoded["logEvents"][1]
79+
assert log_record.id == raw_log_record["id"]
80+
convert_time = int(round(log_record.timestamp.timestamp() * 1000))
81+
assert convert_time == raw_log_record["timestamp"]
82+
assert log_record.message == raw_log_record["message"]
83+
84+
85+
def test_handle_cloudwatch_trigger_event_no_envelope_with_policylevel():
86+
raw_event = load_event("cloudWatchLogEventWithPolicyLevel.json")
87+
parsed_event: CloudWatchLogsModel = CloudWatchLogsModel(**raw_event)
88+
89+
raw_event_decoded = decode_cloudwatch_raw_event(raw_event["awslogs"]["data"])
90+
91+
assert parsed_event.awslogs.decoded_data.owner == raw_event_decoded["owner"]
92+
assert parsed_event.awslogs.decoded_data.logGroup == raw_event_decoded["logGroup"]
93+
assert parsed_event.awslogs.decoded_data.logStream == raw_event_decoded["logStream"]
94+
assert parsed_event.awslogs.decoded_data.subscriptionFilters == raw_event_decoded["subscriptionFilters"]
95+
assert parsed_event.awslogs.decoded_data.messageType == raw_event_decoded["messageType"]
96+
assert parsed_event.awslogs.decoded_data.policyLevel == "ACCOUNT_LEVEL_POLICY"
6697

6798
assert len(parsed_event.awslogs.decoded_data.logEvents) == 2
6899

0 commit comments

Comments
 (0)