Skip to content

Commit 041fab1

Browse files
authored
feat(mongodb-log-writer): skip checks for retentionGB and maxLogFileCount when set to Infinity MONGOSH-2047 (#515)
1 parent ea915a1 commit 041fab1

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

packages/mongodb-log-writer/src/mongo-log-manager.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,32 @@ describe('MongoLogManager', function () {
316316
expect(await getFilesState(paths)).to.equal('0000111111');
317317
});
318318

319+
it('skips checking file storage if retentionGB is set to Infinity', async function () {
320+
const statStub = sinon.stub(fs, 'stat');
321+
322+
const manager = new MongoLogManager({
323+
directory,
324+
retentionDays,
325+
maxLogFileCount: 1000,
326+
retentionGB: Infinity,
327+
onwarn,
328+
onerror,
329+
});
330+
331+
const offset = Math.floor(Date.now() / 1000);
332+
for (let i = 0; i < 10; i++) {
333+
const filename = path.join(
334+
directory,
335+
ObjectId.createFromTime(offset - i).toHexString() + '_log'
336+
);
337+
await fs.writeFile(filename, '');
338+
}
339+
340+
await manager.cleanupOldLogFiles();
341+
342+
expect(statStub).not.called;
343+
});
344+
319345
describe('with a random file order', function () {
320346
let paths: string[] = [];
321347
const times = [92, 90, 1, 2, 3, 91];

packages/mongodb-log-writer/src/mongo-log-manager.ts

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,10 @@ export class MongoLogManager {
6262
}
6363

6464
/** 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> {
6669
const deletionStartTimestamp = Date.now();
6770
// Delete files older than N days
6871
const deletionCutoffTimestamp =
@@ -84,7 +87,13 @@ export class MongoLogManager {
8487
fileSize: number | undefined;
8588
}>((a, b) => a.fileTimestamp - b.fileTimestamp);
8689

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;
8897

8998
try {
9099
for await (const dirent of dirHandle) {
@@ -93,28 +102,28 @@ export class MongoLogManager {
93102
// where lots and lots of log files end up and filesystem operations happen
94103
// with network latency.
95104
if (Date.now() - deletionStartTimestamp > maxDurationMs) break;
96-
105+
97106
if (!dirent.isFile()) continue;
98107
const logRegExp = new RegExp(
99108
`^${this.prefix}(?<id>[a-f0-9]{24})_log(\\.gz)?$`,
100109
'i'
101110
);
102111
const { id } = logRegExp.exec(dirent.name)?.groups ?? {};
103112
if (!id) continue;
104-
113+
105114
const fileTimestamp = +new ObjectId(id).getTimestamp();
106115
const fullPath = path.join(dir, dirent.name);
107-
116+
108117
// If the file is older than expected, delete it. If the file is recent,
109118
// add it to the list of seen files, and if that list is too large, remove
110119
// the least recent file we've seen so far.
111120
if (fileTimestamp < deletionCutoffTimestamp) {
112121
await this.deleteFile(fullPath);
113122
continue;
114123
}
115-
124+
116125
let fileSize: number | undefined;
117-
if (this._options.retentionGB) {
126+
if (hasRetentionGB) {
118127
try {
119128
fileSize = (await fs.stat(fullPath)).size;
120129
usedStorageSize += fileSize;
@@ -123,12 +132,13 @@ export class MongoLogManager {
123132
continue;
124133
}
125134
}
126-
127-
if (this._options.maxLogFileCount || this._options.retentionGB) {
135+
136+
if (hasMaxLogFileCount || hasRetentionGB) {
128137
leastRecentFileHeap.push({ fullPath, fileTimestamp, fileSize });
129138
}
130-
139+
131140
if (
141+
hasMaxLogFileCount &&
132142
this._options.maxLogFileCount &&
133143
leastRecentFileHeap.size() > this._options.maxLogFileCount
134144
) {
@@ -145,11 +155,14 @@ export class MongoLogManager {
145155
// To handle such scenarios, we will catch lstat errors and retry cleaning up
146156
// to let different processes reach out to different log files.
147157
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+
);
149162
}
150163
}
151164

152-
if (this._options.retentionGB) {
165+
if (hasRetentionGB && this._options.retentionGB) {
153166
const storageSizeLimit = this._options.retentionGB * 1024 * 1024 * 1024;
154167

155168
for (const file of leastRecentFileHeap) {

0 commit comments

Comments
 (0)