Skip to content

Commit 6bb2e37

Browse files
committed
feat(mongodb-log-writer): add ability to specify a prefix for log files
This is needed for mongosh to use a `mongosh_` prefix for custom log directories.
1 parent b638b34 commit 6bb2e37

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

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

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,19 @@ describe('MongoLogManager', function () {
5959
expect(log[0].t.$date).to.be.a('string');
6060
});
6161

62+
it('can take a custom prefix for log files', async function () {
63+
const manager = new MongoLogManager({
64+
directory,
65+
retentionDays,
66+
prefix: 'custom_',
67+
onwarn,
68+
onerror,
69+
});
70+
71+
const writer = await manager.createLogWriter();
72+
expect(writer.logFilePath as string).to.match(/custom_/);
73+
});
74+
6275
it('cleans up old log files when requested', async function () {
6376
retentionDays = 0.000001; // 86.4 ms
6477
const manager = new MongoLogManager({
@@ -124,6 +137,56 @@ describe('MongoLogManager', function () {
124137
expect(await getFilesState(paths)).to.equal('0000011111');
125138
});
126139

140+
it('cleanup only applies to files with the prefix, if set', async function () {
141+
const manager = new MongoLogManager({
142+
directory,
143+
retentionDays,
144+
maxLogFileCount: 7,
145+
prefix: 'custom_',
146+
onwarn,
147+
onerror,
148+
});
149+
150+
const paths: string[] = [];
151+
const offset = Math.floor(Date.now() / 1000);
152+
153+
// Create 4 files: 2 with a different prefix and 2 with no prefix
154+
for (let i = 1; i >= 0; i--) {
155+
const withoutPrefix = path.join(
156+
directory,
157+
ObjectId.createFromTime(offset - i).toHexString() + '_log'
158+
);
159+
await fs.writeFile(withoutPrefix, '');
160+
paths.push(withoutPrefix);
161+
162+
const withDifferentPrefix = path.join(
163+
directory,
164+
'different_' +
165+
ObjectId.createFromTime(offset - i).toHexString() +
166+
'_log'
167+
);
168+
await fs.writeFile(withDifferentPrefix, '');
169+
paths.push(withDifferentPrefix);
170+
}
171+
172+
// Create 10 files with the prefix
173+
for (let i = 9; i >= 0; i--) {
174+
const filename = path.join(
175+
directory,
176+
`custom_${ObjectId.createFromTime(offset - i).toHexString()}_log`
177+
);
178+
await fs.writeFile(filename, '');
179+
paths.push(filename);
180+
}
181+
182+
expect(await getFilesState(paths)).to.equal('11111111111111');
183+
await manager.cleanupOldLogFiles();
184+
185+
// The first 4 files without the right prefix should still be there.
186+
// The next (oldest) 3 files with the prefix should be deleted.
187+
expect(await getFilesState(paths)).to.equal('11110001111111');
188+
});
189+
127190
it('cleans up least recent log files when requested with a storage limit', async function () {
128191
const manager = new MongoLogManager({
129192
directory,

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

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ interface MongoLogOptions {
1919
maxLogFileCount?: number;
2020
/** The maximal GB of log files which are kept. */
2121
logRetentionGB?: number;
22+
/** Prefix to use for the log files */
23+
prefix?: string;
2224
/** A handler for warnings related to a specific filesystem path. */
2325
onerror: (err: Error, path: string) => unknown | Promise<void>;
2426
/** A handler for errors related to a specific filesystem path. */
@@ -37,6 +39,10 @@ export class MongoLogManager {
3739
this._options = options;
3840
}
3941

42+
private get prefix() {
43+
return this._options.prefix ?? '';
44+
}
45+
4046
/** Clean up log files older than `retentionDays`. */
4147
async cleanupOldLogFiles(maxDurationMs = 5_000): Promise<void> {
4248
const dir = this._options.directory;
@@ -73,8 +79,11 @@ export class MongoLogManager {
7379
if (Date.now() - deletionStartTimestamp > maxDurationMs) break;
7480

7581
if (!dirent.isFile()) continue;
76-
const { id } =
77-
/^(?<id>[a-f0-9]{24})_log(\.gz)?$/i.exec(dirent.name)?.groups ?? {};
82+
const logRegExp = new RegExp(
83+
`^${this.prefix}(?<id>[a-f0-9]{24})_log(\\.gz)?$`,
84+
'i'
85+
);
86+
const { id } = logRegExp.exec(dirent.name)?.groups ?? {};
7887
if (!id) continue;
7988
const fileTimestamp = +new ObjectId(id).getTimestamp();
8089
const fullPath = path.join(dir, dirent.name);
@@ -141,7 +150,7 @@ export class MongoLogManager {
141150
const doGzip = !!this._options.gzip;
142151
const logFilePath = path.join(
143152
this._options.directory,
144-
`${logId}_log${doGzip ? '.gz' : ''}`
153+
`${this.prefix}${logId}_log${doGzip ? '.gz' : ''}`
145154
);
146155

147156
let originalTarget: Writable;

0 commit comments

Comments
 (0)