@@ -62,7 +62,10 @@ export class MongoLogManager {
62
62
}
63
63
64
64
/** Clean up log files older than `retentionDays`. */
65
- async cleanupOldLogFiles ( maxDurationMs = 5_000 , remainingRetries = 1 ) : Promise < void > {
65
+ async cleanupOldLogFiles (
66
+ maxDurationMs = 5_000 ,
67
+ remainingRetries = 1
68
+ ) : Promise < void > {
66
69
const deletionStartTimestamp = Date . now ( ) ;
67
70
// Delete files older than N days
68
71
const deletionCutoffTimestamp =
@@ -84,7 +87,13 @@ export class MongoLogManager {
84
87
fileSize : number | undefined ;
85
88
} > ( ( a , b ) => a . fileTimestamp - b . fileTimestamp ) ;
86
89
87
- let usedStorageSize = this . _options . retentionGB ? 0 : - Infinity ;
90
+ const hasRetentionGB =
91
+ ! ! this . _options . retentionGB && isFinite ( this . _options . retentionGB ) ;
92
+ const hasMaxLogFileCount =
93
+ ! ! this . _options . maxLogFileCount &&
94
+ isFinite ( this . _options . maxLogFileCount ) ;
95
+
96
+ let usedStorageSize = hasRetentionGB ? 0 : - Infinity ;
88
97
89
98
try {
90
99
for await ( const dirent of dirHandle ) {
@@ -93,28 +102,28 @@ export class MongoLogManager {
93
102
// where lots and lots of log files end up and filesystem operations happen
94
103
// with network latency.
95
104
if ( Date . now ( ) - deletionStartTimestamp > maxDurationMs ) break ;
96
-
105
+
97
106
if ( ! dirent . isFile ( ) ) continue ;
98
107
const logRegExp = new RegExp (
99
108
`^${ this . prefix } (?<id>[a-f0-9]{24})_log(\\.gz)?$` ,
100
109
'i'
101
110
) ;
102
111
const { id } = logRegExp . exec ( dirent . name ) ?. groups ?? { } ;
103
112
if ( ! id ) continue ;
104
-
113
+
105
114
const fileTimestamp = + new ObjectId ( id ) . getTimestamp ( ) ;
106
115
const fullPath = path . join ( dir , dirent . name ) ;
107
-
116
+
108
117
// If the file is older than expected, delete it. If the file is recent,
109
118
// add it to the list of seen files, and if that list is too large, remove
110
119
// the least recent file we've seen so far.
111
120
if ( fileTimestamp < deletionCutoffTimestamp ) {
112
121
await this . deleteFile ( fullPath ) ;
113
122
continue ;
114
123
}
115
-
124
+
116
125
let fileSize : number | undefined ;
117
- if ( this . _options . retentionGB ) {
126
+ if ( hasRetentionGB ) {
118
127
try {
119
128
fileSize = ( await fs . stat ( fullPath ) ) . size ;
120
129
usedStorageSize += fileSize ;
@@ -123,12 +132,13 @@ export class MongoLogManager {
123
132
continue ;
124
133
}
125
134
}
126
-
127
- if ( this . _options . maxLogFileCount || this . _options . retentionGB ) {
135
+
136
+ if ( hasMaxLogFileCount || hasRetentionGB ) {
128
137
leastRecentFileHeap . push ( { fullPath, fileTimestamp, fileSize } ) ;
129
138
}
130
-
139
+
131
140
if (
141
+ hasMaxLogFileCount &&
132
142
this . _options . maxLogFileCount &&
133
143
leastRecentFileHeap . size ( ) > this . _options . maxLogFileCount
134
144
) {
@@ -145,11 +155,14 @@ export class MongoLogManager {
145
155
// To handle such scenarios, we will catch lstat errors and retry cleaning up
146
156
// to let different processes reach out to different log files.
147
157
if ( statErr . code === 'ENOENT' && remainingRetries > 0 ) {
148
- await this . cleanupOldLogFiles ( maxDurationMs - ( Date . now ( ) - deletionStartTimestamp ) , remainingRetries - 1 ) ;
158
+ await this . cleanupOldLogFiles (
159
+ maxDurationMs - ( Date . now ( ) - deletionStartTimestamp ) ,
160
+ remainingRetries - 1
161
+ ) ;
149
162
}
150
163
}
151
164
152
- if ( this . _options . retentionGB ) {
165
+ if ( hasRetentionGB && this . _options . retentionGB ) {
153
166
const storageSizeLimit = this . _options . retentionGB * 1024 * 1024 * 1024 ;
154
167
155
168
for ( const file of leastRecentFileHeap ) {
0 commit comments