@observertc/observer-js 0.40.10-beta → 0.40.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/README.md +52 -24
  2. package/lib/ObservedClient.d.ts +9 -0
  3. package/lib/ObservedClient.d.ts.map +1 -1
  4. package/lib/ObservedClient.js +19 -8
  5. package/lib/ObservedICE.d.ts +2 -2
  6. package/lib/ObservedICE.d.ts.map +1 -1
  7. package/lib/ObservedICE.js +4 -4
  8. package/lib/ObservedOutboundTrack.d.ts +1 -0
  9. package/lib/ObservedOutboundTrack.d.ts.map +1 -1
  10. package/lib/ObservedOutboundTrack.js +7 -0
  11. package/lib/ObservedSfu.d.ts.map +1 -1
  12. package/lib/ObservedSfu.js +1 -0
  13. package/lib/Observer.d.ts +4 -2
  14. package/lib/Observer.d.ts.map +1 -1
  15. package/lib/Observer.js +4 -4
  16. package/lib/common/CallEventType.d.ts +2 -1
  17. package/lib/common/CallEventType.d.ts.map +1 -1
  18. package/lib/common/CallEventType.js +2 -1
  19. package/lib/common/callMetaReports.d.ts +1 -1
  20. package/lib/common/callMetaReports.d.ts.map +1 -1
  21. package/lib/common/callMetaReports.js +1 -1
  22. package/lib/monitors/CallSummary.d.ts +4 -0
  23. package/lib/monitors/CallSummary.d.ts.map +1 -1
  24. package/lib/monitors/CallSummaryMonitor.d.ts +8 -1
  25. package/lib/monitors/CallSummaryMonitor.d.ts.map +1 -1
  26. package/lib/monitors/CallSummaryMonitor.js +55 -1
  27. package/lib/monitors/TurnUsageMonitor.d.ts +2 -0
  28. package/lib/monitors/TurnUsageMonitor.d.ts.map +1 -1
  29. package/lib/monitors/TurnUsageMonitor.js +9 -0
  30. package/package.json +1 -1
  31. package/src/ObservedClient.ts +60 -10
  32. package/src/ObservedICE.ts +12 -4
  33. package/src/ObservedOutboundTrack.ts +9 -0
  34. package/src/ObservedSfu.ts +2 -0
  35. package/src/Observer.ts +13 -7
  36. package/src/common/CallEventType.ts +1 -1
  37. package/src/common/callMetaReports.ts +1 -0
  38. package/src/monitors/CallSummary.ts +5 -0
  39. package/src/monitors/CallSummaryMonitor.ts +76 -4
  40. package/src/monitors/TurnUsageMonitor.ts +13 -0
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- Server side component for monitoring WebRTC stack
1
+ Server side component for monitoring WebRTC applications and services
2
2
  ---
3
3
 
4
4
  Table of Contents:
