29
29
import org .bson .codecs .EncoderContext ;
30
30
import org .bson .io .BasicOutputBuffer ;
31
31
32
+ import java .io .File ;
32
33
import java .nio .charset .StandardCharsets ;
34
+ import java .nio .file .Files ;
33
35
import java .util .ArrayList ;
34
36
import java .util .Arrays ;
35
37
import java .util .List ;
38
40
import static com .mongodb .assertions .Assertions .isTrueArgument ;
39
41
import static java .lang .String .format ;
40
42
import static java .lang .System .getProperty ;
43
+ import static java .nio .file .Paths .get ;
41
44
42
45
/**
43
46
* <p>This class is not part of the public API and may be removed or changed at any time</p>
@@ -98,17 +101,26 @@ public static BsonDocument createClientMetadataDocument(@Nullable final String a
98
101
putAtPath (d , "driver.name" , listToString (fullDriverInfo .getDriverNames ()));
99
102
putAtPath (d , "driver.version" , listToString (fullDriverInfo .getDriverVersions ()));
100
103
});
104
+
101
105
// optional fields:
102
- Environment environment = getEnvironment ();
106
+ FaasEnvironment faasEnvironment = getFaasEnvironment ();
107
+ ContainerRuntime containerRuntime = ContainerRuntime .determineExecutionContainer ();
108
+ Orchestrator orchestrator = Orchestrator .determineExecutionOrchestrator ();
109
+
103
110
tryWithLimit (client , d -> putAtPath (d , "platform" , listToString (baseDriverInfor .getDriverPlatforms ())));
104
111
tryWithLimit (client , d -> putAtPath (d , "platform" , listToString (fullDriverInfo .getDriverPlatforms ())));
105
- tryWithLimit (client , d -> putAtPath (d , "env.name" , environment .getName ()));
106
112
tryWithLimit (client , d -> putAtPath (d , "os.name" , getOperatingSystemName ()));
107
113
tryWithLimit (client , d -> putAtPath (d , "os.architecture" , getProperty ("os.arch" , "unknown" )));
108
114
tryWithLimit (client , d -> putAtPath (d , "os.version" , getProperty ("os.version" , "unknown" )));
109
- tryWithLimit (client , d -> putAtPath (d , "env.timeout_sec" , environment .getTimeoutSec ()));
110
- tryWithLimit (client , d -> putAtPath (d , "env.memory_mb" , environment .getMemoryMb ()));
111
- tryWithLimit (client , d -> putAtPath (d , "env.region" , environment .getRegion ()));
115
+
116
+ tryWithLimit (client , d -> putAtPath (d , "env.name" , faasEnvironment .getName ()));
117
+ tryWithLimit (client , d -> putAtPath (d , "env.timeout_sec" , faasEnvironment .getTimeoutSec ()));
118
+ tryWithLimit (client , d -> putAtPath (d , "env.memory_mb" , faasEnvironment .getMemoryMb ()));
119
+ tryWithLimit (client , d -> putAtPath (d , "env.region" , faasEnvironment .getRegion ()));
120
+
121
+ tryWithLimit (client , d -> putAtPath (d , "env.container.runtime" , containerRuntime .getName ()));
122
+ tryWithLimit (client , d -> putAtPath (d , "env.container.orchestrator" , orchestrator .getName ()));
123
+
112
124
return client ;
113
125
}
114
126
@@ -168,8 +180,7 @@ static boolean clientMetadataDocumentTooLarge(final BsonDocument document) {
168
180
new BsonDocumentCodec ().encode (new BsonBinaryWriter (buffer ), document , EncoderContext .builder ().build ());
169
181
return buffer .getPosition () > MAXIMUM_CLIENT_METADATA_ENCODED_SIZE ;
170
182
}
171
-
172
- private enum Environment {
183
+ private enum FaasEnvironment {
173
184
AWS_LAMBDA ("aws.lambda" ),
174
185
AZURE_FUNC ("azure.func" ),
175
186
GCP_FUNC ("gcp.func" ),
@@ -179,7 +190,7 @@ private enum Environment {
179
190
@ Nullable
180
191
private final String name ;
181
192
182
- Environment (@ Nullable final String name ) {
193
+ FaasEnvironment (@ Nullable final String name ) {
183
194
this .name = name ;
184
195
}
185
196
@@ -225,6 +236,81 @@ public String getRegion() {
225
236
}
226
237
}
227
238
239
+ public enum ContainerRuntime {
240
+ DOCKER ("docker" ) {
241
+ @ Override
242
+ boolean isCurrentRuntimeContainer () {
243
+ try {
244
+ return Files .exists (get (File .separator + ".dockerenv" ));
245
+ } catch (Exception e ) {
246
+ return false ;
247
+ // NOOP. This could be a SecurityException.
248
+ }
249
+ }
250
+ },
251
+ UNKNOWN (null );
252
+
253
+ @ Nullable
254
+ private final String name ;
255
+
256
+ ContainerRuntime (@ Nullable final String name ) {
257
+ this .name = name ;
258
+ }
259
+
260
+ @ Nullable
261
+ public String getName () {
262
+ return name ;
263
+ }
264
+
265
+ boolean isCurrentRuntimeContainer () {
266
+ return false ;
267
+ }
268
+
269
+ static ContainerRuntime determineExecutionContainer () {
270
+ for (ContainerRuntime allegedContainer : ContainerRuntime .values ()) {
271
+ if (allegedContainer .isCurrentRuntimeContainer ()) {
272
+ return allegedContainer ;
273
+ }
274
+ }
275
+ return UNKNOWN ;
276
+ }
277
+ }
278
+
279
+ private enum Orchestrator {
280
+ K8S ("kubernetes" ) {
281
+ @ Override
282
+ boolean isCurrentOrchestrator () {
283
+ return System .getenv ("KUBERNETES_SERVICE_HOST" ) != null ;
284
+ }
285
+ },
286
+ UNKNOWN (null );
287
+
288
+ @ Nullable
289
+ private final String name ;
290
+
291
+ Orchestrator (@ Nullable final String name ) {
292
+ this .name = name ;
293
+ }
294
+
295
+ @ Nullable
296
+ public String getName () {
297
+ return name ;
298
+ }
299
+
300
+ boolean isCurrentOrchestrator () {
301
+ return false ;
302
+ }
303
+
304
+ static Orchestrator determineExecutionOrchestrator () {
305
+ for (Orchestrator alledgedOrchestrator : Orchestrator .values ()) {
306
+ if (alledgedOrchestrator .isCurrentOrchestrator ()) {
307
+ return alledgedOrchestrator ;
308
+ }
309
+ }
310
+ return UNKNOWN ;
311
+ }
312
+ }
313
+
228
314
@ Nullable
229
315
private static Integer getEnvInteger (final String name ) {
230
316
try {
@@ -235,29 +321,29 @@ private static Integer getEnvInteger(final String name) {
235
321
}
236
322
}
237
323
238
- static Environment getEnvironment () {
239
- List <Environment > result = new ArrayList <>();
324
+ static FaasEnvironment getFaasEnvironment () {
325
+ List <FaasEnvironment > result = new ArrayList <>();
240
326
String awsExecutionEnv = System .getenv ("AWS_EXECUTION_ENV" );
241
327
242
328
if (System .getenv ("VERCEL" ) != null ) {
243
- result .add (Environment .VERCEL );
329
+ result .add (FaasEnvironment .VERCEL );
244
330
}
245
331
if ((awsExecutionEnv != null && awsExecutionEnv .startsWith ("AWS_Lambda_" ))
246
332
|| System .getenv ("AWS_LAMBDA_RUNTIME_API" ) != null ) {
247
- result .add (Environment .AWS_LAMBDA );
333
+ result .add (FaasEnvironment .AWS_LAMBDA );
248
334
}
249
335
if (System .getenv ("FUNCTIONS_WORKER_RUNTIME" ) != null ) {
250
- result .add (Environment .AZURE_FUNC );
336
+ result .add (FaasEnvironment .AZURE_FUNC );
251
337
}
252
338
if (System .getenv ("K_SERVICE" ) != null || System .getenv ("FUNCTION_NAME" ) != null ) {
253
- result .add (Environment .GCP_FUNC );
339
+ result .add (FaasEnvironment .GCP_FUNC );
254
340
}
255
341
// vercel takes precedence over aws.lambda
256
- if (result .equals (Arrays .asList (Environment .VERCEL , Environment .AWS_LAMBDA ))) {
257
- return Environment .VERCEL ;
342
+ if (result .equals (Arrays .asList (FaasEnvironment .VERCEL , FaasEnvironment .AWS_LAMBDA ))) {
343
+ return FaasEnvironment .VERCEL ;
258
344
}
259
345
if (result .size () != 1 ) {
260
- return Environment .UNKNOWN ;
346
+ return FaasEnvironment .UNKNOWN ;
261
347
}
262
348
return result .get (0 );
263
349
}
0 commit comments