Skip to content

Commit 7fa19e4

Browse files
authored
chore: avoid logging files on disk and move them to console for containers (#340)
1 parent 5b7ba55 commit 7fa19e4

File tree

5 files changed

+67
-32
lines changed

5 files changed

+67
-32
lines changed

src/common/container.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import fs from "fs/promises";
2+
3+
let containerEnv: boolean | undefined;
4+
5+
export async function detectContainerEnv(): Promise<boolean> {
6+
if (containerEnv !== undefined) {
7+
return containerEnv;
8+
}
9+
10+
const detect = async function (): Promise<boolean> {
11+
if (process.platform !== "linux") {
12+
return false; // we only support linux containers for now
13+
}
14+
15+
if (process.env.container) {
16+
return true;
17+
}
18+
19+
const exists = await Promise.all(
20+
["/.dockerenv", "/run/.containerenv", "/var/run/.containerenv"].map(async (file) => {
21+
try {
22+
await fs.access(file);
23+
return true;
24+
} catch {
25+
return false;
26+
}
27+
})
28+
);
29+
30+
return exists.includes(true);
31+
};
32+
33+
containerEnv = await detect();
34+
return containerEnv;
35+
}

src/logger.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,11 +180,16 @@ class CompositeLogger extends LoggerBase {
180180
const logger = new CompositeLogger();
181181
export default logger;
182182

183-
export async function initializeLogger(server: McpServer, logPath: string): Promise<LoggerBase> {
183+
export async function setStdioPreset(server: McpServer, logPath: string): Promise<void> {
184184
const diskLogger = await DiskLogger.fromPath(logPath);
185185
const mcpLogger = new McpLogger(server);
186186

187187
logger.setLoggers(mcpLogger, diskLogger);
188+
}
189+
190+
export function setContainerPreset(server: McpServer): void {
191+
const mcpLogger = new McpLogger(server);
192+
const consoleLogger = new ConsoleLogger();
188193

189-
return logger;
194+
logger.setLoggers(mcpLogger, consoleLogger);
190195
}

src/server.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,15 @@ import { Session } from "./session.js";
33
import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js";
44
import { AtlasTools } from "./tools/atlas/tools.js";
55
import { MongoDbTools } from "./tools/mongodb/tools.js";
6-
import logger, { initializeLogger, LogId } from "./logger.js";
6+
import logger, { setStdioPreset, setContainerPreset, LogId } from "./logger.js";
77
import { ObjectId } from "mongodb";
88
import { Telemetry } from "./telemetry/telemetry.js";
99
import { UserConfig } from "./config.js";
1010
import { type ServerEvent } from "./telemetry/types.js";
1111
import { type ServerCommand } from "./telemetry/types.js";
1212
import { CallToolRequestSchema, CallToolResult } from "@modelcontextprotocol/sdk/types.js";
1313
import assert from "assert";
14+
import { detectContainerEnv } from "./common/container.js";
1415

1516
export interface ServerOptions {
1617
session: Session;
@@ -63,7 +64,13 @@ export class Server {
6364
return existingHandler(request, extra);
6465
});
6566

66-
await initializeLogger(this.mcpServer, this.userConfig.logPath);
67+
const containerEnv = await detectContainerEnv();
68+
69+
if (containerEnv) {
70+
setContainerPreset(this.mcpServer);
71+
} else {
72+
await setStdioPreset(this.mcpServer, this.userConfig.logPath);
73+
}
6774

6875
await this.mcpServer.connect(transport);
6976

src/telemetry/telemetry.ts

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { MACHINE_METADATA } from "./constants.js";
77
import { EventCache } from "./eventCache.js";
88
import nodeMachineId from "node-machine-id";
99
import { getDeviceId } from "@mongodb-js/device-id";
10-
import fs from "fs/promises";
10+
import { detectContainerEnv } from "../common/container.js";
1111

1212
type EventResult = {
1313
success: boolean;
@@ -53,29 +53,6 @@ export class Telemetry {
5353
return instance;
5454
}
5555

56-
private async isContainerEnv(): Promise<boolean> {
57-
if (process.platform !== "linux") {
58-
return false; // we only support linux containers for now
59-
}
60-
61-
if (process.env.container) {
62-
return true;
63-
}
64-
65-
const exists = await Promise.all(
66-
["/.dockerenv", "/run/.containerenv", "/var/run/.containerenv"].map(async (file) => {
67-
try {
68-
await fs.access(file);
69-
return true;
70-
} catch {
71-
return false;
72-
}
73-
})
74-
);
75-
76-
return exists.includes(true);
77-
}
78-
7956
private async setup(): Promise<void> {
8057
if (!this.isTelemetryEnabled()) {
8158
return;
@@ -98,7 +75,7 @@ export class Telemetry {
9875
},
9976
abortSignal: this.deviceIdAbortController.signal,
10077
}),
101-
this.isContainerEnv(),
78+
detectContainerEnv(),
10279
]);
10380

10481
const [deviceId, containerEnv] = await this.setupPromise;

tests/integration/tools/atlas/clusters.test.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Session } from "../../../../src/session.js";
22
import { expectDefined } from "../../helpers.js";
33
import { describeWithAtlas, withProject, randomId } from "./atlasHelpers.js";
4+
import { ClusterDescription20240805 } from "../../../../src/common/atlas/openapi.js";
45
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
56

67
function sleep(ms: number) {
@@ -33,7 +34,12 @@ async function deleteAndWaitCluster(session: Session, projectId: string, cluster
3334
}
3435
}
3536

36-
async function waitClusterState(session: Session, projectId: string, clusterName: string, state: string) {
37+
async function waitCluster(
38+
session: Session,
39+
projectId: string,
40+
clusterName: string,
41+
check: (cluster: ClusterDescription20240805) => boolean | Promise<boolean>
42+
) {
3743
while (true) {
3844
const cluster = await session.apiClient.getCluster({
3945
params: {
@@ -43,7 +49,7 @@ async function waitClusterState(session: Session, projectId: string, clusterName
4349
},
4450
},
4551
});
46-
if (cluster?.stateName === state) {
52+
if (await check(cluster)) {
4753
return;
4854
}
4955
await sleep(1000);
@@ -142,7 +148,12 @@ describeWithAtlas("clusters", (integration) => {
142148
describe("atlas-connect-cluster", () => {
143149
beforeAll(async () => {
144150
const projectId = getProjectId();
145-
await waitClusterState(integration.mcpServer().session, projectId, clusterName, "IDLE");
151+
await waitCluster(integration.mcpServer().session, projectId, clusterName, (cluster) => {
152+
return (
153+
cluster.stateName === "IDLE" &&
154+
(cluster.connectionStrings?.standardSrv || cluster.connectionStrings?.standard) !== undefined
155+
);
156+
});
146157
await integration.mcpServer().session.apiClient.createProjectIpAccessList({
147158
params: {
148159
path: {

0 commit comments

Comments
 (0)