@@ -6,9 +6,7 @@ Table of Contents:
6
6
  * [Quick Start](#quick-start)
7
7
  * [Configurations](#configurations)
8
8
  * [NPM package](#npm-package)
9
- * [API docs](#api-docs)
10
9
  * [Schemas](#schemas)
11
- * [Getting Involved](#getting-involved)
12
10
  * [License](#license)
13
11
 
14
12
  ## Qucik Start
@@ -25,29 +23,23 @@ Use it in your server side NodeJS app.
25
23
  import { createObserver, ClientSample } from "@observertc/observer-js";
26
24
 
27
25
  const observer = createObserver({
28
- // see full config in Configuration section
26
+ defaultServiceId: 'my-service-name',
27
+ defaultMediaUnitId: 'my-reporting-component',
29
28
  });
30
29
 
31
- const clientSource = observer.createClientSource({
30
+ const observedCall = observer.createObservedCall({
32
31
  roomId: 'roomId',
33
32
  callId: 'room-session-id',
34
- clientId: 'reporting-client-id',
35
33
  });
36
34
 
37
- const clientSample: ClientSample; // Receive your samples, for example, from a WebSocket
38
-
39
- clientSource.accept(clientSample);
40
-
41
- observer.addEvaluator(async context => {
42
- const { endedCalls } = context;
43
-
44
- // Observe call durations
45
- for (const endedCall of endedCalls) {
46
- const elapsedTimeInMins = (endedCall.ended - Number(endedCall.started)) / (60 * 1000);
47
- console.log(`Call ${endedCall.callId} duration was ${elapsedTimeInMins} minutes`);
48
- }
35
+ const observedClient = observedCall.createObservedClient({
36
+ clientId: 'client-id',
37
+ mediaUnitId: 'media-unit-id',
49
38
  });
50
39
 
40
+ const clientSample: ClientSample; // Receive your samples, for example, from a WebSocket
41
+
42
+ observedClient.accept(clientSample);
51
43
  ```
52
44
 
53
45
  The above example do as follows:
@@ -55,9 +47,49 @@ The above example do as follows:
55
47
  2. create a client source object to accept client samples
56
48
  3. add an evaluator process to evaluate ended calls
57
49
 
58
- ## API documentation
50
+ ### Get a Summary of a call when it ends
51
+
52
+ ```javascript
53
+
54
+ const monitor = observer.createCallSummaryMonitor('summary', (summary) => {
55
+ console.log('Call Summary', summary);
56
+ });
57
+ ```
58
+
59
+ ### How Many Clients are using TURN?
60
+
61
+ ```javascript
62
+ const monitor = observer.createTurnUsageMonitor('turn', (turn) => {
63
+ console.log('TURN', turn);
64
+ });
65
+
66
+ // at any point of time you can get the current state of the turn usage
59
67
 
60
- https://observertc.org/docs/api/observer-js
68
+ console.log('Currently ', monitor.clients.size, 'clients are using TURN');
69
+
70
+ // you can get the incoming and outgoing bytes of the TURN server
71
+ console.log(`${YOUR_TURN_SERVER_ADDRESS} usage:`, monitor.getUsage(YOUR_TURN_SERVER_ADDRESS));
72
+
73
+ ```
74
+
75
+ ### Monitor Calls and Clients as they updated
76
+
77
+ ```javascript
78
+ observer.on('newcall', (call) => {
79
+ call.on('update', () => {
80
+ console.log('Call Updated', call.callId);
81
+ });
82
+
83
+ call.on('newclient', (client) => {
84
+
85
+ client.on('update', () => {
86
+ console.log('Client Updated', client.clientId);
87
+
88
+ console.log(`The avaialble incoming bitrate for the client ${client.clientId} is: ${client.availableIncomingBitrate}`)
89
+ });
90
+ })
91
+ });
92
+ ```
61
93
 
62
94
  ## NPM package
63
95
 
@@ -69,10 +101,6 @@ https://www.npmjs.com/package/@observertc/observer-js
69
101
  https://github.com/observertc/schemas
70
102
 
71
103
 
72
- ## Getting Involved
73
-
74
- The repository is open for contributions.
75
-
76
104
  ## License
77
105
 
78
106
  Apache-2.0
@@ -4,6 +4,13 @@ import { ObservedCall } from './ObservedCall';
4
4
  import { EventEmitter } from 'events';
5
5
  import { ObservedPeerConnection } from './ObservedPeerConnection';
6
6
  import { ObservedSfu } from './ObservedSfu';
7
+ export interface ClientIssue {
8
+ severity: 'critical' | 'major' | 'minor';
9
+ timestamp: number;
10
+ description?: string;
11
+ peerConnectionId?: string;
12
+ trackId?: string;
13
+ }
7
14
  export type ObservedClientModel = {
8
15
  clientId: string;
9
16
  mediaUnitId: string;
@@ -47,7 +54,9 @@ export type ObservedClientEvents = {
47
54
  remoteCandidate: IceRemoteCandidate;
48
55
  }
49
56
  ];
57
+ issue: [ClientIssue];
50
58
  usingturn: [boolean];
59
+ usermediaerror: [string];
51
60
  };
52
61
  export declare interface ObservedClient<AppData extends Record<string, unknown> = Record<string, unknown>> {
53
62
  on<U extends keyof ObservedClientEvents>(event: U, listener: (...args: ObservedClientEvents[U]) => void): this;
@@ -1 +1 @@
1
- {"version":3,"file":"ObservedClient.d.ts","sourceRoot":"","sources":["../src/ObservedClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ObservedClient.d.ts","sourceRoot":"","sources":["../src/ObservedClient.ts"],"names":[],"mappings":"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"}
@@ -164,7 +164,7 @@ class ObservedClient extends events_1.EventEmitter {
164
164
  const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
165
165
  type: callMetaReports_1.CallMetaType.OPERATION_SYSTEM,
166
166
  payload: sample.os,
167
- }, this.userId);
167
+ }, this.userId, undefined, sample.timestamp);
168
168
  this.reports.addCallMetaReport(callMetaReport);
169
169
  }
170
170
  if (sample.engine && (((_d = this._model.engine) === null || _d === void 0 ? void 0 : _d.name) !== sample.engine.name ||
@@ -173,7 +173,7 @@ class ObservedClient extends events_1.EventEmitter {
173
173
  const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
174
174
  type: callMetaReports_1.CallMetaType.ENGINE,
175
175
  payload: sample.engine,
176
- }, this.userId);
176
+ }, this.userId, undefined, sample.timestamp);
177
177
  this.reports.addCallMetaReport(callMetaReport);
178
178
  }
179
179
  if (sample.platform && (((_f = this._model.platform) === null || _f === void 0 ? void 0 : _f.model) !== sample.platform.model ||
@@ -183,7 +183,7 @@ class ObservedClient extends events_1.EventEmitter {
183
183
  const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
184
184
  type: callMetaReports_1.CallMetaType.PLATFORM,
185
185
  payload: sample.platform,
186
- }, this.userId);
186
+ }, this.userId, undefined, sample.timestamp);
187
187
  this.reports.addCallMetaReport(callMetaReport);
188
188
  }
189
189
  if (sample.browser && (((_j = this._model.browser) === null || _j === void 0 ? void 0 : _j.name) !== sample.browser.name ||
@@ -192,21 +192,21 @@ class ObservedClient extends events_1.EventEmitter {
192
192
  const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
193
193
  type: callMetaReports_1.CallMetaType.BROWSER,
194
194
  payload: sample.browser,
195
- }, this.userId);
195
+ }, this.userId, undefined, sample.timestamp);
196
196
  this.reports.addCallMetaReport(callMetaReport);
197
197
  }
198
198
  for (const mediaConstraint of (_l = sample.mediaConstraints) !== null && _l !== void 0 ? _l : []) {
199
199
  const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
200
200
  type: callMetaReports_1.CallMetaType.MEDIA_CONSTRAINT,
201
201
  payload: mediaConstraint,
202
- }, this.userId);
202
+ }, this.userId, undefined, sample.timestamp);
203
203
  this.reports.addCallMetaReport(callMetaReport);
204
204
  }
205
205
  for (const localSDP of (_m = sample.localSDPs) !== null && _m !== void 0 ? _m : []) {
206
206
  const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
207
207
  type: callMetaReports_1.CallMetaType.LOCAL_SDP,
208
208
  payload: localSDP,
209
- }, this.userId);
209
+ }, this.userId, undefined, sample.timestamp);
210
210
  this.reports.addCallMetaReport(callMetaReport);
211
211
  }
212
212
  for (const extensionStats of (_o = sample.extensionStats) !== null && _o !== void 0 ? _o : []) {
@@ -229,6 +229,16 @@ class ObservedClient extends events_1.EventEmitter {
229
229
  this._left = timestamp;
230
230
  break;
231
231
  }
232
+ case CallEventType_1.CallEventType.CLIENT_ISSUE: {
233
+ const severity = callEvent.value ? callEvent.value : 'minor';
234
+ this.emit('issue', {
235
+ severity,
236
+ timestamp: timestamp !== null && timestamp !== void 0 ? timestamp : Date.now(),
237
+ description: callEvent.message,
238
+ peerConnectionId: callEvent.peerConnectionId,
239
+ trackId: callEvent.mediaTrackId,
240
+ });
241
+ }
232
242
  }
233
243
  this.reports.addCallEventReport(Object.assign({ serviceId: this.serviceId, mediaUnitId: this.mediaUnitId, roomId: this.roomId, callId: this.callId, clientId: this.clientId, userId: this.userId, timestamp: timestamp !== null && timestamp !== void 0 ? timestamp : Date.now() }, callEvent));
234
244
  }
@@ -239,6 +249,7 @@ class ObservedClient extends events_1.EventEmitter {
239
249
  }, this.userId);
240
250
  this.reports.addCallMetaReport(callMetaReport);
241
251
  this.userMediaErrors.push(userMediaError);
252
+ this.emit('usermediaerror', userMediaError);
242
253
  }
243
254
  for (const certificate of (_r = sample.certificates) !== null && _r !== void 0 ? _r : []) {
244
255
  const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.serviceId, this.mediaUnitId, this.roomId, this.callId, this.clientId, {
@@ -390,7 +401,7 @@ class ObservedClient extends events_1.EventEmitter {
390
401
  logger.debug(`Peer connection ${iceLocalCandidate.peerConnectionId} not found for ice local candidate ${iceLocalCandidate.id}`);
391
402
  continue;
392
403
  }
393
- peerConnection.ICE.addLocalCandidate(iceLocalCandidate);
404
+ peerConnection.ICE.addLocalCandidate(iceLocalCandidate, sample.timestamp);
394
405
  }
395
406
  for (const iceRemoteCandidate of (_13 = sample.iceRemoteCandidates) !== null && _13 !== void 0 ? _13 : []) {
396
407
  if (!iceRemoteCandidate.peerConnectionId) {
@@ -402,7 +413,7 @@ class ObservedClient extends events_1.EventEmitter {
402
413
  logger.debug(`Peer connection ${iceRemoteCandidate.peerConnectionId} not found for ice remote candidate ${iceRemoteCandidate.id}`);
403
414
  continue;
404
415
  }
405
- peerConnection.ICE.addRemoteCandidate(iceRemoteCandidate);
416
+ peerConnection.ICE.addRemoteCandidate(iceRemoteCandidate, sample.timestamp);
406
417
  }
407
418
  for (const candidatePair of (_14 = sample.iceCandidatePairs) !== null && _14 !== void 0 ? _14 : []) {
408
419
  const peerConnection = this._peerConnections.get(candidatePair.peerConnectionId);
@@ -56,8 +56,8 @@ export declare class ObservedICE extends EventEmitter {
56
56
  get updated(): number;
57
57
  get closed(): boolean;
58
58
  close(): void;
59
- addLocalCandidate(candidate: IceLocalCandidate): void;
60
- addRemoteCandidate(candidate: IceRemoteCandidate): void;
59
+ addLocalCandidate(candidate: IceLocalCandidate, sampleTimestamp?: number): void;
60
+ addRemoteCandidate(candidate: IceRemoteCandidate, sampleTimestamp?: number): void;
61
61
  resetMetrics(): void;
62
62
  update(candidatePair: IceCandidatePair, timestamp: number): void;
63
63
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ObservedICE.d.ts","sourceRoot":"","sources":["../src/ObservedICE.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ObservedICE.d.ts","sourceRoot":"","sources":["../src/ObservedICE.ts"],"names":[],"mappings":"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"}
@@ -57,7 +57,7 @@ class ObservedICE extends events_1.EventEmitter {
57
57
  this._closed = true;
58
58
  this.emit('close');
59
59
  }
60
- addLocalCandidate(candidate) {
60
+ addLocalCandidate(candidate, sampleTimestamp) {
61
61
  if (!candidate.id)
62
62
  return;
63
63
  const newCandidate = !this._localCandidates.has(candidate.id);
@@ -66,12 +66,12 @@ class ObservedICE extends events_1.EventEmitter {
66
66
  const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.peerConnection.client.serviceId, this.peerConnection.client.mediaUnitId, this.peerConnection.client.roomId, this.peerConnection.client.callId, this.peerConnection.client.clientId, {
67
67
  type: callMetaReports_1.CallMetaType.ICE_LOCAL_CANDIDATE,
68
68
  payload: candidate,
69
- }, this.peerConnection.client.userId);
69
+ }, this.peerConnection.client.userId, this.peerConnection.peerConnectionId, sampleTimestamp);
70
70
  this.reports.addCallMetaReport(callMetaReport);
71
71
  this.emit('new-local-candidate', candidate);
72
72
  }
73
73
  }
74
- addRemoteCandidate(candidate) {
74
+ addRemoteCandidate(candidate, sampleTimestamp) {
75
75
  if (!candidate.id)
76
76
  return;
77
77
  const newCandidate = !this._remoteCandidates.has(candidate.id);
@@ -80,7 +80,7 @@ class ObservedICE extends events_1.EventEmitter {
80
80
  const callMetaReport = (0, callMetaReports_1.createCallMetaReport)(this.peerConnection.client.serviceId, this.peerConnection.client.mediaUnitId, this.peerConnection.client.roomId, this.peerConnection.client.callId, this.peerConnection.client.clientId, {
81
81
  type: callMetaReports_1.CallMetaType.ICE_REMOTE_CANDIDATE,
82
82
  payload: candidate,
83
- }, this.peerConnection.client.userId);
83
+ }, this.peerConnection.client.userId, this.peerConnection.peerConnectionId, sampleTimestamp);
84
84
  this.reports.addCallMetaReport(callMetaReport);
85
85
  this.emit('new-remote-candidate', candidate);
86
86
  }
@@ -10,6 +10,7 @@ export type ObservedOutboundTrackModel<K extends MediaKind> = {
10
10
  sfuStreamId?: string;
11
11
  };
12
12
  export type ObservedOutboundTrackEvents = {
13
+ qualitylimitationchanged: [string];
13
14
  update: [
14
15
  {
15
16
  elapsedTimeInMs: number;
@@ -1 +1 @@
1
- {"version":3,"file":"ObservedOutboundTrack.d.ts","sourceRoot":"","sources":["../src/ObservedOutboundTrack.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ObservedOutboundTrack.d.ts","sourceRoot":"","sources":["../src/ObservedOutboundTrack.ts"],"names":[],"mappings":"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"}
@@ -112,6 +112,13 @@ class ObservedOutboundTrack extends events_1.EventEmitter {
112
112
  if ((videoSample === null || videoSample === void 0 ? void 0 : videoSample.framesSent) && (lastVideoStats === null || lastVideoStats === void 0 ? void 0 : lastVideoStats.framesSent) && lastVideoStats.framesSent < videoSample.framesSent) {
113
113
  deltaSentFrames = videoSample.framesSent - lastVideoStats.framesSent;
114
114
  }
115
+ if (videoSample.qualityLimitationReason && (lastVideoStats === null || lastVideoStats === void 0 ? void 0 : lastVideoStats.qualityLimitationReason) !== videoSample.qualityLimitationReason) {
116
+ this.emit('qualitylimitationchanged', videoSample.qualityLimitationReason);
117
+ }
118
+ }
119
+ else if (this.kind === 'audio') {
120
+ // const audioSample = sample as OutboundAudioTrack;
121
+ // const lastAudioStats = lastStat as OutboundAudioTrack | undefined;
115
122
  }
116
123
  const stats = Object.assign(Object.assign({}, sample), { rttInMs,
117
124
  bitrate, ssrc: sample.ssrc, deltaLostPackets,
@@ -1 +1 @@
1
- {"version":3,"file":"ObservedSfu.d.ts","sourceRoot":"","sources":["../src/ObservedSfu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAA6B,MAAM,wBAAwB,CAAC;AAGzF,MAAM,MAAM,gBAAgB,GAAE;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE;QAAC;YACR,eAAe,EAAE,MAAM,CAAC;SACxB;KAAC,CAAC;IACH,KAAK,EAAE,EAAE,CAAC;IACV,YAAY,EAAE,CAAC,oBAAoB,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACrG,EAAE,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACzG,GAAG,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAE1F,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;CAChC;AAED,qBAAa,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,YAAY;IAY9G,OAAO,CAAC,QAAQ,CAAC,MAAM;aACP,QAAQ,EAAE,QAAQ;aAClB,OAAO,EAAE,OAAO;IAbjC,SAAgB,OAAO,SAAc;IAErC,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,sBAAsB,CAAC,CAAS;IACxC,OAAO,CAAC,KAAK,CAAC,CAAS;IAEvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2C;gBAGrD,MAAM,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO;IAMjC,IAAW,MAAM,uBAEhB;IAED,IAAW,OAAO,kDAEjB;IAED,IAAW,SAAS,WAGnB;IAED,IAAW,WAAW,WAErB;IAED,IAAW,KAAK,WAGf;IAED,IAAW,MAAM,WAGhB;IAED,IAAW,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAEjE;IAED,IAAW,OAAO,WAEjB;IAED,IAAW,MAAM,YAEhB;IAEM,KAAK;IAiGZ,OAAO,CAAC,gBAAgB;CAYxB"}
1
+ {"version":3,"file":"ObservedSfu.d.ts","sourceRoot":"","sources":["../src/ObservedSfu.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAA6B,MAAM,wBAAwB,CAAC;AAGzF,MAAM,MAAM,gBAAgB,GAAE;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC/B,MAAM,EAAE;QAAC;YACR,eAAe,EAAE,MAAM,CAAC;SACxB;KAAC,CAAC;IACH,KAAK,EAAE,EAAE,CAAC;IACV,YAAY,EAAE,CAAC,oBAAoB,CAAC,CAAC;CACrC,CAAC;AAEF,MAAM,CAAC,OAAO,WAAW,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACrG,EAAE,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACzG,GAAG,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC1G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IAC3G,IAAI,CAAC,CAAC,SAAS,MAAM,iBAAiB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;IAE1F,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,MAAM,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;CAChC;AAED,qBAAa,WAAW,CAAC,OAAO,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAE,SAAQ,YAAY;IAY9G,OAAO,CAAC,QAAQ,CAAC,MAAM;aACP,QAAQ,EAAE,QAAQ;aAClB,OAAO,EAAE,OAAO;IAbjC,SAAgB,OAAO,SAAc;IAErC,OAAO,CAAC,QAAQ,CAAc;IAC9B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,sBAAsB,CAAC,CAAS;IACxC,OAAO,CAAC,KAAK,CAAC,CAAS;IAEvB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA2C;gBAGrD,MAAM,EAAE,gBAAgB,EACzB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,OAAO;IAMjC,IAAW,MAAM,uBAEhB;IAED,IAAW,OAAO,kDAEjB;IAED,IAAW,SAAS,WAGnB;IAED,IAAW,WAAW,WAErB;IAED,IAAW,KAAK,WAGf;IAED,IAAW,MAAM,WAGhB;IAED,IAAW,UAAU,IAAI,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAEjE;IAED,IAAW,OAAO,WAEjB;IAED,IAAW,MAAM,YAEhB;IAEM,KAAK;IAmGZ,OAAO,CAAC,gBAAgB;CAYxB"}
@@ -61,6 +61,7 @@ class ObservedSfu extends events_1.EventEmitter {
61
61
  if (!this._timeZoneOffsetInHours && sample.timeZoneOffsetInHours) {
62
62
  this._timeZoneOffsetInHours = sample.timeZoneOffsetInHours;
63
63
  }
64
+ this._marker = sample.marker;
64
65
  const now = Date.now();
65
66
  const elapsedTimeInMs = now - this._updated;
66
67
  for (const customSfuEvents of (_a = sample.customSfuEvents) !== null && _a !== void 0 ? _a : []) {
package/lib/Observer.d.ts CHANGED
@@ -5,7 +5,7 @@ import { EventEmitter } from 'events';
5
5
  import { PartialBy } from './common/utils';
6
6
  import { ObserverSinkContext } from './common/types';
7
7
  import { ObservedSfu, ObservedSfuModel } from './ObservedSfu';
8
- import { CallSummaryMonitor } from './monitors/CallSummaryMonitor';
8
+ import { CallSummaryMonitor, CallSummaryMonitorConfig } from './monitors/CallSummaryMonitor';
9
9
  import { TurnUsageMonitor } from './monitors/TurnUsageMonitor';
10
10
  export type ObserverEvents = {
11
11
  'newcall': [ObservedCall];
@@ -51,9 +51,11 @@ export declare class Observer extends EventEmitter {
51
51
  createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(config: PartialBy<ObservedCallModel, 'serviceId'> & {
52
52
  appData: T;
53
53
  started?: number;
54
+ reportCallStarted?: boolean;
55
+ reportCallEnded?: boolean;
54
56
  }): ObservedCall<T>;
55
57
  createObservedSfu<AppData extends Record<string, unknown> = Record<string, unknown>>(model: ObservedSfuModel, appData: AppData): ObservedSfu<AppData>;
56
- createCallSummaryMonitor(options?: {
58
+ createCallSummaryMonitor(options?: CallSummaryMonitorConfig & {
57
59
  timeoutAfterCallClose?: number;
58
60
  }): CallSummaryMonitor;
59
61
  createTurnUsageMonitor(): TurnUsageMonitor;
@@ -1 +1 @@
1
- {"version":3,"file":"Observer.d.ts","sourceRoot":"","sources":["../src/Observer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Observer.d.ts","sourceRoot":"","sources":["../src/Observer.ts"],"names":[],"mappings":"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"}
package/lib/Observer.js CHANGED
@@ -65,7 +65,7 @@ class Observer extends events_1.EventEmitter {
65
65
  if (this._closed) {
66
66
  throw new Error('Attempted to create a call source on a closed observer');
67
67
  }
68
- const { appData, started = Date.now() } = config, model = __rest(config, ["appData", "started"]);
68
+ const { appData, started = Date.now(), reportCallEnded = true, reportCallStarted = true } = config, model = __rest(config, ["appData", "started", "reportCallEnded", "reportCallStarted"]);
69
69
  const call = new ObservedCall_1.ObservedCall(Object.assign(Object.assign({}, model), { serviceId: this.config.defaultServiceId }), this, appData);
70
70
  if (this._closed)
71
71
  throw new Error('Cannot create an observed call on a closed observer');
@@ -73,10 +73,10 @@ class Observer extends events_1.EventEmitter {
73
73
  throw new Error(`Observed Call with id ${call.callId} already exists`);
74
74
  call.once('close', () => {
75
75
  this._observedCalls.delete(call.callId);
76
- this.reports.addCallEventReport((0, callEventReports_1.createCallEndedEventReport)(call.serviceId, call.roomId, call.callId, Date.now()));
76
+ reportCallEnded && this.reports.addCallEventReport((0, callEventReports_1.createCallEndedEventReport)(call.serviceId, call.roomId, call.callId, Date.now()));
77
77
  });
78
78
  this._observedCalls.set(call.callId, call);
79
- this.reports.addCallEventReport((0, callEventReports_1.createCallStartedEventReport)(call.serviceId, call.roomId, call.callId, started));
79
+ reportCallStarted && this.reports.addCallEventReport((0, callEventReports_1.createCallStartedEventReport)(call.serviceId, call.roomId, call.callId, started));
80
80
  this.emit('newcall', call);
81
81
  return call;
82
82
  }
@@ -102,7 +102,7 @@ class Observer extends events_1.EventEmitter {
102
102
  const existingMonitor = this._monitors.get(CallSummaryMonitor_1.CallSummaryMonitor.name);
103
103
  if (existingMonitor)
104
104
  return existingMonitor;
105
- const monitor = new CallSummaryMonitor_1.CallSummaryMonitor();
105
+ const monitor = new CallSummaryMonitor_1.CallSummaryMonitor(options);
106
106
  const onNewCall = (call) => {
107
107
  monitor.addCall(call);
108
108
  call.once('close', () => {
@@ -17,6 +17,7 @@ export declare enum CallEventType {
17
17
  DATA_CHANNEL_CLOSED = "DATA_CHANNEL_CLOSED",
18
18
  DATA_CHANNEL_ERROR = "DATA_CHANNEL_ERROR",
19
19
  NEGOTIATION_NEEDED = "NEGOTIATION_NEEDED",
20
- SIGNALING_STATE_CHANGE = "SIGNALING_STATE_CHANGE"
20
+ SIGNALING_STATE_CHANGE = "SIGNALING_STATE_CHANGE",
21
+ CLIENT_ISSUE = "CLIENT_ISSUE"
21
22
  }
22
23
  //# sourceMappingURL=CallEventType.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CallEventType.d.ts","sourceRoot":"","sources":["../../src/common/CallEventType.ts"],"names":[],"mappings":"AAEA,oBAAY,aAAa;IACxB,YAAY,iBAAiB;IAC7B,UAAU,eAAe;IACzB,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;IAC3B,sBAAsB,2BAA2B;IACjD,sBAAsB,2BAA2B;IACjD,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,2BAA2B,gCAAgC;IAC3D,6BAA6B,kCAAkC;IAC/D,4BAA4B,iCAAiC;IAC7D,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,kBAAkB,uBAAuB;IACzC,kBAAkB,uBAAuB;IACzC,sBAAsB,2BAA2B;CACjD"}
1
+ {"version":3,"file":"CallEventType.d.ts","sourceRoot":"","sources":["../../src/common/CallEventType.ts"],"names":[],"mappings":"AACA,oBAAY,aAAa;IACxB,YAAY,iBAAiB;IAC7B,UAAU,eAAe;IACzB,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;IAC3B,sBAAsB,2BAA2B;IACjD,sBAAsB,2BAA2B;IACjD,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,2BAA2B,gCAAgC;IAC3D,6BAA6B,kCAAkC;IAC/D,4BAA4B,iCAAiC;IAC7D,iBAAiB,sBAAsB;IACvC,mBAAmB,wBAAwB;IAC3C,kBAAkB,uBAAuB;IACzC,kBAAkB,uBAAuB;IACzC,sBAAsB,2BAA2B;IACjD,YAAY,iBAAiB;CAC7B"}
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
- // eslint-disable-next-line no-shadow
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
4
3
  exports.CallEventType = void 0;
4
+ // eslint-disable-next-line no-shadow
5
5
  var CallEventType;
6
6
  (function (CallEventType) {
7
7
  CallEventType["CALL_STARTED"] = "CALL_STARTED";
@@ -23,4 +23,5 @@ var CallEventType;
23
23
  CallEventType["DATA_CHANNEL_ERROR"] = "DATA_CHANNEL_ERROR";
24
24
  CallEventType["NEGOTIATION_NEEDED"] = "NEGOTIATION_NEEDED";
25
25
  CallEventType["SIGNALING_STATE_CHANGE"] = "SIGNALING_STATE_CHANGE";
26
+ CallEventType["CLIENT_ISSUE"] = "CLIENT_ISSUE";
26
27
  })(CallEventType = exports.CallEventType || (exports.CallEventType = {}));
@@ -59,5 +59,5 @@ export type CallMetaReportType = {
59
59
  type: CallMetaType.BROWSER;
60
60
  payload: Browser;
61
61
  };
62
- export declare function createCallMetaReport(serviceId: string, mediaUnitId: string, roomId: string, callId: string, clientId: string, reportType: CallMetaReportType, userId?: string, timestamp?: number): CallMetaReport;
62
+ export declare function createCallMetaReport(serviceId: string, mediaUnitId: string, roomId: string, callId: string, clientId: string, reportType: CallMetaReportType, userId?: string, peerConnectionId?: string, timestamp?: number): CallMetaReport;
63
63
  //# sourceMappingURL=callMetaReports.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"callMetaReports.d.ts","sourceRoot":"","sources":["../../src/common/callMetaReports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EACN,OAAO,EACP,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,QAAQ,EACR,MAAM,+BAA+B,CAAC;AAGvC,oBAAY,YAAY;IACvB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;IACf,mBAAmB,wBAAwB;IAC3C,oBAAoB,yBAAyB;IAC7C,UAAU,eAAe;IACzB,gBAAgB,qBAAqB;IACrC,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,SAAS,cAAc;IAEvB,gBAAgB,qBAAqB;IACrC,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,OAAO,YAAY;CACnB;AAED,MAAM,MAAM,kBAAkB,GAC3B;IACD,IAAI,EAAE,YAAY,CAAC,WAAW,CAAC;IAC/B,OAAO,EAAE,WAAW,CAAC;CACrB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,mBAAmB,CAAC;IACvC,OAAO,EAAE,iBAAiB,CAAC;CAC3B,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,oBAAoB,CAAC;IACxC,OAAO,EAAE,kBAAkB,CAAC;CAC5B,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC;IAChC,OAAO,EAAE,WAAW,CAAC;CACrB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;IAC5B,OAAO,EAAE,QAAQ,CAAC;CAClB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CACjB,CAAC;AAEH,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,kBAAkB,EAC9B,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,kBAelB"}
1
+ {"version":3,"file":"callMetaReports.d.ts","sourceRoot":"","sources":["../../src/common/callMetaReports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,EACN,OAAO,EACP,WAAW,EACX,MAAM,EACN,iBAAiB,EACjB,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,eAAe,EACf,eAAe,EACf,QAAQ,EACR,MAAM,+BAA+B,CAAC;AAGvC,oBAAY,YAAY;IACvB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;IACf,mBAAmB,wBAAwB;IAC3C,oBAAoB,yBAAyB;IAC7C,UAAU,eAAe;IACzB,gBAAgB,qBAAqB;IACrC,YAAY,iBAAiB;IAC7B,YAAY,iBAAiB;IAC7B,gBAAgB,qBAAqB;IACrC,SAAS,cAAc;IAEvB,gBAAgB,qBAAqB;IACrC,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,OAAO,YAAY;CACnB;AAED,MAAM,MAAM,kBAAkB,GAC3B;IACD,IAAI,EAAE,YAAY,CAAC,WAAW,CAAC;IAC/B,OAAO,EAAE,WAAW,CAAC;CACrB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,KAAK,CAAC;IACzB,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,mBAAmB,CAAC;IACvC,OAAO,EAAE,iBAAiB,CAAC;CAC3B,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,oBAAoB,CAAC;IACxC,OAAO,EAAE,kBAAkB,CAAC;CAC5B,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,UAAU,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC;IAChC,OAAO,EAAE,WAAW,CAAC;CACrB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,YAAY,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,gBAAgB,CAAC;IACpC,OAAO,EAAE,eAAe,CAAC;CACzB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,QAAQ,CAAC;IAC5B,OAAO,EAAE,QAAQ,CAAC;CAClB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC;IAC1B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,CAAC;CAChB,GAAG;IACH,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;IAC3B,OAAO,EAAE,OAAO,CAAC;CACjB,CAAC;AAEH,wBAAgB,oBAAoB,CACnC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,kBAAkB,EAC9B,MAAM,CAAC,EAAE,MAAM,EACf,gBAAgB,CAAC,EAAE,MAAM,EACzB,SAAS,CAAC,EAAE,MAAM,kBAelB"}
@@ -19,7 +19,7 @@ var CallMetaType;
19
19
  CallMetaType["PLATFORM"] = "PLATFORM";
20
20
  CallMetaType["BROWSER"] = "BROWSER";
21
21
  })(CallMetaType = exports.CallMetaType || (exports.CallMetaType = {}));
22
- function createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, reportType, userId, timestamp) {
22
+ function createCallMetaReport(serviceId, mediaUnitId, roomId, callId, clientId, reportType, userId, peerConnectionId, timestamp) {
23
23
  const report = {
24
24
  type: reportType.type,
25
25
  serviceId,
@@ -1,14 +1,18 @@
1
+ import { ClientIssue } from '../ObservedClient';
1
2
  export interface ClientSummary {
2
3
  clientId: string;
3
4
  mediaUnitId: string;
4
5
  userId?: string;
5
6
  joined: number;
7
+ left?: number;
6
8
  durationInMs: number;
7
9
  avgOutboundAudioBitrate: number;
8
10
  avgOutboundVideoBitrate: number;
9
11
  avgInboundAudioBitrate: number;
10
12
  avgInboundVideoBitrate: number;
11
13
  ewmaRttInMs: number;
14
+ usedTurn: boolean;
15
+ issues: ClientIssue[];
12
16
  }
13
17
  export interface CallSummary {
14
18
  serviceId: string;
@@ -1 +1 @@
1
- {"version":3,"file":"CallSummary.d.ts","sourceRoot":"","sources":["../../src/monitors/CallSummary.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,MAAM,CAAC;IAChC,uBAAuB,EAAE,MAAM,CAAC;IAChC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,aAAa,EAAE,CAAC;CACzB"}
1
+ {"version":3,"file":"CallSummary.d.ts","sourceRoot":"","sources":["../../src/monitors/CallSummary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,MAAM,CAAC;IAChC,uBAAuB,EAAE,MAAM,CAAC;IAChC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,sBAAsB,EAAE,MAAM,CAAC;IAC/B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,aAAa,EAAE,CAAC;CACzB"}
@@ -6,6 +6,10 @@ export type CallSummaryMonitorEvents = {
6
6
  close: [];
7
7
  summary: [CallSummary];
8
8
  };
9
+ export type CallSummaryMonitorConfig = {
10
+ detectUserMediaIssues?: boolean;
11
+ detectMediaTrackQualityLimitationIssues?: boolean;
12
+ };
9
13
  export declare interface CallSummaryMonitor {
10
14
  on<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
11
15
  off<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
@@ -13,11 +17,14 @@ export declare interface CallSummaryMonitor {
13
17
  emit<U extends keyof CallSummaryMonitorEvents>(event: U, ...args: CallSummaryMonitorEvents[U]): boolean;
14
18
  }
15
19
  export declare class CallSummaryMonitor extends EventEmitter {
20
+ readonly config: CallSummaryMonitorConfig;
16
21
  private readonly _summaries;
17
22
  private _closed;
18
- constructor();
23
+ constructor(config?: CallSummaryMonitorConfig);
19
24
  addCall(call: ObservedCall): void;
20
25
  private _addClient;
26
+ private _addPeerConnection;
27
+ private _addOutboundVideoTrack;
21
28
  takeSummary(callId: string): CallSummary | undefined;
22
29
  get closed(): boolean;
23
30
  close(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"CallSummaryMonitor.d.ts","sourceRoot":"","sources":["../../src/monitors/CallSummaryMonitor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAG/C,MAAM,MAAM,wBAAwB,GAAG;IACtC,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC;CACvB,CAAA;AAED,MAAM,CAAC,OAAO,WAAW,kBAAkB;IAC1C,EAAE,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACvH,GAAG,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACxH,IAAI,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACzH,IAAI,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACxG;AAED,qBAAa,kBAAmB,SAAQ,YAAY;IACnD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAE7D,OAAO,CAAC,OAAO,CAAS;;IAKjB,OAAO,CAAC,IAAI,EAAE,YAAY;IAyBjC,OAAO,CAAC,UAAU;IAoCX,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAU3D,IAAW,MAAM,YAEhB;IAEM,KAAK;CAMZ"}
1
+ {"version":3,"file":"CallSummaryMonitor.d.ts","sourceRoot":"","sources":["../../src/monitors/CallSummaryMonitor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,WAAW,EAAiB,MAAM,eAAe,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/C,MAAM,MAAM,wBAAwB,GAAG;IACtC,KAAK,EAAE,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC;CACvB,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACtC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uCAAuC,CAAC,EAAE,OAAO,CAAC;CAClD,CAAA;AAED,MAAM,CAAC,OAAO,WAAW,kBAAkB;IAC1C,EAAE,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACvH,GAAG,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACxH,IAAI,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACzH,IAAI,CAAC,CAAC,SAAS,MAAM,wBAAwB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACxG;AAED,qBAAa,kBAAmB,SAAQ,YAAY;aAKlC,MAAM,EAAE,wBAAwB;IAJjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAkC;IAE7D,OAAO,CAAC,OAAO,CAAS;gBAEP,MAAM,GAAE,wBAA6B;IAK/C,OAAO,CAAC,IAAI,EAAE,YAAY;IAyBjC,OAAO,CAAC,UAAU;IAuElB,OAAO,CAAC,kBAAkB;IAS1B,OAAO,CAAC,sBAAsB;IAmBvB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS;IAU3D,IAAW,MAAM,YAEhB;IAEM,KAAK;CAMZ"}
@@ -3,8 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.CallSummaryMonitor = void 0;
4
4
  const events_1 = require("events");
5
5
  class CallSummaryMonitor extends events_1.EventEmitter {
6
- constructor() {
6
+ constructor(config = {}) {
7
7
  super();
8
+ this.config = config;
8
9
  this._summaries = new Map();
9
10
  this._closed = false;
10
11
  }
@@ -44,6 +45,8 @@ class CallSummaryMonitor extends events_1.EventEmitter {
44
45
  ewmaRttInMs: 0,
45
46
  joined: client.created,
46
47
  userId: client.userId,
48
+ usedTurn: false,
49
+ issues: [],
47
50
  };
48
51
  callSummary.clients.push(clientSummary);
49
52
  const updateClient = () => {
@@ -51,7 +54,29 @@ class CallSummaryMonitor extends events_1.EventEmitter {
51
54
  clientSummary.ewmaRttInMs = (clientSummary.ewmaRttInMs * 0.9) + (client.avgRttInMs * 0.1);
52
55
  }
53
56
  };
57
+ const onUsingTurn = (usingTurn) => {
58
+ clientSummary.usedTurn || (clientSummary.usedTurn = usingTurn);
59
+ };
60
+ const onIssue = (issue) => {
61
+ clientSummary.issues.push(issue);
62
+ };
63
+ const onUserMediaError = (error) => {
64
+ if (!this.config.detectUserMediaIssues)
65
+ return;
66
+ // maybe the client also sned this issue, in which case the timestamp can be more accurate
67
+ const alreadyDetected = clientSummary.issues.find((issue) => issue.severity === 'critical' && issue.description === error);
68
+ !alreadyDetected && clientSummary.issues.push({
69
+ severity: 'critical',
70
+ timestamp: Date.now(),
71
+ description: error,
72
+ });
73
+ };
74
+ const onNewPeerConnection = (peerConnection) => this._addPeerConnection(clientSummary, peerConnection);
54
75
  client.on('update', updateClient);
76
+ client.on('usingturn', onUsingTurn);
77
+ client.on('issue', onIssue);
78
+ client.on('usermediaerror', onUserMediaError);
79
+ client.on('newpeerconnection', onNewPeerConnection);
55
80
  client.once('close', () => {
56
81
  const elapsedTimeInS = (Date.now() - client.created) / 1000;
57
82
  clientSummary.avgInboundAudioBitrate = (client.totalReceivedBytes * 8) / elapsedTimeInS;
@@ -60,7 +85,36 @@ class CallSummaryMonitor extends events_1.EventEmitter {
60
85
  clientSummary.avgOutboundVideoBitrate = (client.totalSentBytes * 8) / elapsedTimeInS;
61
86
  clientSummary.durationInMs = elapsedTimeInS * 1000;
62
87
  client.off('update', updateClient);
88
+ client.off('usingturn', onUsingTurn);
89
+ client.off('issue', onIssue);
90
+ client.off('usermediaerror', onUserMediaError);
91
+ client.off('newpeerconnection', onNewPeerConnection);
92
+ callSummary.durationInMs += clientSummary.durationInMs;
93
+ });
94
+ }
95
+ _addPeerConnection(clientSummary, peerConnection) {
96
+ const onOutboundVideoTrack = (track) => this._addOutboundVideoTrack(clientSummary, track);
97
+ peerConnection.on('newoutboundvideotrack', onOutboundVideoTrack);
98
+ peerConnection.once('close', () => {
99
+ peerConnection.off('newoutboundvideotrack', onOutboundVideoTrack);
100
+ });
101
+ }
102
+ _addOutboundVideoTrack(clientSummary, track) {
103
+ const onQualityLimitationChanged = (reason) => {
104
+ if (!this.config.detectMediaTrackQualityLimitationIssues)
105
+ return;
106
+ clientSummary.issues.push({
107
+ severity: 'minor',
108
+ timestamp: Date.now(),
109
+ description: reason,
110
+ peerConnectionId: track.peerConnectionId,
111
+ trackId: track.trackId,
112
+ });
113
+ };
114
+ track.once('close', () => {
115
+ track.off('qualitylimitationchanged', onQualityLimitationChanged);
63
116
  });
117
+ track.on('qualitylimitationchanged', onQualityLimitationChanged);
64
118
  }
65
119
  takeSummary(callId) {
66
120
  if (this.closed)
@@ -1,6 +1,7 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from 'events';
3
3
  import { ObservedPeerConnection } from '../ObservedPeerConnection';
4
+ import { ObservedClient } from '../ObservedClient';
4
5
  export type TurnUsageMonitorEvents = {
5
6
  close: [];
6
7
  'newturnip': [string];
@@ -31,6 +32,7 @@ export declare class TurnUsageMonitor extends EventEmitter {
31
32
  get turnIps(): string[];
32
33
  get peerConnections(): ObservedPeerConnection[];
33
34
  getUsage(turnIp: string): TurnUsage | undefined;
35
+ get clients(): ReadonlyMap<string, ObservedClient>;
34
36
  get closed(): boolean;
35
37
  close(): void;
36
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"TurnUsageMonitor.d.ts","sourceRoot":"","sources":["../../src/monitors/TurnUsageMonitor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAGnE,MAAM,MAAM,sBAAsB,GAAG;IACpC,KAAK,EAAE,EAAE,CAAC;IACV,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC;IACtB,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC;IACpB,iBAAiB,EAAE,CAAC,sBAAsB,CAAC,CAAC;IAC5C,oBAAoB,EAAE,CAAC,sBAAsB,CAAC,CAAC;CAC/C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;CAC7B,CAAA;AAQD,MAAM,CAAC,OAAO,WAAW,gBAAgB;IACxC,EAAE,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACnH,GAAG,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACpH,IAAI,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACrH,IAAI,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACpG;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyC;IACtE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAE3D,OAAO,CAAC,OAAO,CAAS;;IAKjB,iBAAiB,CAAC,cAAc,EAAE,sBAAsB;IA4CxD,oBAAoB,CAAC,cAAc,EAAE,sBAAsB;IAelE,IAAW,OAAO,aAEjB;IAED,IAAW,eAAe,6BAEzB;IAEM,QAAQ,CAAC,MAAM,EAAE,MAAM;IAI9B,IAAW,MAAM,YAEhB;IAEM,KAAK;CAMZ"}
1
+ {"version":3,"file":"TurnUsageMonitor.d.ts","sourceRoot":"","sources":["../../src/monitors/TurnUsageMonitor.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,MAAM,sBAAsB,GAAG;IACpC,KAAK,EAAE,EAAE,CAAC;IACV,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC;IACtB,MAAM,EAAE,CAAC,SAAS,CAAC,CAAC;IACpB,iBAAiB,EAAE,CAAC,sBAAsB,CAAC,CAAC;IAC5C,oBAAoB,EAAE,CAAC,sBAAsB,CAAC,CAAC;CAC/C,CAAA;AAED,MAAM,MAAM,SAAS,GAAG;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,oBAAoB,EAAE,MAAM,CAAC;CAC7B,CAAA;AAQD,MAAM,CAAC,OAAO,WAAW,gBAAgB;IACxC,EAAE,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACnH,GAAG,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACpH,IAAI,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,KAAK,IAAI,GAAG,IAAI,CAAC;IACrH,IAAI,CAAC,CAAC,SAAS,MAAM,sBAAsB,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;CACpG;AAED,qBAAa,gBAAiB,SAAQ,YAAY;IACjD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyC;IACtE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAgC;IAE3D,OAAO,CAAC,OAAO,CAAS;;IAKjB,iBAAiB,CAAC,cAAc,EAAE,sBAAsB;IA4CxD,oBAAoB,CAAC,cAAc,EAAE,sBAAsB;IAelE,IAAW,OAAO,aAEjB;IAED,IAAW,eAAe,6BAEzB;IAEM,QAAQ,CAAC,MAAM,EAAE,MAAM;IAI9B,IAAW,OAAO,IAAI,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,CAUxD;IAED,IAAW,MAAM,YAEhB;IAEM,KAAK;CAMZ"}
@@ -67,6 +67,15 @@ class TurnUsageMonitor extends events_1.EventEmitter {
67
67
  getUsage(turnIp) {
68
68
  return this._turnUsage.get(turnIp);
69
69
  }
70
+ get clients() {
71
+ const result = new Map();
72
+ for (const pc of this.peerConnections) {
73
+ if (result.has(pc.clientId))
74
+ continue;
75
+ result.set(pc.clientId, pc.client);
76
+ }
77
+ return result;
78
+ }
70
79
  get closed() {
71
80
  return this._closed;
72
81
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@observertc/observer-js",
3
- "version": "0.40.10-beta",
3
+ "version": "0.40.12",
4
4
  "description": "Server Side NodeJS Library for processing ObserveRTC Samples",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -12,6 +12,14 @@ import { ObservedSfu } from './ObservedSfu';
12
12
 
13
13
  const logger = createLogger('ObservedClient');
14
14
 
15
+ export interface ClientIssue {
16
+ severity: 'critical' | 'major' | 'minor';
17
+ timestamp: number;
18
+ description?: string;
19
+ peerConnectionId?: string,
20
+ trackId?: string,
21
+ }
22
+
15
23
  export type ObservedClientModel= {
16
24
  clientId: string;
17
25
  mediaUnitId: string;
@@ -46,7 +54,9 @@ export type ObservedClientEvents = {
46
54
  localCandidate: IceLocalCandidate,
47
55
  remoteCandidate: IceRemoteCandidate,
48
56
  }],
57
+ issue: [ClientIssue],
49
58
  usingturn: [boolean],
59
+ usermediaerror: [string],
50
60
  };
51
61
 
52
62
  export declare interface ObservedClient<AppData extends Record<string, unknown> = Record<string, unknown>> {
@@ -252,7 +262,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
252
262
  {
253
263
  type: CallMetaType.OPERATION_SYSTEM,
254
264
  payload: sample.os,
255
- }, this.userId);
265
+ },
266
+ this.userId,
267
+ undefined,
268
+ sample.timestamp
269
+ );
256
270
 
257
271
  this.reports.addCallMetaReport(callMetaReport);
258
272
  }
@@ -272,7 +286,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
272
286
  {
273
287
  type: CallMetaType.ENGINE,
274
288
  payload: sample.engine,
275
- }, this.userId);
289
+ },
290
+ this.userId,
291
+ undefined,
292
+ sample.timestamp
293
+ );
276
294
 
277
295
  this.reports.addCallMetaReport(callMetaReport);
278
296
  }
@@ -293,7 +311,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
293
311
  {
294
312
  type: CallMetaType.PLATFORM,
295
313
  payload: sample.platform,
296
- }, this.userId);
314
+ },
315
+ this.userId,
316
+ undefined,
317
+ sample.timestamp
318
+ );
297
319
 
298
320
  this.reports.addCallMetaReport(callMetaReport);
299
321
  }
@@ -313,7 +335,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
313
335
  {
314
336
  type: CallMetaType.BROWSER,
315
337
  payload: sample.browser,
316
- }, this.userId);
338
+ },
339
+ this.userId,
340
+ undefined,
341
+ sample.timestamp
342
+ );
317
343
 
318
344
  this.reports.addCallMetaReport(callMetaReport);
319
345
  }
@@ -328,7 +354,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
328
354
  {
329
355
  type: CallMetaType.MEDIA_CONSTRAINT,
330
356
  payload: mediaConstraint,
331
- }, this.userId);
357
+ },
358
+ this.userId,
359
+ undefined,
360
+ sample.timestamp
361
+ );
332
362
 
333
363
  this.reports.addCallMetaReport(callMetaReport);
334
364
  }
@@ -343,7 +373,11 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
343
373
  {
344
374
  type: CallMetaType.LOCAL_SDP,
345
375
  payload: localSDP,
346
- }, this.userId);
376
+ },
377
+ this.userId,
378
+ undefined,
379
+ sample.timestamp
380
+ );
347
381
 
348
382
  this.reports.addCallMetaReport(callMetaReport);
349
383
  }
@@ -368,6 +402,17 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
368
402
  this._left = timestamp;
369
403
  break;
370
404
  }
405
+ case CallEventType.CLIENT_ISSUE: {
406
+ const severity = callEvent.value ? callEvent.value as ClientIssue['severity'] : 'minor';
407
+
408
+ this.emit('issue', {
409
+ severity,
410
+ timestamp: timestamp ?? Date.now(),
411
+ description: callEvent.message,
412
+ peerConnectionId: callEvent.peerConnectionId,
413
+ trackId: callEvent.mediaTrackId,
414
+ });
415
+ }
371
416
  }
372
417
  this.reports.addCallEventReport({
373
418
  serviceId: this.serviceId,
@@ -390,10 +435,13 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
390
435
  this.clientId, {
391
436
  type: CallMetaType.USER_MEDIA_ERROR,
392
437
  payload: userMediaError,
393
- }, this.userId);
438
+ },
439
+ this.userId,
440
+ );
394
441
 
395
442
  this.reports.addCallMetaReport(callMetaReport);
396
443
  this.userMediaErrors.push(userMediaError);
444
+ this.emit('usermediaerror', userMediaError);
397
445
  }
398
446
 
399
447
  for (const certificate of sample.certificates ?? []) {
@@ -405,7 +453,9 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
405
453
  this.clientId, {
406
454
  type: CallMetaType.CERTIFICATE,
407
455
  payload: certificate,
408
- }, this.userId);
456
+ },
457
+ this.userId
458
+ );
409
459
 
410
460
  this.reports.addCallMetaReport(callMetaReport);
411
461
  }
@@ -606,7 +656,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
606
656
  continue;
607
657
  }
608
658
 
609
- peerConnection.ICE.addLocalCandidate(iceLocalCandidate);
659
+ peerConnection.ICE.addLocalCandidate(iceLocalCandidate, sample.timestamp);
610
660
  }
611
661
 
612
662
  for (const iceRemoteCandidate of sample.iceRemoteCandidates ?? []) {
@@ -621,7 +671,7 @@ export class ObservedClient<AppData extends Record<string, unknown> = Record<str
621
671
  continue;
622
672
  }
623
673
 
624
- peerConnection.ICE.addRemoteCandidate(iceRemoteCandidate);
674
+ peerConnection.ICE.addRemoteCandidate(iceRemoteCandidate, sample.timestamp);
625
675
  }
626
676
 
627
677
  for (const candidatePair of sample.iceCandidatePairs ?? []) {
@@ -100,7 +100,7 @@ export class ObservedICE extends EventEmitter {
100
100
  this.emit('close');
101
101
  }
102
102
 
103
- public addLocalCandidate(candidate: IceLocalCandidate) {
103
+ public addLocalCandidate(candidate: IceLocalCandidate, sampleTimestamp?: number) {
104
104
  if (!candidate.id) return;
105
105
 
106
106
  const newCandidate = !this._localCandidates.has(candidate.id);
@@ -116,7 +116,11 @@ export class ObservedICE extends EventEmitter {
116
116
  this.peerConnection.client.clientId, {
117
117
  type: CallMetaType.ICE_LOCAL_CANDIDATE,
118
118
  payload: candidate,
119
- }, this.peerConnection.client.userId);
119
+ },
120
+ this.peerConnection.client.userId,
121
+ this.peerConnection.peerConnectionId,
122
+ sampleTimestamp,
123
+ );
120
124
 
121
125
  this.reports.addCallMetaReport(callMetaReport);
122
126
 
@@ -124,7 +128,7 @@ export class ObservedICE extends EventEmitter {
124
128
  }
125
129
  }
126
130
 
127
- public addRemoteCandidate(candidate: IceRemoteCandidate) {
131
+ public addRemoteCandidate(candidate: IceRemoteCandidate, sampleTimestamp?: number) {
128
132
  if (!candidate.id) return;
129
133
 
130
134
  const newCandidate = !this._remoteCandidates.has(candidate.id);
@@ -140,7 +144,11 @@ export class ObservedICE extends EventEmitter {
140
144
  this.peerConnection.client.clientId, {
141
145
  type: CallMetaType.ICE_REMOTE_CANDIDATE,
142
146
  payload: candidate,
143
- }, this.peerConnection.client.userId);
147
+ },
148
+ this.peerConnection.client.userId,
149
+ this.peerConnection.peerConnectionId,
150
+ sampleTimestamp
151
+ );
144
152
 
145
153
  this.reports.addCallMetaReport(callMetaReport);
146
154
 
@@ -12,6 +12,7 @@ export type ObservedOutboundTrackModel<K extends MediaKind> = {
12
12
  }
13
13
 
14
14
  export type ObservedOutboundTrackEvents = {
15
+ qualitylimitationchanged: [string];
15
16
  update: [{
16
17
  elapsedTimeInMs: number;
17
18
  }],
@@ -197,6 +198,14 @@ export class ObservedOutboundTrack<Kind extends MediaKind> extends EventEmitter
197
198
  if (videoSample?.framesSent && lastVideoStats?.framesSent && lastVideoStats.framesSent < videoSample.framesSent) {
198
199
  deltaSentFrames = videoSample.framesSent - lastVideoStats.framesSent;
199
200
  }
201
+
202
+ if (videoSample.qualityLimitationReason && lastVideoStats?.qualityLimitationReason !== videoSample.qualityLimitationReason) {
203
+ this.emit('qualitylimitationchanged', videoSample.qualityLimitationReason);
204
+ }
205
+ } else if (this.kind === 'audio') {
206
+ // const audioSample = sample as OutboundAudioTrack;
207
+ // const lastAudioStats = lastStat as OutboundAudioTrack | undefined;
208
+
200
209
  }
201
210
  const stats: ObservedOutboundTrackStats<Kind> = {
202
211
  ...sample,
@@ -105,6 +105,8 @@ export class ObservedSfu<AppData extends Record<string, unknown> = Record<string
105
105
  this._timeZoneOffsetInHours = sample.timeZoneOffsetInHours;
106
106
  }
107
107
 
108
+ this._marker = sample.marker;
109
+
108
110
  const now = Date.now();
109
111
  const elapsedTimeInMs = now - this._updated;
110
112
 
package/src/Observer.ts CHANGED
@@ -6,7 +6,7 @@ import { PartialBy } from './common/utils';
6
6
  import { createCallEndedEventReport, createCallStartedEventReport } from './common/callEventReports';
7
7
  import { ObserverSinkContext } from './common/types';
8
8
  import { ObservedSfu, ObservedSfuModel } from './ObservedSfu';
9
- import { CallSummaryMonitor } from './monitors/CallSummaryMonitor';
9
+ import { CallSummaryMonitor, CallSummaryMonitorConfig } from './monitors/CallSummaryMonitor';
10
10
  import { TurnUsageMonitor } from './monitors/TurnUsageMonitor';
11
11
  import { ObservedClient } from './ObservedClient';
12
12
  import { ObservedPeerConnection } from './ObservedPeerConnection';
@@ -104,13 +104,19 @@ export class Observer extends EventEmitter {
104
104
  }
105
105
 
106
106
  public createObservedCall<T extends Record<string, unknown> = Record<string, unknown>>(
107
- config: PartialBy<ObservedCallModel, 'serviceId'> & { appData: T, started?: number }
107
+ config: PartialBy<ObservedCallModel, 'serviceId'> & { appData: T, started?: number, reportCallStarted?: boolean, reportCallEnded?: boolean }
108
108
  ): ObservedCall<T> {
109
109
  if (this._closed) {
110
110
  throw new Error('Attempted to create a call source on a closed observer');
111
111
  }
112
112
 
113
- const { appData, started = Date.now(), ...model } = config;
113
+ const {
114
+ appData,
115
+ started = Date.now(),
116
+ reportCallEnded = true,
117
+ reportCallStarted = true,
118
+ ...model
119
+ } = config;
114
120
  const call = new ObservedCall({
115
121
  ...model,
116
122
  serviceId: this.config.defaultServiceId,
@@ -121,7 +127,7 @@ export class Observer extends EventEmitter {
121
127
 
122
128
  call.once('close', () => {
123
129
  this._observedCalls.delete(call.callId);
124
- this.reports.addCallEventReport(createCallEndedEventReport(
130
+ reportCallEnded && this.reports.addCallEventReport(createCallEndedEventReport(
125
131
  call.serviceId,
126
132
  call.roomId,
127
133
  call.callId,
@@ -130,7 +136,7 @@ export class Observer extends EventEmitter {
130
136
  });
131
137
 
132
138
  this._observedCalls.set(call.callId, call);
133
- this.reports.addCallEventReport(createCallStartedEventReport(
139
+ reportCallStarted && this.reports.addCallEventReport(createCallStartedEventReport(
134
140
  call.serviceId,
135
141
  call.roomId,
136
142
  call.callId,
@@ -165,14 +171,14 @@ export class Observer extends EventEmitter {
165
171
  return sfu;
166
172
  }
167
173
 
168
- public createCallSummaryMonitor(options?: { timeoutAfterCallClose?: number }): CallSummaryMonitor {
174
+ public createCallSummaryMonitor(options?: CallSummaryMonitorConfig & { timeoutAfterCallClose?: number }): CallSummaryMonitor {
169
175
  if (this._closed) throw new Error('Cannot create a call summary monitor on a closed observer');
170
176
 
171
177
  const existingMonitor = this._monitors.get(CallSummaryMonitor.name);
172
178
 
173
179
  if (existingMonitor) return existingMonitor as CallSummaryMonitor;
174
180
 
175
- const monitor = new CallSummaryMonitor();
181
+ const monitor = new CallSummaryMonitor(options);
176
182
  const onNewCall = (call: ObservedCall) => {
177
183
  monitor.addCall(call);
178
184
 
@@ -1,5 +1,4 @@
1
1
  // eslint-disable-next-line no-shadow
2
-
3
2
  export enum CallEventType {
4
3
  CALL_STARTED = 'CALL_STARTED',
5
4
  CALL_ENDED = 'CALL_ENDED',
@@ -20,4 +19,5 @@ export enum CallEventType {
20
19
  DATA_CHANNEL_ERROR = 'DATA_CHANNEL_ERROR',
21
20
  NEGOTIATION_NEEDED = 'NEGOTIATION_NEEDED',
22
21
  SIGNALING_STATE_CHANGE = 'SIGNALING_STATE_CHANGE',
22
+ CLIENT_ISSUE = 'CLIENT_ISSUE',
23
23
  }
@@ -84,6 +84,7 @@ export function createCallMetaReport(
84
84
  clientId: string,
85
85
  reportType: CallMetaReportType,
86
86
  userId?: string,
87
+ peerConnectionId?: string,
87
88
  timestamp?: number
88
89
  ) {
89
90
  const report: CallMetaReport = {
@@ -1,14 +1,19 @@
1
+ import { ClientIssue } from '../ObservedClient';
2
+
1
3
  export interface ClientSummary {
2
4
  clientId: string;
3
5
  mediaUnitId: string;
4
6
  userId?: string;
5
7
  joined: number;
8
+ left?: number;
6
9
  durationInMs: number;
7
10
  avgOutboundAudioBitrate: number,
8
11
  avgOutboundVideoBitrate: number,
9
12
  avgInboundAudioBitrate: number,
10
13
  avgInboundVideoBitrate: number,
11
14
  ewmaRttInMs: number,
15
+ usedTurn: boolean;
16
+ issues: ClientIssue[];
12
17
  }
13
18
 
14
19
  export interface CallSummary {
@@ -1,13 +1,20 @@
1
1
  import { EventEmitter } from 'events';
2
- import { CallSummary } from './CallSummary';
2
+ import { CallSummary, ClientSummary } from './CallSummary';
3
3
  import { ObservedCall } from '../ObservedCall';
4
- import { ObservedClient } from '../ObservedClient';
4
+ import { ClientIssue, ObservedClient } from '../ObservedClient';
5
+ import { ObservedOutboundTrack } from '../ObservedOutboundTrack';
6
+ import { ObservedPeerConnection } from '../ObservedPeerConnection';
5
7
 
6
8
  export type CallSummaryMonitorEvents = {
7
9
  close: [],
8
10
  summary: [CallSummary],
9
11
  }
10
12
 
13
+ export type CallSummaryMonitorConfig = {
14
+ detectUserMediaIssues?: boolean;
15
+ detectMediaTrackQualityLimitationIssues?: boolean;
16
+ }
17
+
11
18
  export declare interface CallSummaryMonitor {
12
19
  on<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
13
20
  off<U extends keyof CallSummaryMonitorEvents>(event: U, listener: (...args: CallSummaryMonitorEvents[U]) => void): this;
@@ -19,7 +26,9 @@ export class CallSummaryMonitor extends EventEmitter {
19
26
  private readonly _summaries = new Map<string, CallSummary>();
20
27
 
21
28
  private _closed = false;
22
- public constructor() {
29
+ public constructor(
30
+ public readonly config: CallSummaryMonitorConfig = {},
31
+ ) {
23
32
  super();
24
33
  }
25
34
 
@@ -50,7 +59,7 @@ export class CallSummaryMonitor extends EventEmitter {
50
59
 
51
60
  private _addClient(callSummary: CallSummary, client: ObservedClient) {
52
61
  if (this.closed) return;
53
- const clientSummary = {
62
+ const clientSummary: ClientSummary = {
54
63
  clientId: client.clientId,
55
64
  mediaUnitId: client.mediaUnitId,
56
65
  durationInMs: 0,
@@ -61,6 +70,8 @@ export class CallSummaryMonitor extends EventEmitter {
61
70
  ewmaRttInMs: 0,
62
71
  joined: client.created,
63
72
  userId: client.userId,
73
+ usedTurn: false,
74
+ issues: [],
64
75
  };
65
76
 
66
77
  callSummary.clients.push(clientSummary);
@@ -71,7 +82,34 @@ export class CallSummaryMonitor extends EventEmitter {
71
82
  }
72
83
  };
73
84
 
85
+ const onUsingTurn = (usingTurn: boolean) => {
86
+ clientSummary.usedTurn ||= usingTurn;
87
+ };
88
+
89
+ const onIssue = (issue: ClientIssue) => {
90
+ clientSummary.issues.push(issue);
91
+ };
92
+
93
+ const onUserMediaError = (error: string) => {
94
+ if (!this.config.detectUserMediaIssues) return;
95
+
96
+ // maybe the client also sned this issue, in which case the timestamp can be more accurate
97
+ const alreadyDetected = clientSummary.issues.find((issue) => issue.severity === 'critical' && issue.description === error);
98
+
99
+ !alreadyDetected && clientSummary.issues.push({
100
+ severity: 'critical',
101
+ timestamp: Date.now(),
102
+ description: error,
103
+ });
104
+ };
105
+
106
+ const onNewPeerConnection = (peerConnection: ObservedPeerConnection) => this._addPeerConnection(clientSummary, peerConnection);
107
+
74
108
  client.on('update', updateClient);
109
+ client.on('usingturn', onUsingTurn);
110
+ client.on('issue', onIssue);
111
+ client.on('usermediaerror', onUserMediaError);
112
+ client.on('newpeerconnection', onNewPeerConnection);
75
113
  client.once('close', () => {
76
114
  const elapsedTimeInS = (Date.now() - client.created) / 1000;
77
115
 
@@ -81,7 +119,41 @@ export class CallSummaryMonitor extends EventEmitter {
81
119
  clientSummary.avgOutboundVideoBitrate = (client.totalSentBytes * 8) / elapsedTimeInS;
82
120
  clientSummary.durationInMs = elapsedTimeInS * 1000;
83
121
  client.off('update', updateClient);
122
+ client.off('usingturn', onUsingTurn);
123
+ client.off('issue', onIssue);
124
+ client.off('usermediaerror', onUserMediaError);
125
+ client.off('newpeerconnection', onNewPeerConnection);
126
+
127
+ callSummary.durationInMs += clientSummary.durationInMs;
128
+ });
129
+ }
130
+
131
+ private _addPeerConnection(clientSummary: ClientSummary, peerConnection: ObservedPeerConnection) {
132
+ const onOutboundVideoTrack = (track: ObservedOutboundTrack<'video'>) => this._addOutboundVideoTrack(clientSummary, track);
133
+
134
+ peerConnection.on('newoutboundvideotrack', onOutboundVideoTrack);
135
+ peerConnection.once('close', () => {
136
+ peerConnection.off('newoutboundvideotrack', onOutboundVideoTrack);
137
+ });
138
+ }
139
+
140
+ private _addOutboundVideoTrack(clientSummary: ClientSummary, track: ObservedOutboundTrack<'video'>) {
141
+ const onQualityLimitationChanged = (reason: string) => {
142
+ if (!this.config.detectMediaTrackQualityLimitationIssues) return;
143
+
144
+ clientSummary.issues.push({
145
+ severity: 'minor',
146
+ timestamp: Date.now(),
147
+ description: reason,
148
+ peerConnectionId: track.peerConnectionId,
149
+ trackId: track.trackId,
150
+ });
151
+ };
152
+
153
+ track.once('close', () => {
154
+ track.off('qualitylimitationchanged', onQualityLimitationChanged);
84
155
  });
156
+ track.on('qualitylimitationchanged', onQualityLimitationChanged);
85
157
  }
86
158
 
87
159
  public takeSummary(callId: string): CallSummary | undefined {
@@ -1,6 +1,7 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import { ObservedPeerConnection } from '../ObservedPeerConnection';
3
3
  import { ObservedICEEvents } from '../ObservedICE';
4
+ import { ObservedClient } from '../ObservedClient';
4
5
 
5
6
  export type TurnUsageMonitorEvents = {
6
7
  close: [],
@@ -111,6 +112,18 @@ export class TurnUsageMonitor extends EventEmitter {
111
112
  return this._turnUsage.get(turnIp);
112
113
  }
113
114
 
115
+ public get clients(): ReadonlyMap<string, ObservedClient> {
116
+ const result = new Map<string, ObservedClient>();
117
+
118
+ for (const pc of this.peerConnections) {
119
+ if (result.has(pc.clientId)) continue;
120
+
121
+ result.set(pc.clientId, pc.client);
122
+ }
123
+
124
+ return result;
125
+ }
126
+
114
127
  public get closed() {
115
128
  return this._closed;
116
129
  }