Skip to content

Commit dbec2ef

Browse files
authored
feat(cli-repl): use mongosh_ prefix for logs in custom locations MONGOSH-2012 (#2365)
1 parent 3c085d2 commit dbec2ef

File tree

7 files changed

+163
-67
lines changed

7 files changed

+163
-67
lines changed

package-lock.json

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cli-repl/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
"is-recoverable-error": "^1.0.3",
8686
"js-yaml": "^4.1.0",
8787
"mongodb-connection-string-url": "^3.0.1",
88-
"mongodb-log-writer": "^2.3.0",
88+
"mongodb-log-writer": "^2.3.1",
8989
"numeral": "^2.0.6",
9090
"pretty-repl": "^4.0.1",
9191
"semver": "^7.5.4",

packages/cli-repl/src/cli-repl.spec.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1433,7 +1433,7 @@ describe('CliRepl', function () {
14331433
});
14341434

14351435
const customLogLocation = useTmpdir();
1436-
it('can set the log location', async function () {
1436+
it('can set the log location and uses a prefix', async function () {
14371437
cliRepl.config.logLocation = customLogLocation.path;
14381438
await cliRepl.start(await testServer.connectionString(), {});
14391439

@@ -1443,7 +1443,26 @@ describe('CliRepl', function () {
14431443
expect(cliRepl.logWriter?.logFilePath).equals(
14441444
path.join(
14451445
customLogLocation.path,
1446-
(cliRepl.logWriter?.logId as string) + '_log'
1446+
'mongosh_' + (cliRepl.logWriter?.logId as string) + '_log'
1447+
)
1448+
);
1449+
});
1450+
1451+
it('uses a prefix even if the custom location is the same as the home location', async function () {
1452+
// This is a corner case where the custom location is the same as the home location.
1453+
// The prefix is still added to the log file name for consistency. If the user needs
1454+
// the default behavior for the log names, they should instead set the location to undefined.
1455+
const customLogHomePath = cliRepl.shellHomeDirectory.localPath('.');
1456+
cliRepl.config.logLocation = customLogHomePath;
1457+
await cliRepl.start(await testServer.connectionString(), {});
1458+
1459+
expect(await cliRepl.getConfig('logLocation')).equals(
1460+
customLogHomePath
1461+
);
1462+
expect(cliRepl.logWriter?.logFilePath).equals(
1463+
path.join(
1464+
customLogHomePath,
1465+
'mongosh_' + (cliRepl.logWriter?.logId as string) + '_log'
14471466
)
14481467
);
14491468
});

packages/cli-repl/src/cli-repl.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,10 +255,11 @@ export class CliRepl implements MongoshIOProvider {
255255
throw new Error('Logging and telemetry not setup');
256256
}
257257

258+
const customLogLocation = await this.getConfig('logLocation');
259+
258260
this.logManager ??= new MongoLogManager({
259-
directory:
260-
(await this.getConfig('logLocation')) ||
261-
this.shellHomeDirectory.localPath('.'),
261+
directory: customLogLocation || this.shellHomeDirectory.localPath('.'),
262+
prefix: customLogLocation ? 'mongosh_' : undefined,
262263
retentionDays: await this.getConfig('logRetentionDays'),
263264
gzip: await this.getConfig('logCompressionEnabled'),
264265
maxLogFileCount: await this.getConfig('logMaxFileCount'),

packages/e2e-tests/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"strip-ansi": "^6.0.0"
3434
},
3535
"devDependencies": {
36-
"mongodb-log-writer": "^2.3.0",
36+
"mongodb-log-writer": "^2.3.1",
3737
"@mongodb-js/eslint-config-mongosh": "^1.0.0",
3838
"@mongodb-js/oidc-mock-provider": "^0.10.2",
3939
"@mongodb-js/prettier-config-devtools": "^1.0.1",

packages/e2e-tests/test/e2e.spec.ts

Lines changed: 123 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1407,7 +1407,7 @@ describe('e2e', function () {
14071407
}
14081408
const logPath = path.join(
14091409
customBasePath ?? logBasePath,
1410-
`${shell.logId}_log`
1410+
`${customBasePath ? 'mongosh_' : ''}${shell.logId}_log`
14111411
);
14121412
return readReplLogFile<T>(logPath);
14131413
};
@@ -1681,6 +1681,43 @@ describe('e2e', function () {
16811681
).join('');
16821682
};
16831683

1684+
const getLogName = (
1685+
logId: string | null,
1686+
{ isCompressed = false, prefix = 'mongosh_' } = {}
1687+
): string => {
1688+
if (!logId) throw new Error('logId is not set');
1689+
return `${prefix}${logId}_log${isCompressed ? '.gz' : ''}`;
1690+
};
1691+
1692+
/** Creates fake log files for testing. */
1693+
const createFakeLogFiles = async ({
1694+
count,
1695+
prefix = 'mongosh_',
1696+
size = 0,
1697+
offset,
1698+
basePath,
1699+
}: {
1700+
count: number;
1701+
offset?: number;
1702+
prefix?: string;
1703+
basePath: string | null;
1704+
size?: number;
1705+
}): Promise<string[]> => {
1706+
const paths: string[] = [];
1707+
offset ??= Math.floor(Date.now() / 1000);
1708+
for (let i = count - 1; i >= 0; i--) {
1709+
const logPath = path.join(
1710+
basePath ?? logBasePath,
1711+
getLogName(ObjectId.createFromTime(offset - i).toHexString(), {
1712+
prefix,
1713+
})
1714+
);
1715+
paths.push(logPath);
1716+
await fs.writeFile(logPath, '0'.repeat(size));
1717+
}
1718+
return paths;
1719+
};
1720+
16841721
describe('with custom log compression', function () {
16851722
const customLogDir = useTmpdir();
16861723

@@ -1704,11 +1741,11 @@ describe('e2e', function () {
17041741

17051742
const logFile = path.join(
17061743
customLogDir.path,
1707-
`${shell.logId as string}_log`
1744+
getLogName(shell.logId)
17081745
);
17091746
const logFileGzip = path.join(
17101747
customLogDir.path,
1711-
`${shell.logId as string}_log.gz`
1748+
getLogName(shell.logId, { isCompressed: true })
17121749
);
17131750

17141751
// Only the gzipped file should exist
@@ -1729,27 +1766,27 @@ describe('e2e', function () {
17291766
const paths: string[] = [];
17301767
const today = Math.floor(Date.now() / 1000);
17311768
const tenDaysAgo = today - 10 * 24 * 60 * 60;
1732-
// Create 6 files older than 7 days
1733-
for (let i = 5; i >= 0; i--) {
1734-
const filename = path.join(
1735-
customLogDir.path,
1736-
ObjectId.createFromTime(tenDaysAgo - i).toHexString() + '_log'
1737-
);
1738-
await fs.writeFile(filename, '');
1739-
paths.push(filename);
1740-
}
1741-
// Create 4 files newer than 10 days
1742-
for (let i = 3; i >= 0; i--) {
1743-
const filename = path.join(
1744-
customLogDir.path,
1745-
ObjectId.createFromTime(today - i).toHexString() + '_log'
1746-
);
1747-
await fs.writeFile(filename, '');
1748-
paths.push(filename);
1749-
}
17501769

17511770
const retentionDays = 7;
17521771

1772+
// Create 6 files older than 7 days
1773+
paths.push(
1774+
...(await createFakeLogFiles({
1775+
count: 6,
1776+
offset: tenDaysAgo,
1777+
basePath: customLogDir.path,
1778+
}))
1779+
);
1780+
1781+
// Create 4 files newer than 7 days
1782+
paths.push(
1783+
...(await createFakeLogFiles({
1784+
count: 4,
1785+
offset: today,
1786+
basePath: customLogDir.path,
1787+
}))
1788+
);
1789+
17531790
const globalConfig = path.join(homedir, 'globalconfig.conf');
17541791
await fs.writeFile(
17551792
globalConfig,
@@ -1770,7 +1807,7 @@ describe('e2e', function () {
17701807
await shell.waitForPrompt();
17711808

17721809
// Add the newly created log file
1773-
paths.push(path.join(customLogDir.path, `${shell.logId}_log`));
1810+
paths.push(path.join(customLogDir.path, getLogName(shell.logId)));
17741811
// Expect 6 files to be deleted and 5 to remain (including the new log file)
17751812
expect(await getFilesState(paths)).equals('00000011111');
17761813
});
@@ -1779,6 +1816,57 @@ describe('e2e', function () {
17791816
describe('with logMaxFileCount', function () {
17801817
const customLogDir = useTmpdir();
17811818

1819+
it('should only delete files with mongosh_ prefix in a custom location', async function () {
1820+
const globalConfig = path.join(homedir, 'globalconfig.conf');
1821+
await fs.writeFile(
1822+
globalConfig,
1823+
`mongosh:\n logLocation: ${JSON.stringify(
1824+
customLogDir.path
1825+
)}\n logMaxFileCount: 2`
1826+
);
1827+
1828+
const paths: string[] = [];
1829+
1830+
// Create 3 log files without mongosh_ prefix
1831+
paths.push(
1832+
...(await createFakeLogFiles({
1833+
count: 3,
1834+
prefix: '',
1835+
basePath: customLogDir.path,
1836+
}))
1837+
);
1838+
1839+
// Create 4 log files with mongosh_ prefix
1840+
paths.push(
1841+
...(await createFakeLogFiles({
1842+
count: 3,
1843+
prefix: 'mongosh_',
1844+
basePath: customLogDir.path,
1845+
}))
1846+
);
1847+
1848+
// All 7 existing log files exist.
1849+
expect(await getFilesState(paths)).to.equal('111111');
1850+
1851+
shell = this.startTestShell({
1852+
args: ['--nodb'],
1853+
env: {
1854+
...env,
1855+
MONGOSH_TEST_ONLY_MAX_LOG_FILE_COUNT: '',
1856+
MONGOSH_GLOBAL_CONFIG_FILE_FOR_TESTING: globalConfig,
1857+
},
1858+
forceTerminal: true,
1859+
});
1860+
1861+
await shell.waitForPrompt();
1862+
1863+
paths.push(path.join(customLogDir.path, getLogName(shell.logId)));
1864+
// 3 log files without mongosh_ prefix should remain
1865+
// 2 log file with mongosh_ prefix should be deleted
1866+
// 2 log files with mongosh_ prefix should remain (including the new log)
1867+
expect(await getFilesState(paths)).to.equal('1110011');
1868+
});
1869+
17821870
it('should delete files once it is above logMaxFileCount', async function () {
17831871
const globalConfig = path.join(homedir, 'globalconfig.conf');
17841872
await fs.writeFile(
@@ -1787,18 +1875,12 @@ describe('e2e', function () {
17871875
customLogDir.path
17881876
)}\n logMaxFileCount: 4`
17891877
);
1790-
const paths: string[] = [];
1791-
const offset = Math.floor(Date.now() / 1000);
17921878

17931879
// Create 10 log files
1794-
for (let i = 9; i >= 0; i--) {
1795-
const filename = path.join(
1796-
customLogDir.path,
1797-
ObjectId.createFromTime(offset - i).toHexString() + '_log'
1798-
);
1799-
await fs.writeFile(filename, '');
1800-
paths.push(filename);
1801-
}
1880+
const paths = await createFakeLogFiles({
1881+
count: 10,
1882+
basePath: customLogDir.path,
1883+
});
18021884

18031885
// All 10 existing log files exist.
18041886
expect(await getFilesState(paths)).to.equal('1111111111');
@@ -1812,9 +1894,7 @@ describe('e2e', function () {
18121894
await shell.waitForPrompt();
18131895

18141896
// Add the newly created log to the file list.
1815-
paths.push(
1816-
path.join(customLogDir.path, `${shell.logId as string}_log`)
1817-
);
1897+
paths.push(path.join(customLogDir.path, getLogName(shell.logId)));
18181898

18191899
expect(
18201900
await shell.executeLine('config.get("logMaxFileCount")')
@@ -1838,17 +1918,15 @@ describe('e2e', function () {
18381918
)}\n logRetentionGB: ${4 / 1024}`
18391919
);
18401920
const paths: string[] = [];
1841-
const offset = Math.floor(Date.now() / 1000);
18421921

18431922
// Create 10 log files, around 1 mb each
1844-
for (let i = 9; i >= 0; i--) {
1845-
const filename = path.join(
1846-
customLogDir.path,
1847-
ObjectId.createFromTime(offset - i).toHexString() + '_log'
1848-
);
1849-
await fs.writeFile(filename, '0'.repeat(1024 * 1024));
1850-
paths.push(filename);
1851-
}
1923+
paths.push(
1924+
...(await createFakeLogFiles({
1925+
count: 10,
1926+
size: 1024 * 1024,
1927+
basePath: customLogDir.path,
1928+
}))
1929+
);
18521930

18531931
// All 10 existing log files exist.
18541932
expect(await getFilesState(paths)).to.equal('1111111111');
@@ -1862,9 +1940,7 @@ describe('e2e', function () {
18621940
await shell.waitForPrompt();
18631941

18641942
// Add the newly created log to the file list.
1865-
paths.push(
1866-
path.join(customLogDir.path, `${shell.logId as string}_log`)
1867-
);
1943+
paths.push(path.join(customLogDir.path, getLogName(shell.logId)));
18681944

18691945
expect(
18701946
await shell.executeLine('config.get("logRetentionGB")')

packages/logging/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
"@mongosh/errors": "2.4.0",
2222
"@mongosh/history": "2.4.2",
2323
"@mongosh/types": "3.2.0",
24-
"mongodb-log-writer": "^2.3.0",
24+
"mongodb-log-writer": "^2.3.1",
2525
"mongodb-redact": "^1.1.5"
2626
},
2727
"devDependencies": {

0 commit comments

Comments
 (0)