1
- import { EJSON } from 'bson' ;
1
+ import { type Document , EJSON , type EJSONOptions } from 'bson' ;
2
2
import type { Writable } from 'stream' ;
3
3
import { inspect } from 'util' ;
4
4
@@ -35,8 +35,23 @@ import {
35
35
CONNECTION_POOL_CLOSED ,
36
36
CONNECTION_POOL_CREATED ,
37
37
CONNECTION_POOL_READY ,
38
- CONNECTION_READY
38
+ CONNECTION_READY ,
39
+ SERVER_CLOSED ,
40
+ SERVER_HEARTBEAT_FAILED ,
41
+ SERVER_HEARTBEAT_STARTED ,
42
+ SERVER_HEARTBEAT_SUCCEEDED ,
43
+ SERVER_OPENING ,
44
+ TOPOLOGY_CLOSED ,
45
+ TOPOLOGY_DESCRIPTION_CHANGED ,
46
+ TOPOLOGY_OPENING
39
47
} from './constants' ;
48
+ import type {
49
+ ServerClosedEvent ,
50
+ ServerOpeningEvent ,
51
+ TopologyClosedEvent ,
52
+ TopologyDescriptionChangedEvent ,
53
+ TopologyOpeningEvent
54
+ } from './sdam/events' ;
40
55
import { HostAddress , parseUnsignedInteger } from './utils' ;
41
56
42
57
/** @internal */
@@ -270,6 +285,54 @@ function compareSeverity(s0: SeverityLevel, s1: SeverityLevel): 1 | 0 | -1 {
270
285
return s0Num < s1Num ? - 1 : s0Num > s1Num ? 1 : 0 ;
271
286
}
272
287
288
+ /**
289
+ * @internal
290
+ * Must be separate from Events API due to differences in spec requirements for logging server heartbeat beginning
291
+ */
292
+ export type LoggableServerHeartbeatStartedEvent = {
293
+ topologyId : number ;
294
+ awaited : boolean ;
295
+ connectionId : string ;
296
+ name : typeof SERVER_HEARTBEAT_STARTED ;
297
+ } ;
298
+
299
+ /**
300
+ * @internal
301
+ * Must be separate from Events API due to differences in spec requirements for logging server heartbeat success
302
+ */
303
+ export type LoggableServerHeartbeatSucceededEvent = {
304
+ topologyId : number ;
305
+ awaited : boolean ;
306
+ connectionId : string ;
307
+ reply : Document ;
308
+ serverConnectionId : number | '<monitor>' ;
309
+ duration : number ;
310
+ name : typeof SERVER_HEARTBEAT_SUCCEEDED ;
311
+ } ;
312
+
313
+ /**
314
+ * @internal
315
+ * Must be separate from Events API due to differences in spec requirements for logging server heartbeat failure
316
+ */
317
+ export type LoggableServerHeartbeatFailedEvent = {
318
+ topologyId : number ;
319
+ awaited : boolean ;
320
+ connectionId : string ;
321
+ failure : Error ;
322
+ duration : number ;
323
+ name : typeof SERVER_HEARTBEAT_FAILED ;
324
+ } ;
325
+
326
+ type SDAMLoggableEvent =
327
+ | ServerClosedEvent
328
+ | LoggableServerHeartbeatFailedEvent
329
+ | LoggableServerHeartbeatStartedEvent
330
+ | LoggableServerHeartbeatSucceededEvent
331
+ | ServerOpeningEvent
332
+ | TopologyClosedEvent
333
+ | TopologyDescriptionChangedEvent
334
+ | TopologyOpeningEvent ;
335
+
273
336
/** @internal */
274
337
export type LoggableEvent =
275
338
| CommandStartedEvent
@@ -285,16 +348,28 @@ export type LoggableEvent =
285
348
| ConnectionCheckedInEvent
286
349
| ConnectionCheckedOutEvent
287
350
| ConnectionCheckOutStartedEvent
288
- | ConnectionCheckOutFailedEvent ;
351
+ | ConnectionCheckOutFailedEvent
352
+ | ServerClosedEvent
353
+ | LoggableServerHeartbeatFailedEvent
354
+ | LoggableServerHeartbeatStartedEvent
355
+ | LoggableServerHeartbeatSucceededEvent
356
+ | ServerOpeningEvent
357
+ | TopologyClosedEvent
358
+ | TopologyDescriptionChangedEvent
359
+ | TopologyOpeningEvent ;
289
360
290
361
/** @internal */
291
362
export interface LogConvertible extends Record < string , any > {
292
363
toLog ( ) : Record < string , any > ;
293
364
}
294
365
295
366
/** @internal */
296
- export function stringifyWithMaxLen ( value : any , maxDocumentLength : number ) : string {
297
- const ejson = EJSON . stringify ( value ) ;
367
+ export function stringifyWithMaxLen (
368
+ value : any ,
369
+ maxDocumentLength : number ,
370
+ options : EJSONOptions = { }
371
+ ) : string {
372
+ const ejson = EJSON . stringify ( value , options ) ;
298
373
299
374
return maxDocumentLength !== 0 && ejson . length > maxDocumentLength
300
375
? `${ ejson . slice ( 0 , maxDocumentLength ) } ...`
@@ -329,15 +404,36 @@ function attachCommandFields(
329
404
330
405
function attachConnectionFields (
331
406
log : Record < string , any > ,
332
- connectionPoolEvent : ConnectionPoolMonitoringEvent
407
+ event : ConnectionPoolMonitoringEvent | ServerOpeningEvent | ServerClosedEvent
333
408
) {
334
- const { host, port } = HostAddress . fromString ( connectionPoolEvent . address ) . toHostPort ( ) ;
409
+ const { host, port } = HostAddress . fromString ( event . address ) . toHostPort ( ) ;
335
410
log . serverHost = host ;
336
411
log . serverPort = port ;
337
412
338
413
return log ;
339
414
}
340
415
416
+ function attachSDAMFields ( log : Record < string , any > , sdamEvent : SDAMLoggableEvent ) {
417
+ log . topologyId = sdamEvent . topologyId ;
418
+ return log ;
419
+ }
420
+
421
+ function attachServerHeartbeatFields (
422
+ log : Record < string , any > ,
423
+ serverHeartbeatEvent :
424
+ | LoggableServerHeartbeatFailedEvent
425
+ | LoggableServerHeartbeatStartedEvent
426
+ | LoggableServerHeartbeatSucceededEvent
427
+ ) {
428
+ const { awaited, connectionId } = serverHeartbeatEvent ;
429
+ log . awaited = awaited ;
430
+ log . driverConnectionId = serverHeartbeatEvent . connectionId ;
431
+ const { host, port } = HostAddress . fromString ( connectionId ) . toHostPort ( ) ;
432
+ log . serverHost = host ;
433
+ log . serverPort = port ;
434
+ return log ;
435
+ }
436
+
341
437
function defaultLogTransform (
342
438
logObject : LoggableEvent | Record < string , any > ,
343
439
maxDocumentLength : number = DEFAULT_MAX_DOCUMENT_LENGTH
@@ -456,14 +552,63 @@ function defaultLogTransform(
456
552
case CONNECTION_CHECKED_OUT :
457
553
log = attachConnectionFields ( log , logObject ) ;
458
554
log . message = 'Connection checked out' ;
459
-
460
555
log . driverConnectionId = logObject . connectionId ;
461
556
return log ;
462
557
case CONNECTION_CHECKED_IN :
463
558
log = attachConnectionFields ( log , logObject ) ;
464
559
log . message = 'Connection checked in' ;
465
560
log . driverConnectionId = logObject . connectionId ;
466
561
return log ;
562
+ case SERVER_OPENING :
563
+ log = attachSDAMFields ( log , logObject ) ;
564
+ log = attachConnectionFields ( log , logObject ) ;
565
+ log . message = 'Starting server monitoring' ;
566
+ return log ;
567
+ case SERVER_CLOSED :
568
+ log = attachSDAMFields ( log , logObject ) ;
569
+ log = attachConnectionFields ( log , logObject ) ;
570
+ log . message = 'Stopped server monitoring' ;
571
+ return log ;
572
+ case SERVER_HEARTBEAT_STARTED :
573
+ log = attachSDAMFields ( log , logObject ) ;
574
+ log = attachServerHeartbeatFields ( log , logObject ) ;
575
+ log . message = 'Server heartbeat started' ;
576
+ return log ;
577
+ case SERVER_HEARTBEAT_SUCCEEDED :
578
+ log = attachSDAMFields ( log , logObject ) ;
579
+ log = attachServerHeartbeatFields ( log , logObject ) ;
580
+ log . message = 'Server heartbeat succeeded' ;
581
+ log . durationMS = logObject . duration ;
582
+ log . serverConnectionId = logObject . serverConnectionId ;
583
+ log . reply = stringifyWithMaxLen ( logObject . reply , maxDocumentLength , { relaxed : true } ) ;
584
+ return log ;
585
+ case SERVER_HEARTBEAT_FAILED :
586
+ log = attachSDAMFields ( log , logObject ) ;
587
+ log = attachServerHeartbeatFields ( log , logObject ) ;
588
+ log . message = 'Server heartbeat failed' ;
589
+ log . durationMS = logObject . duration ;
590
+ log . failure = logObject . failure . message ;
591
+ return log ;
592
+ case TOPOLOGY_OPENING :
593
+ log = attachSDAMFields ( log , logObject ) ;
594
+ log . message = 'Starting topology monitoring' ;
595
+ return log ;
596
+ case TOPOLOGY_CLOSED :
597
+ log = attachSDAMFields ( log , logObject ) ;
598
+ log . message = 'Stopped topology monitoring' ;
599
+ return log ;
600
+ case TOPOLOGY_DESCRIPTION_CHANGED :
601
+ log = attachSDAMFields ( log , logObject ) ;
602
+ log . message = 'Topology description changed' ;
603
+ log . previousDescription = log . reply = stringifyWithMaxLen (
604
+ logObject . previousDescription ,
605
+ maxDocumentLength
606
+ ) ;
607
+ log . newDescription = log . reply = stringifyWithMaxLen (
608
+ logObject . newDescription ,
609
+ maxDocumentLength
610
+ ) ;
611
+ return log ;
467
612
default :
468
613
for ( const [ key , value ] of Object . entries ( logObject ) ) {
469
614
if ( value != null ) log [ key ] = value ;
0 commit comments