@@ -8,6 +8,7 @@ import { EventCache } from "./eventCache.js";
8
8
import nodeMachineId from "node-machine-id" ;
9
9
import { getDeviceId } from "@mongodb-js/device-id" ;
10
10
import fs from "fs/promises" ;
11
+ import { get } from "http" ;
11
12
12
13
type EventResult = {
13
14
success : boolean ;
@@ -22,30 +23,74 @@ export type TelemetryOptions = {
22
23
commonProperties ?: CommonProperties ;
23
24
eventCache ?: EventCache ;
24
25
getRawMachineId ?: ( ) => Promise < string > ;
26
+ getContainerEnv ?: ( ) => Promise < boolean > ;
25
27
} ;
26
28
29
+ async function fileExists ( filePath : string ) : Promise < boolean > {
30
+ try {
31
+ await fs . stat ( filePath ) ;
32
+ return true ; // File exists
33
+ } catch ( e : unknown ) {
34
+ if (
35
+ e instanceof Error &&
36
+ (
37
+ e as Error & {
38
+ code : string ;
39
+ }
40
+ ) . code === "ENOENT"
41
+ ) {
42
+ return false ; // File does not exist
43
+ }
44
+ throw e ; // Re-throw unexpected errors
45
+ }
46
+ }
47
+
48
+ async function isContainerized ( ) : Promise < boolean > {
49
+ for ( const file of [ "/.dockerenv" , "/run/.containerenv" , "/var/run/.containerenv" ] ) {
50
+ const exists = await fileExists ( file ) ;
51
+ if ( exists ) {
52
+ return true ;
53
+ }
54
+ }
55
+ return ! ! process . env . container ;
56
+ }
57
+
27
58
export class Telemetry {
28
59
private isBufferingEvents : boolean = true ;
29
60
/** Resolves when the device ID is retrieved or timeout occurs */
30
61
public deviceIdPromise : Promise < string > | undefined ;
31
62
private deviceIdAbortController = new AbortController ( ) ;
63
+ private eventCache : EventCache ;
64
+ private getRawMachineId : ( ) => Promise < string > ;
65
+ private getContainerEnv : ( ) => Promise < boolean > ;
32
66
33
67
private constructor (
34
68
private readonly session : Session ,
35
69
private readonly userConfig : UserConfig ,
36
70
private readonly commonProperties : CommonProperties ,
37
- private readonly eventCache : EventCache ,
38
- private readonly getRawMachineId : ( ) => Promise < string >
39
- ) { }
40
-
41
- static create ( { session, userConfig, commonProperties, eventCache, getRawMachineId } : TelemetryOptions ) : Telemetry {
42
- const instance = new Telemetry (
43
- session ,
44
- userConfig ,
45
- commonProperties || { ...MACHINE_METADATA } ,
46
- eventCache || EventCache . getInstance ( ) ,
47
- getRawMachineId || ( ( ) => nodeMachineId . machineId ( true ) )
48
- ) ;
71
+ { eventCache, getRawMachineId, getContainerEnv } : { eventCache : EventCache ; getRawMachineId : ( ) => Promise < string > ; getContainerEnv : ( ) => Promise < boolean > }
72
+ ) {
73
+ this . eventCache = eventCache ;
74
+ this . getRawMachineId = getRawMachineId ;
75
+ this . getContainerEnv = getContainerEnv ;
76
+ }
77
+
78
+ static create (
79
+ session : Session ,
80
+ userConfig : UserConfig ,
81
+ {
82
+ commonProperties = { ...MACHINE_METADATA } ,
83
+ eventCache = EventCache . getInstance ( ) ,
84
+ getRawMachineId = ( ) => nodeMachineId . machineId ( true ) ,
85
+ getContainerEnv = isContainerized ,
86
+ } : {
87
+ commonProperties ?: CommonProperties ;
88
+ eventCache ?: EventCache ;
89
+ getRawMachineId ?: ( ) => Promise < string > ;
90
+ getContainerEnv ?: ( ) => Promise < boolean > ;
91
+ } = { }
92
+ ) : Telemetry {
93
+ const instance = new Telemetry ( session , userConfig , commonProperties , { eventCache, getRawMachineId, getContainerEnv } ) ;
49
94
50
95
void instance . start ( ) ;
51
96
return instance ;
@@ -73,9 +118,17 @@ export class Telemetry {
73
118
abortSignal : this . deviceIdAbortController . signal ,
74
119
} ) ;
75
120
121
+ // try {
122
+ // this.commonProperties.is_container_env = (await this.getContainerEnv()) ? "true" : "false";
123
+ // } catch (error: unknown) {
124
+ // logger.info(
125
+ // LogId.telemetryContainerEnvFailure,
126
+ // "telemetry",
127
+ // `Failed trying to check if is in container environment ${error as string}`
128
+ // );
129
+ // }
76
130
this . commonProperties . device_id = await this . deviceIdPromise ;
77
- this . commonProperties . is_container_env = ( await this . isContainerized ( ) ) ? "true" : "false" ;
78
-
131
+
79
132
this . isBufferingEvents = false ;
80
133
}
81
134
@@ -117,35 +170,6 @@ export class Telemetry {
117
170
} ;
118
171
}
119
172
120
- private async fileExists ( filePath : string ) : Promise < boolean > {
121
- try {
122
- await fs . stat ( filePath ) ;
123
- return true ; // File exists
124
- } catch ( e : unknown ) {
125
- if (
126
- e instanceof Error &&
127
- (
128
- e as Error & {
129
- code : string ;
130
- }
131
- ) . code === "ENOENT"
132
- ) {
133
- return false ; // File does not exist
134
- }
135
- throw e ; // Re-throw unexpected errors
136
- }
137
- }
138
-
139
- private async isContainerized ( ) : Promise < boolean > {
140
- for ( const file of [ "/.dockerenv" , "/run/.containerenv" , "/var/run/.containerenv" ] ) {
141
- const fileExists = await this . fileExists ( file ) ;
142
- if ( fileExists ) {
143
- return true ;
144
- }
145
- }
146
- return ! ! process . env . container ;
147
- }
148
-
149
173
/**
150
174
* Checks if telemetry is currently enabled
151
175
* This is a method rather than a constant to capture runtime config changes
0 commit comments