@@ -6,6 +6,13 @@ import {
6
6
StackStatus ,
7
7
StackSummary ,
8
8
} from '@aws-sdk/client-cloudformation' ;
9
+ import {
10
+ CloudWatchLogsClient ,
11
+ DeleteLogGroupCommand ,
12
+ DescribeLogGroupsCommand ,
13
+ DescribeLogGroupsCommandOutput ,
14
+ LogGroup ,
15
+ } from '@aws-sdk/client-cloudwatch-logs' ;
9
16
import {
10
17
Bucket ,
11
18
DeleteBucketCommand ,
@@ -70,6 +77,9 @@ const amplifyClient = new AmplifyClient({
70
77
const cfnClient = new CloudFormationClient ( {
71
78
maxAttempts : 5 ,
72
79
} ) ;
80
+ const cloudWatchClient = new CloudWatchLogsClient ( {
81
+ maxAttempts : 5 ,
82
+ } ) ;
73
83
const cognitoClient = new CognitoIdentityProviderClient ( {
74
84
maxAttempts : 5 ,
75
85
} ) ;
@@ -91,6 +101,7 @@ const TEST_CDK_RESOURCE_PREFIX = 'test-cdk';
91
101
92
102
/**
93
103
* Stacks are considered stale after 2 hours.
104
+ * Log groups are considered stale after 7 days. For troubleshooting purposes.
94
105
* Other resources are considered stale after 3 hours.
95
106
*
96
107
* Stack deletion triggers asynchronous resource deletion while this script is running.
@@ -100,6 +111,7 @@ const TEST_CDK_RESOURCE_PREFIX = 'test-cdk';
100
111
*/
101
112
const stackStaleDurationInMilliseconds = 2 * 60 * 60 * 1000 ; // 2 hours in milliseconds
102
113
const staleDurationInMilliseconds = 3 * 60 * 60 * 1000 ; // 3 hours in milliseconds
114
+ const logGroupStaleDurationInMilliseconds = 7 * 24 * 60 * 60 * 1000 ; // 7 days in milliseconds
103
115
104
116
const isStackStale = (
105
117
stackSummary : StackSummary | undefined
@@ -113,6 +125,17 @@ const isStackStale = (
113
125
) ;
114
126
} ;
115
127
128
+ const isLogGroupStale = (
129
+ logGroup : LogGroup | undefined
130
+ ) : boolean | undefined => {
131
+ if ( ! logGroup ?. creationTime ) {
132
+ return ;
133
+ }
134
+ return (
135
+ now . getTime ( ) - logGroup . creationTime > logGroupStaleDurationInMilliseconds
136
+ ) ;
137
+ } ;
138
+
116
139
const isStale = ( creationDate : Date | undefined ) : boolean | undefined => {
117
140
if ( ! creationDate ) {
118
141
return ;
@@ -546,3 +569,47 @@ for (const staleDynamoDBTable of allStaleDynamoDBTables) {
546
569
) ;
547
570
}
548
571
}
572
+
573
+ const listAllStaleTestLogGroups = async ( ) : Promise < Array < LogGroup > > => {
574
+ let nextToken : string | undefined = undefined ;
575
+ const logGroups : Array < LogGroup > = [ ] ;
576
+ do {
577
+ const listLogGroupsResponse : DescribeLogGroupsCommandOutput =
578
+ await cloudWatchClient . send (
579
+ new DescribeLogGroupsCommand ( {
580
+ nextToken,
581
+ } )
582
+ ) ;
583
+ nextToken = listLogGroupsResponse . nextToken ;
584
+ listLogGroupsResponse . logGroups
585
+ ?. filter (
586
+ ( logGroup ) =>
587
+ ( logGroup . logGroupName ?. startsWith ( TEST_AMPLIFY_RESOURCE_PREFIX ) ||
588
+ logGroup . logGroupName ?. startsWith (
589
+ `/aws/lambda/${ TEST_AMPLIFY_RESOURCE_PREFIX } `
590
+ ) ) &&
591
+ isLogGroupStale ( logGroup )
592
+ )
593
+ . forEach ( ( item ) => {
594
+ logGroups . push ( item ) ;
595
+ } ) ;
596
+ } while ( nextToken ) ;
597
+ return logGroups ;
598
+ } ;
599
+
600
+ const allStaleLogGroups = await listAllStaleTestLogGroups ( ) ;
601
+ for ( const logGroup of allStaleLogGroups ) {
602
+ try {
603
+ await cloudWatchClient . send (
604
+ new DeleteLogGroupCommand ( {
605
+ logGroupName : logGroup . logGroupName ,
606
+ } )
607
+ ) ;
608
+ console . log ( `Successfully deleted ${ logGroup . logGroupName } log group` ) ;
609
+ } catch ( e ) {
610
+ const errorMessage = e instanceof Error ? e . message : '' ;
611
+ console . log (
612
+ `Failed to delete ${ logGroup . logGroupName } log group. ${ errorMessage } `
613
+ ) ;
614
+ }
615
+ }
0 commit comments