UNPKG

3.86 kBJavaScriptView Raw
1Object.defineProperty(exports, '__esModule', { value: true });
2
3const utils = require('@sentry/utils');
4const hub = require('./hub.js');
5
6/**
7 * @inheritdoc
8 */
9class SessionFlusher {
10 __init() {this.flushTimeout = 60;}
11 __init2() {this._pendingAggregates = {};}
12
13 __init3() {this._isEnabled = true;}
14
15 constructor(client, attrs) {SessionFlusher.prototype.__init.call(this);SessionFlusher.prototype.__init2.call(this);SessionFlusher.prototype.__init3.call(this);
16 this._client = client;
17 // Call to setInterval, so that flush is called every 60 seconds
18 this._intervalId = setInterval(() => this.flush(), this.flushTimeout * 1000);
19 this._sessionAttrs = attrs;
20 }
21
22 /** Checks if `pendingAggregates` has entries, and if it does flushes them by calling `sendSession` */
23 flush() {
24 const sessionAggregates = this.getSessionAggregates();
25 if (sessionAggregates.aggregates.length === 0) {
26 return;
27 }
28 this._pendingAggregates = {};
29 this._client.sendSession(sessionAggregates);
30 }
31
32 /** Massages the entries in `pendingAggregates` and returns aggregated sessions */
33 getSessionAggregates() {
34 const aggregates = Object.keys(this._pendingAggregates).map((key) => {
35 return this._pendingAggregates[parseInt(key)];
36 });
37
38 const sessionAggregates = {
39 attrs: this._sessionAttrs,
40 aggregates,
41 };
42 return utils.dropUndefinedKeys(sessionAggregates);
43 }
44
45 /** JSDoc */
46 close() {
47 clearInterval(this._intervalId);
48 this._isEnabled = false;
49 this.flush();
50 }
51
52 /**
53 * Wrapper function for _incrementSessionStatusCount that checks if the instance of SessionFlusher is enabled then
54 * fetches the session status of the request from `Scope.getRequestSession().status` on the scope and passes them to
55 * `_incrementSessionStatusCount` along with the start date
56 */
57 incrementSessionStatusCount() {
58 if (!this._isEnabled) {
59 return;
60 }
61 const scope = hub.getCurrentHub().getScope();
62 const requestSession = scope && scope.getRequestSession();
63
64 if (requestSession && requestSession.status) {
65 this._incrementSessionStatusCount(requestSession.status, new Date());
66 // This is not entirely necessarily but is added as a safe guard to indicate the bounds of a request and so in
67 // case captureRequestSession is called more than once to prevent double count
68 if (scope) {
69 scope.setRequestSession(undefined);
70 }
71 /* eslint-enable @typescript-eslint/no-unsafe-member-access */
72 }
73 }
74
75 /**
76 * Increments status bucket in pendingAggregates buffer (internal state) corresponding to status of
77 * the session received
78 */
79 _incrementSessionStatusCount(status, date) {
80 // Truncate minutes and seconds on Session Started attribute to have one minute bucket keys
81 const sessionStartedTrunc = new Date(date).setSeconds(0, 0);
82 this._pendingAggregates[sessionStartedTrunc] = this._pendingAggregates[sessionStartedTrunc] || {};
83
84 // corresponds to aggregated sessions in one specific minute bucket
85 // for example, {"started":"2021-03-16T08:00:00.000Z","exited":4, "errored": 1}
86 const aggregationCounts = this._pendingAggregates[sessionStartedTrunc];
87 if (!aggregationCounts.started) {
88 aggregationCounts.started = new Date(sessionStartedTrunc).toISOString();
89 }
90
91 switch (status) {
92 case 'errored':
93 aggregationCounts.errored = (aggregationCounts.errored || 0) + 1;
94 return aggregationCounts.errored;
95 case 'ok':
96 aggregationCounts.exited = (aggregationCounts.exited || 0) + 1;
97 return aggregationCounts.exited;
98 default:
99 aggregationCounts.crashed = (aggregationCounts.crashed || 0) + 1;
100 return aggregationCounts.crashed;
101 }
102 }
103}
104
105exports.SessionFlusher = SessionFlusher;
106//# sourceMappingURL=sessionflusher.js.map