• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mongodb-js / mongodb-mcp-server / 14670404051

25 Apr 2025 05:45PM UTC coverage: 81.886% (+0.2%) from 81.696%
14670404051

Pull #118

github

nirinchev
Merge branch 'main' into ni/conditional-connect
Pull Request #118: feat: update the connect tool based on connectivity status

129 of 210 branches covered (61.43%)

Branch coverage included in aggregate %.

59 of 67 new or added lines in 9 files covered. (88.06%)

10 existing lines in 1 file now uncovered.

748 of 861 relevant lines covered (86.88%)

47.74 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

34.69
/src/telemetry/telemetry.ts
1
import { Session } from "../session.js";
2
import { BaseEvent } from "./types.js";
3
import { config } from "../config.js";
31✔
4
import logger, { LogId } from "../logger.js";
31✔
5
import { ApiClient } from "../common/atlas/apiClient.js";
6
import { MACHINE_METADATA } from "./constants.js";
31✔
7
import { EventCache } from "./eventCache.js";
31✔
8

9
type EventResult = {
10
    success: boolean;
11
    error?: Error;
12
};
13

14
type CommonProperties = {
15
    device_id?: string;
16
    mcp_server_version: string;
17
    mcp_server_name: string;
18
    mcp_client_version?: string;
19
    mcp_client_name?: string;
20
    platform: string;
21
    arch: string;
22
    os_type: string;
23
    os_version?: string;
24
    session_id?: string;
25
};
26

27
export class Telemetry {
31✔
28
    private readonly commonProperties: CommonProperties;
29

30
    constructor(
31
        private readonly session: Session,
28✔
32
        private readonly eventCache: EventCache = EventCache.getInstance()
28✔
33
    ) {
34
        this.commonProperties = {
28✔
35
            ...MACHINE_METADATA,
36
        };
37
    }
38

39
    /**
40
     * Checks if telemetry is currently enabled
41
     * This is a method rather than a constant to capture runtime config changes
42
     *
43
     * Follows the Console Do Not Track standard (https://consoledonottrack.com/)
44
     * by respecting the DO_NOT_TRACK environment variable
45
     */
46
    private static isTelemetryEnabled(): boolean {
47
        // Check if telemetry is explicitly disabled in config
48
        if (config.telemetry === "disabled") {
282✔
49
            return false;
282✔
50
        }
51

52
        const doNotTrack = process.env.DO_NOT_TRACK;
×
53
        if (doNotTrack) {
×
54
            const value = doNotTrack.toLowerCase();
×
55
            // Telemetry should be disabled if DO_NOT_TRACK is "1", "true", or "yes"
56
            if (value === "1" || value === "true" || value === "yes") {
×
57
                return false;
×
58
            }
59
        }
60

61
        return true;
×
62
    }
63

64
    /**
65
     * Emits events through the telemetry pipeline
66
     * @param events - The events to emit
67
     */
68
    public async emitEvents(events: BaseEvent[]): Promise<void> {
69
        try {
282✔
70
            if (!Telemetry.isTelemetryEnabled()) {
282✔
71
                return;
282✔
72
            }
73

74
            await this.emit(events);
×
75
        } catch {
NEW
76
            logger.debug(LogId.telemetryEmitFailure, "telemetry", `Error emitting telemetry events.`);
×
77
        }
78
    }
79

80
    /**
81
     * Gets the common properties for events
82
     * @returns Object containing common properties for all events
83
     */
84
    public getCommonProperties(): CommonProperties {
85
        return {
282✔
86
            ...this.commonProperties,
87
            mcp_client_version: this.session.agentRunner?.version,
88
            mcp_client_name: this.session.agentRunner?.name,
89
            session_id: this.session.sessionId,
90
        };
91
    }
92

93
    /**
94
     * Attempts to emit events through authenticated and unauthenticated clients
95
     * Falls back to caching if both attempts fail
96
     */
97
    private async emit(events: BaseEvent[]): Promise<void> {
98
        const cachedEvents = this.eventCache.getEvents();
×
99
        const allEvents = [...cachedEvents, ...events];
×
100

101
        logger.debug(
×
102
            LogId.telemetryEmitStart,
103
            "telemetry",
104
            `Attempting to send ${allEvents.length} events (${cachedEvents.length} cached)`
105
        );
106

107
        const result = await this.sendEvents(this.session.apiClient, allEvents);
×
108
        if (result.success) {
×
109
            this.eventCache.clearEvents();
×
NEW
110
            logger.debug(LogId.telemetryEmitSuccess, "telemetry", `Sent ${allEvents.length} events successfully`);
×
111
            return;
×
112
        }
113

NEW
114
        logger.debug(
×
115
            LogId.telemetryEmitFailure,
116
            "telemetry",
117
            `Error sending event to client: ${result.error instanceof Error ? result.error.message : String(result.error)}`
×
118
        );
119
        this.eventCache.appendEvents(events);
×
120
    }
121

122
    /**
123
     * Attempts to send events through the provided API client
124
     */
125
    private async sendEvents(client: ApiClient, events: BaseEvent[]): Promise<EventResult> {
126
        try {
×
127
            await client.sendEvents(events);
×
128
            return { success: true };
×
129
        } catch (error) {
130
            return {
×
131
                success: false,
132
                error: error instanceof Error ? error : new Error(String(error)),
×
133
            };
134
        }
135
    }
136
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc