This repository has been archived by the owner on May 30, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 65
/
Copy pathdiagnostic_events.js
151 lines (137 loc) · 5.24 KB
/
diagnostic_events.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
const os = require('os');
const { v4: uuidv4 } = require('uuid');
const configuration = require('./configuration');
const packageJson = require('./package.json');
// An object that maintains information that will go into diagnostic events, and knows how to format
// those events. It is instantiated by the SDK client, and shared with the event processor.
function DiagnosticsManager(config, diagnosticId, startTime) {
let dataSinceDate = startTime;
let streamInits = [];
const acc = {};
// Creates the initial event that is sent by the event processor when the SDK starts up. This will not
// be repeated during the lifetime of the SDK client.
acc.createInitEvent = () => ({
kind: 'diagnostic-init',
id: diagnosticId,
creationDate: startTime,
sdk: makeSdkData(config),
configuration: makeConfigData(config),
platform: makePlatformData(),
});
// Records a stream connection attempt (called by the stream processor).
// timestamp: Time of the *beginning* of the connection attempt.
// failed: True if the connection failed, or we got a read timeout before receiving a "put".
// durationMillis: Elapsed time between starting timestamp and when we either gave up/lost the
// connection or received a successful "put".
acc.recordStreamInit = (timestamp, failed, durationMillis) => {
const item = { timestamp, failed, durationMillis };
streamInits.push(item);
};
// Creates a periodic event containing time-dependent stats, and resets the state of the manager with
// regard to those stats.
// Note: the reason droppedEvents, deduplicatedUsers, and eventsInLastBatch are passed into this function,
// instead of being properties of the DiagnosticsManager, is that the event processor is the one who's
// calling this function and is also the one who's tracking those stats.
acc.createStatsEventAndReset = (droppedEvents, deduplicatedUsers, eventsInLastBatch) => {
const currentTime = new Date().getTime();
const ret = {
kind: 'diagnostic',
id: diagnosticId,
creationDate: currentTime,
dataSinceDate,
droppedEvents,
deduplicatedUsers,
eventsInLastBatch,
streamInits,
};
dataSinceDate = currentTime;
streamInits = [];
return ret;
};
return acc;
}
function DiagnosticId(sdkKey) {
const ret = {
diagnosticId: uuidv4(),
};
if (sdkKey) {
ret.sdkKeySuffix = sdkKey.length > 6 ? sdkKey.substring(sdkKey.length - 6) : sdkKey;
}
return ret;
}
function makeSdkData(config) {
const sdkData = {
name: 'node-server-sdk',
version: packageJson.version,
};
if (config.wrapperName) {
sdkData.wrapperName = config.wrapperName;
}
if (config.wrapperVersion) {
sdkData.wrapperVersion = config.wrapperVersion;
}
return sdkData;
}
function makeConfigData(config) {
const defaults = configuration.defaults();
const secondsToMillis = sec => Math.trunc(sec * 1000);
function getComponentDescription(component, defaultName) {
if (component) {
return component.description || 'custom';
}
return defaultName;
}
const configData = {
customBaseURI: config.baseUri !== defaults.baseUri,
customStreamURI: config.streamUri !== defaults.streamUri,
customEventsURI: config.eventsUri !== defaults.eventsUri,
eventsCapacity: config.capacity,
connectTimeoutMillis: secondsToMillis(config.timeout),
socketTimeoutMillis: secondsToMillis(config.timeout), // Node doesn't distinguish between these two kinds of timeouts
eventsFlushIntervalMillis: secondsToMillis(config.flushInterval),
pollingIntervalMillis: secondsToMillis(config.pollInterval),
// startWaitMillis: n/a (Node SDK does not have this feature)
// samplingInterval: n/a (Node SDK does not have this feature)
reconnectTimeMillis: secondsToMillis(config.streamInitialReconnectDelay),
streamingDisabled: !config.stream,
usingRelayDaemon: !!config.useLdd,
offline: !!config.offline,
allAttributesPrivate: !!config.allAttributesPrivate,
contextKeysCapacity: config.contextKeysCapacity,
contextKeysFlushIntervalMillis: secondsToMillis(config.contextKeysFlushInterval),
usingProxy: !!(config.proxyAgent || config.proxyHost),
usingProxyAuthenticator: !!config.proxyAuth,
diagnosticRecordingIntervalMillis: secondsToMillis(config.diagnosticRecordingInterval),
dataStoreType: getComponentDescription(config.featureStore, 'memory'),
};
return configData;
}
function makePlatformData() {
return {
name: 'Node',
osArch: os.arch(),
osName: normalizePlatformName(os.platform()),
osVersion: os.release(),
// Note that os.release() is not the same OS version string that would be reported by other languages.
// It's defined as being the value returned by "uname -r" (e.g. on Mac OS 10.14, this is "18.7.0"; on
// Ubuntu 16.04, it is "4.4.0-1095-aws"), or GetVersionExW in Windows.
nodeVersion: process.versions.node,
};
}
function normalizePlatformName(platformName) {
// The following logic is based on how Node.js reports the platform name
switch (platformName) {
case 'darwin':
return 'MacOS';
case 'win32':
return 'Windows';
case 'linux':
return 'Linux';
default:
return platformName;
}
}
module.exports = {
DiagnosticsManager,
DiagnosticId,
};