Feature cloudwatch log retention (#2199)

* add proper retentionInDays to describe_log_groups response and add support for delete_retention_policy() and put_retention_policy() to log groups

* fix for inline comment formatting

* include check for retentionInDays to verify no retention by default in  test_log_group_create
This commit is contained in:
Jon Beilke 2019-05-25 04:14:23 -05:00 committed by Terry Cain
parent 2a5f7e15a7
commit cb72d1d00e
3 changed files with 68 additions and 2 deletions

View File

@ -137,6 +137,7 @@ class LogGroup:
self.creationTime = unix_time_millis()
self.tags = tags
self.streams = dict() # {name: LogStream}
self.retentionInDays = None # AWS defaults to Never Expire for log group retention
def create_log_stream(self, log_stream_name):
if log_stream_name in self.streams:
@ -201,14 +202,20 @@ class LogGroup:
return events_page, next_token, searched_streams
def to_describe_dict(self):
return {
log_group = {
"arn": self.arn,
"creationTime": self.creationTime,
"logGroupName": self.name,
"metricFilterCount": 0,
"retentionInDays": 30,
"storedBytes": sum(s.storedBytes for s in self.streams.values()),
}
# AWS only returns retentionInDays if a value is set for the log group (ie. not Never Expire)
if self.retentionInDays:
log_group["retentionInDays"] = self.retentionInDays
return log_group
def set_retention_policy(self, retention_in_days):
self.retentionInDays = retention_in_days
class LogsBackend(BaseBackend):
@ -289,5 +296,17 @@ class LogsBackend(BaseBackend):
log_group = self.groups[log_group_name]
return log_group.filter_log_events(log_group_name, log_stream_names, start_time, end_time, limit, next_token, filter_pattern, interleaved)
def put_retention_policy(self, log_group_name, retention_in_days):
if log_group_name not in self.groups:
raise ResourceNotFoundException()
log_group = self.groups[log_group_name]
return log_group.set_retention_policy(retention_in_days)
def delete_retention_policy(self, log_group_name):
if log_group_name not in self.groups:
raise ResourceNotFoundException()
log_group = self.groups[log_group_name]
return log_group.set_retention_policy(None)
logs_backends = {region.name: LogsBackend(region.name) for region in boto.logs.regions()}

View File

@ -123,3 +123,14 @@ class LogsResponse(BaseResponse):
"nextToken": next_token,
"searchedLogStreams": searched_streams
})
def put_retention_policy(self):
log_group_name = self._get_param('logGroupName')
retention_in_days = self._get_param('retentionInDays')
self.logs_backend.put_retention_policy(log_group_name, retention_in_days)
return ''
def delete_retention_policy(self):
log_group_name = self._get_param('logGroupName')
self.logs_backend.delete_retention_policy(log_group_name)
return ''

View File

@ -17,6 +17,8 @@ def test_log_group_create():
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response['logGroups']) == 1
# AWS defaults to Never Expire for log group retention
assert response['logGroups'][0].get('retentionInDays') == None
response = conn.delete_log_group(logGroupName=log_group_name)
@ -126,3 +128,37 @@ def test_filter_logs_interleaved():
resulting_event['timestamp'].should.equal(original_message['timestamp'])
resulting_event['message'].should.equal(original_message['message'])
@mock_logs
def test_put_retention_policy():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
response = conn.create_log_group(logGroupName=log_group_name)
response = conn.put_retention_policy(logGroupName=log_group_name, retentionInDays=7)
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response['logGroups']) == 1
assert response['logGroups'][0].get('retentionInDays') == 7
response = conn.delete_log_group(logGroupName=log_group_name)
@mock_logs
def test_delete_retention_policy():
conn = boto3.client('logs', 'us-west-2')
log_group_name = 'dummy'
response = conn.create_log_group(logGroupName=log_group_name)
response = conn.put_retention_policy(logGroupName=log_group_name, retentionInDays=7)
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response['logGroups']) == 1
assert response['logGroups'][0].get('retentionInDays') == 7
response = conn.delete_retention_policy(logGroupName=log_group_name)
response = conn.describe_log_groups(logGroupNamePrefix=log_group_name)
assert len(response['logGroups']) == 1
assert response['logGroups'][0].get('retentionInDays') == None
response = conn.delete_log_group(logGroupName=log_group_name)