Skip to content

Commit 2e1f0f4

Browse files
hamishfaggjamesls
authored andcommitted
Add ability to set log retention for lambda functions globally
1 parent 78a419f commit 2e1f0f4

File tree

5 files changed

+71
-0
lines changed

5 files changed

+71
-0
lines changed

chalice/awsclient.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,27 @@ def delete_role(self, name: str) -> None:
11101110
self.delete_role_policy(name, policy_name)
11111111
client.delete_role(RoleName=name)
11121112

1113+
def log_group_exists(self, name: str) -> bool:
1114+
"""Check if an CloudWatch LOG GROUP exists."""
1115+
client = self._client('logs')
1116+
result = client.describe_log_groups(
1117+
logGroupNamePrefix=name
1118+
)
1119+
if len(result['logGroups']) == 0:
1120+
return False
1121+
return True
1122+
1123+
def create_log_group(self, name: str) -> None:
1124+
self._client('logs').create_log_group(
1125+
logGroupName=name
1126+
)
1127+
1128+
def put_retention_policy(self, name: str, retention_in_days: int) -> None:
1129+
self._client('logs').put_retention_policy(
1130+
logGroupName=name,
1131+
retentionInDays=retention_in_days
1132+
)
1133+
11131134
def get_rest_api_id(self, name: str) -> Optional[str]:
11141135
"""Get rest api id associated with an API name.
11151136

chalice/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,10 @@ def lambda_python_version(self) -> str:
160160
return 'python3.8'
161161
return 'python3.9'
162162

163+
@property
164+
def log_retention_in_days(self) -> int:
165+
return self._chain_lookup('log_retention_in_days')
166+
163167
@property
164168
def layers(self) -> List:
165169
return self._chain_lookup('layers',

chalice/deploy/appgraph.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ def build(self, config, stage_name):
4848
resources.append(websocket_api)
4949
return models.Application(stage_name, resources)
5050

51+
def _create_log_group(self,
52+
config, # type: Config
53+
log_group_name # type: str
54+
):
55+
# type: (...) -> models.LogGroup
56+
return models.LogGroup(resource_name=log_group_name, retention_in_days=config.log_retention_in_days)
57+
5158
def _create_custom_domain_name(
5259
self,
5360
api_type, # type: models.APIType
@@ -367,6 +374,8 @@ def _create_lambda_model(self,
367374
new_config, name, handler_name,
368375
deployment, role
369376
)
377+
if config.log_retention_in_days:
378+
resource.log_group = self._create_log_group(config, '/aws/lambda/%s-%s-%s' % (config.app_name, stage_name, name))
370379
return resource
371380

372381
def _get_managed_lambda_layer(self, config):

chalice/deploy/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,12 +208,16 @@ class LambdaFunction(ManagedModel):
208208
layers = attrib() # type: List[str]
209209
managed_layer = attrib(
210210
default=None) # type: Opt[LambdaLayer]
211+
log_group = attrib(default=None) # type: LogGroup
212+
211213

212214
def dependencies(self):
213215
# type: () -> List[Model]
214216
resources = [] # type: List[Model]
215217
if self.managed_layer is not None:
216218
resources.append(self.managed_layer)
219+
if self.log_group is not None:
220+
resources.append(self.log_group)
217221
resources.extend([self.role, self.deployment_package])
218222
return resources
219223

@@ -245,6 +249,12 @@ class ScheduledEvent(CloudWatchEventBase):
245249
rule_description = attrib(default=None) # type: str
246250

247251

252+
@attrs
253+
class LogGroup(ManagedModel):
254+
resource_type = 'log_group'
255+
retention_in_days = attrib() # type: int
256+
257+
248258
@attrs
249259
class APIMapping(ManagedModel):
250260
resource_type = 'api_mapping'

chalice/deploy/planner.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,10 @@ def _resource_exists_lambdalayer(self, resource):
139139
return bool(self._client.get_layer_version(
140140
deployed_values['layer_version_arn']))
141141

142+
def _resource_exists_loggroup(self, resource):
143+
# type: (models.LogGroup) -> bool
144+
return self._client.log_group_exists(resource.resource_name)
145+
142146
def _resource_exists_lambdafunction(self, resource):
143147
# type: (models.LambdaFunction) -> bool
144148
return self._client.lambda_function_exists(resource.function_name)
@@ -820,6 +824,29 @@ def _plan_kinesiseventsource(self, resource):
820824
}
821825
)
822826

827+
def _plan_loggroup(self, resource):
828+
# type: (models.LogGroup) -> Sequence[InstructionMsg]
829+
instructions = [] # type: List[InstructionMsg]
830+
if self._remote_state.resource_exists(resource):
831+
return instructions + [
832+
models.APICall(
833+
method_name='put_retention_policy',
834+
params={'name': resource.resource_name,
835+
'retention_in_days': resource.retention_in_days}
836+
)
837+
]
838+
return instructions + [
839+
models.APICall(
840+
method_name='create_log_group',
841+
params={'name': resource.resource_name}
842+
),
843+
models.APICall(
844+
method_name='put_retention_policy',
845+
params={'name': resource.resource_name,
846+
'retention_in_days': resource.retention_in_days}
847+
)
848+
]
849+
823850
def _plan_dynamodbeventsource(self, resource):
824851
# type: (models.DynamoDBEventSource) -> Sequence[InstructionMsg]
825852
uuid_varname = '%s_uuid' % resource.resource_name

0 commit comments

Comments
 (0)