@splitsoftware/splitio-commons 1.3.1 → 1.3.2-rc.2
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.
- package/cjs/consent/sdkUserConsent.js +1 -1
- package/cjs/listeners/browser.js +5 -4
- package/cjs/logger/constants.js +2 -1
- package/cjs/logger/messages/error.js +2 -1
- package/cjs/logger/messages/info.js +3 -3
- package/cjs/logger/messages/warn.js +2 -2
- package/cjs/sdkClient/client.js +17 -3
- package/cjs/sdkClient/sdkClient.js +4 -1
- package/cjs/sdkFactory/index.js +16 -19
- package/cjs/services/splitApi.js +15 -14
- package/cjs/services/splitHttpClient.js +4 -1
- package/cjs/storages/AbstractSegmentsCacheSync.js +0 -5
- package/cjs/storages/KeyBuilderSS.js +12 -19
- package/cjs/storages/findLatencyIndex.js +11 -6
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +13 -1
- package/cjs/storages/inLocalStorage/index.js +4 -1
- package/cjs/storages/inMemory/InMemoryStorage.js +2 -0
- package/cjs/storages/inMemory/InMemoryStorageCS.js +3 -0
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +6 -0
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +6 -0
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +165 -0
- package/cjs/storages/inRedis/TelemetryCacheInRedis.js +29 -0
- package/cjs/storages/inRedis/index.js +2 -4
- package/cjs/storages/pluggable/TelemetryCachePluggable.js +27 -0
- package/cjs/storages/pluggable/index.js +2 -1
- package/cjs/sync/polling/pollingManagerCS.js +1 -1
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +0 -3
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -8
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +3 -6
- package/cjs/sync/streaming/SSEHandler/NotificationKeeper.js +20 -13
- package/cjs/sync/streaming/SSEHandler/index.js +21 -15
- package/cjs/sync/streaming/pushManager.js +7 -4
- package/cjs/sync/submitters/eventsSubmitter.js +28 -0
- package/cjs/sync/submitters/{impressionCountsSyncTask.js → impressionCountsSubmitter.js} +10 -7
- package/cjs/sync/submitters/{impressionsSyncTask.js → impressionsSubmitter.js} +8 -8
- package/cjs/sync/submitters/submitter.js +66 -0
- package/cjs/sync/submitters/submitterManager.js +12 -10
- package/cjs/sync/submitters/telemetrySubmitter.js +128 -0
- package/cjs/sync/syncManagerOnline.js +6 -2
- package/cjs/trackers/eventTracker.js +5 -1
- package/cjs/trackers/impressionsTracker.js +9 -1
- package/cjs/trackers/telemetryTracker.js +65 -0
- package/cjs/utils/constants/index.js +40 -1
- package/cjs/utils/inputValidation/apiKey.js +12 -11
- package/cjs/utils/settingsValidation/index.js +35 -11
- package/cjs/utils/settingsValidation/url.js +4 -0
- package/cjs/utils/timeTracker/index.js +1 -0
- package/cjs/utils/timeTracker/timer.js +2 -2
- package/esm/consent/sdkUserConsent.js +1 -1
- package/esm/listeners/browser.js +3 -2
- package/esm/logger/constants.js +1 -0
- package/esm/logger/messages/error.js +2 -1
- package/esm/logger/messages/info.js +3 -3
- package/esm/logger/messages/warn.js +2 -2
- package/esm/sdkClient/client.js +18 -4
- package/esm/sdkClient/sdkClient.js +4 -1
- package/esm/sdkFactory/index.js +16 -19
- package/esm/services/splitApi.js +15 -14
- package/esm/services/splitHttpClient.js +4 -1
- package/esm/storages/AbstractSegmentsCacheSync.js +0 -5
- package/esm/storages/KeyBuilderSS.js +12 -19
- package/esm/storages/findLatencyIndex.js +11 -6
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +13 -1
- package/esm/storages/inLocalStorage/index.js +5 -2
- package/esm/storages/inMemory/InMemoryStorage.js +3 -1
- package/esm/storages/inMemory/InMemoryStorageCS.js +4 -1
- package/esm/storages/inMemory/MySegmentsCacheInMemory.js +6 -0
- package/esm/storages/inMemory/SegmentsCacheInMemory.js +6 -0
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +161 -0
- package/esm/storages/inRedis/TelemetryCacheInRedis.js +26 -0
- package/esm/storages/inRedis/index.js +2 -4
- package/esm/storages/pluggable/TelemetryCachePluggable.js +24 -0
- package/esm/storages/pluggable/index.js +2 -1
- package/esm/sync/polling/pollingManagerCS.js +1 -1
- package/esm/sync/polling/syncTasks/splitsSyncTask.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +0 -3
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -8
- package/esm/sync/polling/updaters/splitChangesUpdater.js +3 -6
- package/esm/sync/streaming/SSEHandler/NotificationKeeper.js +8 -1
- package/esm/sync/streaming/SSEHandler/index.js +21 -15
- package/esm/sync/streaming/pushManager.js +7 -4
- package/esm/sync/submitters/eventsSubmitter.js +24 -0
- package/esm/sync/submitters/{impressionCountsSyncTask.js → impressionCountsSubmitter.js} +8 -5
- package/esm/sync/submitters/{impressionsSyncTask.js → impressionsSubmitter.js} +6 -6
- package/esm/sync/submitters/submitter.js +61 -0
- package/esm/sync/submitters/submitterManager.js +12 -10
- package/esm/sync/submitters/telemetrySubmitter.js +122 -0
- package/esm/sync/syncManagerOnline.js +6 -2
- package/esm/trackers/eventTracker.js +6 -2
- package/esm/trackers/impressionsTracker.js +10 -2
- package/esm/trackers/telemetryTracker.js +61 -0
- package/esm/utils/constants/index.js +38 -0
- package/esm/utils/inputValidation/apiKey.js +2 -1
- package/esm/utils/settingsValidation/index.js +34 -10
- package/esm/utils/settingsValidation/url.js +4 -0
- package/esm/utils/timeTracker/index.js +1 -0
- package/esm/utils/timeTracker/timer.js +2 -2
- package/package.json +1 -1
- package/src/consent/sdkUserConsent.ts +1 -1
- package/src/listeners/browser.ts +3 -2
- package/src/logger/constants.ts +1 -0
- package/src/logger/messages/error.ts +2 -1
- package/src/logger/messages/info.ts +3 -3
- package/src/logger/messages/warn.ts +2 -2
- package/src/sdkClient/client.ts +23 -4
- package/src/sdkClient/sdkClient.ts +4 -1
- package/src/sdkFactory/index.ts +22 -24
- package/src/sdkFactory/types.ts +32 -15
- package/src/services/splitApi.ts +17 -14
- package/src/services/splitHttpClient.ts +6 -3
- package/src/services/types.ts +7 -5
- package/src/storages/AbstractSegmentsCacheSync.ts +8 -3
- package/src/storages/KeyBuilderSS.ts +13 -50
- package/src/storages/findLatencyIndex.ts +12 -3
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +13 -1
- package/src/storages/inLocalStorage/index.ts +5 -2
- package/src/storages/inMemory/InMemoryStorage.ts +3 -1
- package/src/storages/inMemory/InMemoryStorageCS.ts +4 -1
- package/src/storages/inMemory/MySegmentsCacheInMemory.ts +8 -0
- package/src/storages/inMemory/SegmentsCacheInMemory.ts +6 -0
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +210 -0
- package/src/storages/inRedis/TelemetryCacheInRedis.ts +29 -0
- package/src/storages/inRedis/index.ts +2 -4
- package/src/storages/pluggable/TelemetryCachePluggable.ts +26 -0
- package/src/storages/pluggable/index.ts +2 -1
- package/src/storages/types.ts +84 -32
- package/src/sync/offline/syncManagerOffline.ts +4 -3
- package/src/sync/polling/pollingManagerCS.ts +3 -3
- package/src/sync/polling/pollingManagerSS.ts +2 -2
- package/src/sync/polling/syncTasks/splitsSyncTask.ts +2 -0
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +0 -4
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +2 -10
- package/src/sync/polling/updaters/splitChangesUpdater.ts +3 -6
- package/src/sync/streaming/SSEHandler/NotificationKeeper.ts +11 -1
- package/src/sync/streaming/SSEHandler/index.ts +21 -14
- package/src/sync/streaming/pushManager.ts +11 -7
- package/src/sync/submitters/eventsSubmitter.ts +35 -0
- package/src/sync/submitters/{impressionCountsSyncTask.ts → impressionCountsSubmitter.ts} +15 -15
- package/src/sync/submitters/{impressionsSyncTask.ts → impressionsSubmitter.ts} +12 -16
- package/src/sync/submitters/{submitterSyncTask.ts → submitter.ts} +34 -16
- package/src/sync/submitters/submitterManager.ts +14 -11
- package/src/sync/submitters/telemetrySubmitter.ts +143 -0
- package/src/sync/submitters/types.ts +123 -0
- package/src/sync/syncManagerOnline.ts +13 -7
- package/src/sync/types.ts +0 -15
- package/src/trackers/eventTracker.ts +7 -3
- package/src/trackers/impressionsTracker.ts +11 -3
- package/src/trackers/telemetryTracker.ts +63 -0
- package/src/trackers/types.ts +24 -0
- package/src/types.ts +35 -6
- package/src/utils/constants/index.ts +45 -0
- package/src/utils/inputValidation/apiKey.ts +2 -1
- package/src/utils/settingsValidation/index.ts +35 -11
- package/src/utils/settingsValidation/url.ts +4 -0
- package/src/utils/timeTracker/index.ts +1 -1
- package/src/utils/timeTracker/timer.ts +3 -3
- package/types/logger/constants.d.ts +1 -0
- package/types/sdkFactory/types.d.ts +29 -14
- package/types/services/splitApi.d.ts +2 -1
- package/types/services/types.d.ts +8 -5
- package/types/storages/AbstractSegmentsCacheSync.d.ts +7 -3
- package/types/storages/KeyBuilderSS.d.ts +3 -3
- package/types/storages/findLatencyIndex.d.ts +7 -1
- package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +2 -0
- package/types/storages/inMemory/MySegmentsCacheInMemory.d.ts +2 -0
- package/types/storages/inMemory/SegmentsCacheInMemory.d.ts +1 -0
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -2
- package/types/storages/inRedis/TelemetryCacheInRedis.d.ts +3 -3
- package/types/storages/pluggable/TelemetryCachePluggable.d.ts +2 -2
- package/types/storages/types.d.ts +71 -22
- package/types/sync/offline/syncManagerOffline.d.ts +3 -2
- package/types/sync/polling/pollingManagerCS.d.ts +2 -2
- package/types/sync/polling/pollingManagerSS.d.ts +2 -2
- package/types/sync/polling/syncTasks/splitsSyncTask.d.ts +1 -1
- package/types/sync/polling/updaters/splitChangesUpdater.d.ts +1 -1
- package/types/sync/streaming/SSEHandler/NotificationKeeper.d.ts +2 -1
- package/types/sync/streaming/SSEHandler/index.d.ts +2 -1
- package/types/sync/streaming/pushManager.d.ts +2 -2
- package/types/sync/submitters/eventsSubmitter.d.ts +5 -0
- package/types/sync/submitters/impressionCountsSubmitter.d.ts +10 -0
- package/types/sync/submitters/impressionsSubmitter.d.ts +11 -0
- package/types/sync/submitters/submitter.d.ts +12 -0
- package/types/sync/submitters/submitterManager.d.ts +2 -2
- package/types/sync/submitters/telemetrySubmitter.d.ts +24 -0
- package/types/sync/submitters/telemetrySyncTask.d.ts +0 -27
- package/types/sync/submitters/types.d.ts +107 -0
- package/types/sync/syncManagerOnline.d.ts +3 -2
- package/types/sync/types.d.ts +0 -13
- package/types/trackers/eventTracker.d.ts +2 -2
- package/types/trackers/impressionsTracker.d.ts +2 -2
- package/types/trackers/telemetryTracker.d.ts +2 -3
- package/types/trackers/types.d.ts +22 -0
- package/types/types.d.ts +33 -4
- package/types/utils/constants/index.d.ts +37 -0
- package/types/utils/inputValidation/apiKey.d.ts +1 -0
- package/types/utils/settingsValidation/index.d.ts +40 -0
- package/types/utils/timeTracker/index.d.ts +1 -1
- package/types/utils/timeTracker/timer.d.ts +1 -1
- package/cjs/storages/inMemory/CountsCacheInMemory.js +0 -38
- package/cjs/storages/inMemory/LatenciesCacheInMemory.js +0 -43
- package/cjs/storages/inRedis/CountsCacheInRedis.js +0 -16
- package/cjs/storages/inRedis/LatenciesCacheInRedis.js +0 -18
- package/cjs/sync/submitters/eventsSyncTask.js +0 -44
- package/cjs/sync/submitters/metricsSyncTask.js +0 -31
- package/cjs/sync/submitters/submitterSyncTask.js +0 -44
- package/esm/storages/inMemory/CountsCacheInMemory.js +0 -35
- package/esm/storages/inMemory/LatenciesCacheInMemory.js +0 -40
- package/esm/storages/inRedis/CountsCacheInRedis.js +0 -13
- package/esm/storages/inRedis/LatenciesCacheInRedis.js +0 -15
- package/esm/sync/submitters/eventsSyncTask.js +0 -40
- package/esm/sync/submitters/metricsSyncTask.js +0 -26
- package/esm/sync/submitters/submitterSyncTask.js +0 -40
- package/src/storages/inMemory/CountsCacheInMemory.ts +0 -37
- package/src/storages/inMemory/LatenciesCacheInMemory.ts +0 -45
- package/src/storages/inRedis/CountsCacheInRedis.ts +0 -20
- package/src/storages/inRedis/LatenciesCacheInRedis.ts +0 -23
- package/src/sync/submitters/eventsSyncTask.ts +0 -57
- package/src/sync/submitters/metricsSyncTask.ts +0 -49
|
@@ -62,3 +62,126 @@ export type StoredEventWithMetadata = {
|
|
|
62
62
|
/** Stored event */
|
|
63
63
|
e: SplitIO.EventData
|
|
64
64
|
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Telemetry usage stats
|
|
68
|
+
*/
|
|
69
|
+
|
|
70
|
+
export type QUEUED = 0;
|
|
71
|
+
export type DROPPED = 1;
|
|
72
|
+
export type DEDUPED = 2;
|
|
73
|
+
export type ImpressionDataType = QUEUED | DROPPED | DEDUPED
|
|
74
|
+
export type EventDataType = QUEUED | DROPPED;
|
|
75
|
+
|
|
76
|
+
export type SPLITS = 'sp';
|
|
77
|
+
export type IMPRESSIONS = 'im';
|
|
78
|
+
export type IMPRESSIONS_COUNT = 'ic';
|
|
79
|
+
export type EVENTS = 'ev';
|
|
80
|
+
export type TELEMETRY = 'te';
|
|
81
|
+
export type TOKEN = 'to';
|
|
82
|
+
export type SEGMENT = 'se';
|
|
83
|
+
export type MY_SEGMENT = 'ms';
|
|
84
|
+
export type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MY_SEGMENT;
|
|
85
|
+
|
|
86
|
+
export type LastSync = Record<OperationType, number | undefined>
|
|
87
|
+
export type HttpErrors = Record<OperationType, { [statusCode: string]: number }>
|
|
88
|
+
export type HttpLatencies = Record<OperationType, Array<number>>
|
|
89
|
+
|
|
90
|
+
export type TREATMENT = 't';
|
|
91
|
+
export type TREATMENTS = 'ts';
|
|
92
|
+
export type TREATMENT_WITH_CONFIG = 'tc';
|
|
93
|
+
export type TREATMENTS_WITH_CONFIG = 'tcs';
|
|
94
|
+
export type TRACK = 'tr';
|
|
95
|
+
export type Method = TREATMENT | TREATMENTS | TREATMENT_WITH_CONFIG | TREATMENTS_WITH_CONFIG | TRACK;
|
|
96
|
+
|
|
97
|
+
export type MethodLatencies = Record<Method, Array<number>>;
|
|
98
|
+
|
|
99
|
+
export type MethodExceptions = Record<Method, number>;
|
|
100
|
+
|
|
101
|
+
export type CONNECTION_ESTABLISHED = 0;
|
|
102
|
+
export type OCCUPANCY_PRI = 10;
|
|
103
|
+
export type OCCUPANCY_SEC = 20;
|
|
104
|
+
export type STREAMING_STATUS = 30;
|
|
105
|
+
export type SSE_CONNECTION_ERROR = 40;
|
|
106
|
+
export type TOKEN_REFRESH = 50;
|
|
107
|
+
export type ABLY_ERROR = 60;
|
|
108
|
+
export type SYNC_MODE_UPDATE = 70;
|
|
109
|
+
export type StreamingEventType = CONNECTION_ESTABLISHED | OCCUPANCY_PRI | OCCUPANCY_SEC | STREAMING_STATUS | SSE_CONNECTION_ERROR | TOKEN_REFRESH | ABLY_ERROR | SYNC_MODE_UPDATE;
|
|
110
|
+
|
|
111
|
+
export type StreamingEvent = {
|
|
112
|
+
e: StreamingEventType, // eventType
|
|
113
|
+
d?: number, // eventData
|
|
114
|
+
t: number, // timestamp
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 'metrics/usage' JSON request body
|
|
118
|
+
export type TelemetryUsageStatsPayload = {
|
|
119
|
+
lS: LastSync, // lastSynchronization
|
|
120
|
+
mL: MethodLatencies, // clientMethodLatencies
|
|
121
|
+
mE: MethodExceptions, // methodExceptions
|
|
122
|
+
hE: HttpErrors, // httpErrors
|
|
123
|
+
hL: HttpLatencies, // httpLatencies
|
|
124
|
+
tR: number, // tokenRefreshes
|
|
125
|
+
aR: number, // authRejections
|
|
126
|
+
iQ: number, // impressionsQueued
|
|
127
|
+
iDe: number, // impressionsDeduped
|
|
128
|
+
iDr: number, // impressionsDropped
|
|
129
|
+
spC: number, // splitCount
|
|
130
|
+
seC: number, // segmentCount
|
|
131
|
+
skC: number, // segmentKeyCount
|
|
132
|
+
sL?: number, // sessionLengthMs
|
|
133
|
+
eQ: number, // eventsQueued
|
|
134
|
+
eD: number, // eventsDropped
|
|
135
|
+
sE: Array<StreamingEvent>, // streamingEvents
|
|
136
|
+
t?: Array<string>, // tags
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Telemetry config stats
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
export type STANDALONE_ENUM = 0;
|
|
144
|
+
export type CONSUMER_ENUM = 1;
|
|
145
|
+
export type CONSUMER_PARTIAL_ENUM = 2;
|
|
146
|
+
export type OperationMode = STANDALONE_ENUM | CONSUMER_ENUM | CONSUMER_PARTIAL_ENUM
|
|
147
|
+
|
|
148
|
+
export type OPTIMIZED_ENUM = 0;
|
|
149
|
+
export type DEBUG_ENUM = 1;
|
|
150
|
+
export type ImpressionsMode = OPTIMIZED_ENUM | DEBUG_ENUM;
|
|
151
|
+
|
|
152
|
+
export type RefreshRates = {
|
|
153
|
+
sp: number, // splits
|
|
154
|
+
se: number, // mySegments
|
|
155
|
+
im: number, // impressions
|
|
156
|
+
ev: number, // events
|
|
157
|
+
te: number, // telemetry
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export type UrlOverrides = {
|
|
161
|
+
s: boolean, // sdkUrl
|
|
162
|
+
e: boolean, // events
|
|
163
|
+
a: boolean, // auth
|
|
164
|
+
st: boolean, // stream
|
|
165
|
+
t: boolean, // telemetry
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// 'metrics/config' JSON request body
|
|
169
|
+
export type TelemetryConfigStatsPayload = {
|
|
170
|
+
oM?: OperationMode, // operationMode
|
|
171
|
+
st: 'memory' | 'redis' | 'pluggable' | 'localstorage', // storage
|
|
172
|
+
sE: boolean, // streamingEnabled
|
|
173
|
+
rR: RefreshRates, // refreshRates
|
|
174
|
+
uO: UrlOverrides, // urlOverrides
|
|
175
|
+
iQ: number, // impressionsQueueSize
|
|
176
|
+
eQ: number, // eventsQueueSize
|
|
177
|
+
iM: ImpressionsMode, // impressionsMode
|
|
178
|
+
iL: boolean, // impressionsListenerEnabled
|
|
179
|
+
hP: boolean, // httpProxyDetected
|
|
180
|
+
aF: number, // activeFactories
|
|
181
|
+
rF: number, // redundantActiveFactories
|
|
182
|
+
tR: number, // timeUntilSDKReady
|
|
183
|
+
tC?: number, // timeUntilSDKReadyFromCache
|
|
184
|
+
nR: number, // SDKNotReadyUsage
|
|
185
|
+
t?: Array<string>, // tags
|
|
186
|
+
i?: Array<string>, // integrations
|
|
187
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ISyncManagerCS
|
|
1
|
+
import { ISyncManagerCS } from './types';
|
|
2
2
|
import { submitterManagerFactory } from './submitters/submitterManager';
|
|
3
3
|
import { IReadinessManager } from '../readiness/types';
|
|
4
4
|
import { IStorageSync } from '../storages/types';
|
|
@@ -7,6 +7,8 @@ import { IPollingManager, IPollingManagerCS } from './polling/types';
|
|
|
7
7
|
import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
|
|
8
8
|
import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
|
|
9
9
|
import { isConsentGranted } from '../consent';
|
|
10
|
+
import { POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
|
|
11
|
+
import { ISdkFactoryContextSync } from '../sdkFactory/types';
|
|
10
12
|
|
|
11
13
|
/**
|
|
12
14
|
* Online SyncManager factory.
|
|
@@ -17,16 +19,16 @@ import { isConsentGranted } from '../consent';
|
|
|
17
19
|
* @param pushManagerFactory optional to build a SyncManager with or without streaming support
|
|
18
20
|
*/
|
|
19
21
|
export function syncManagerOnlineFactory(
|
|
20
|
-
pollingManagerFactory?: (params:
|
|
21
|
-
pushManagerFactory?: (params:
|
|
22
|
-
): (params:
|
|
22
|
+
pollingManagerFactory?: (params: ISdkFactoryContextSync) => IPollingManager,
|
|
23
|
+
pushManagerFactory?: (params: ISdkFactoryContextSync, pollingManager: IPollingManager) => IPushManager | undefined,
|
|
24
|
+
): (params: ISdkFactoryContextSync) => ISyncManagerCS {
|
|
23
25
|
|
|
24
26
|
/**
|
|
25
27
|
* SyncManager factory for modular SDK
|
|
26
28
|
*/
|
|
27
|
-
return function (params:
|
|
29
|
+
return function (params: ISdkFactoryContextSync): ISyncManagerCS {
|
|
28
30
|
|
|
29
|
-
const { settings, settings: { log, streamingEnabled } } = params;
|
|
31
|
+
const { settings, settings: { log, streamingEnabled }, telemetryTracker } = params;
|
|
30
32
|
|
|
31
33
|
/** Polling Manager */
|
|
32
34
|
const pollingManager = pollingManagerFactory && pollingManagerFactory(params);
|
|
@@ -48,13 +50,17 @@ export function syncManagerOnlineFactory(
|
|
|
48
50
|
} else {
|
|
49
51
|
log.info(SYNC_START_POLLING);
|
|
50
52
|
pollingManager!.start();
|
|
53
|
+
telemetryTracker.streamingEvent(SYNC_MODE_UPDATE, POLLING);
|
|
51
54
|
}
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
function stopPollingAndSyncAll() {
|
|
55
58
|
log.info(SYNC_STOP_POLLING);
|
|
56
59
|
// if polling, stop
|
|
57
|
-
if (pollingManager!.isRunning())
|
|
60
|
+
if (pollingManager!.isRunning()) {
|
|
61
|
+
pollingManager!.stop();
|
|
62
|
+
telemetryTracker.streamingEvent(SYNC_MODE_UPDATE, STREAMING);
|
|
63
|
+
}
|
|
58
64
|
|
|
59
65
|
// fetch splits and segments. There is no need to catch this promise (it is always resolved)
|
|
60
66
|
pollingManager!.syncAll();
|
package/src/sync/types.ts
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import { IReadinessManager } from '../readiness/types';
|
|
2
|
-
import { IPlatform } from '../sdkFactory/types';
|
|
3
|
-
import { ISplitApi } from '../services/types';
|
|
4
2
|
import { IStorageSync } from '../storages/types';
|
|
5
|
-
import { ISettings } from '../types';
|
|
6
3
|
import { IPollingManager } from './polling/types';
|
|
7
4
|
import { IPushManager } from './streaming/types';
|
|
8
5
|
|
|
@@ -36,10 +33,6 @@ export interface ISyncTask<Input extends any[] = [], Output = any> extends ITask
|
|
|
36
33
|
isExecuting(): boolean
|
|
37
34
|
}
|
|
38
35
|
|
|
39
|
-
export interface ITimeTracker {
|
|
40
|
-
start(): () => void // start tracking time and return a function to call for stopping the tracking
|
|
41
|
-
}
|
|
42
|
-
|
|
43
36
|
/** SyncManager */
|
|
44
37
|
|
|
45
38
|
export interface ISyncManager extends ITask {
|
|
@@ -52,11 +45,3 @@ export interface ISyncManager extends ITask {
|
|
|
52
45
|
export interface ISyncManagerCS extends ISyncManager {
|
|
53
46
|
shared(matchingKey: string, readinessManager: IReadinessManager, storage: IStorageSync): ISyncManager | undefined
|
|
54
47
|
}
|
|
55
|
-
|
|
56
|
-
export interface ISyncManagerFactoryParams {
|
|
57
|
-
settings: ISettings,
|
|
58
|
-
readiness: IReadinessManager,
|
|
59
|
-
storage: IStorageSync,
|
|
60
|
-
splitApi: ISplitApi,
|
|
61
|
-
platform: IPlatform
|
|
62
|
-
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
2
|
import { thenable } from '../utils/promise/thenable';
|
|
3
|
-
import { IEventsCacheBase } from '../storages/types';
|
|
3
|
+
import { IEventsCacheBase, ITelemetryCacheAsync, ITelemetryCacheSync } from '../storages/types';
|
|
4
4
|
import { IEventsHandler, IEventTracker } from './types';
|
|
5
5
|
import { ISettings, SplitIO } from '../types';
|
|
6
6
|
import { EVENTS_TRACKER_SUCCESS, ERROR_EVENTS_TRACKER } from '../logger/constants';
|
|
7
|
-
import { CONSENT_DECLINED } from '../utils/constants';
|
|
7
|
+
import { CONSENT_DECLINED, DROPPED, QUEUED } from '../utils/constants';
|
|
8
8
|
import { isStorageSync } from './impressionObserver/utils';
|
|
9
9
|
|
|
10
10
|
/**
|
|
@@ -16,7 +16,8 @@ import { isStorageSync } from './impressionObserver/utils';
|
|
|
16
16
|
export function eventTrackerFactory(
|
|
17
17
|
settings: ISettings,
|
|
18
18
|
eventsCache: IEventsCacheBase,
|
|
19
|
-
integrationsManager?: IEventsHandler
|
|
19
|
+
integrationsManager?: IEventsHandler,
|
|
20
|
+
telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync
|
|
20
21
|
): IEventTracker {
|
|
21
22
|
|
|
22
23
|
const log = settings.log;
|
|
@@ -57,6 +58,9 @@ export function eventTrackerFactory(
|
|
|
57
58
|
if (thenable(tracked)) {
|
|
58
59
|
return tracked.then(queueEventsCallback.bind(null, eventData));
|
|
59
60
|
} else {
|
|
61
|
+
// Record when eventsCache is sync only (standalone mode)
|
|
62
|
+
// @TODO we are not dropping events on full queue yet, so `tracked` is always true ATM
|
|
63
|
+
if (telemetryCache) (telemetryCache as ITelemetryCacheSync).recordEventStats(tracked ? QUEUED : DROPPED, 1);
|
|
60
64
|
return queueEventsCallback(eventData, tracked);
|
|
61
65
|
}
|
|
62
66
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
2
|
import { thenable } from '../utils/promise/thenable';
|
|
3
3
|
import { truncateTimeFrame } from '../utils/time';
|
|
4
|
-
import { IImpressionCountsCacheSync, IImpressionsCacheBase } from '../storages/types';
|
|
4
|
+
import { IImpressionCountsCacheSync, IImpressionsCacheBase, ITelemetryCacheSync, ITelemetryCacheAsync } from '../storages/types';
|
|
5
5
|
import { IImpressionsHandler, IImpressionsTracker } from './types';
|
|
6
6
|
import { SplitIO, ImpressionDTO, ISettings } from '../types';
|
|
7
7
|
import { IImpressionObserver } from './impressionObserver/types';
|
|
8
8
|
import { IMPRESSIONS_TRACKER_SUCCESS, ERROR_IMPRESSIONS_TRACKER, ERROR_IMPRESSIONS_LISTENER } from '../logger/constants';
|
|
9
|
-
import { CONSENT_DECLINED } from '../utils/constants';
|
|
9
|
+
import { CONSENT_DECLINED, DEDUPED, QUEUED } from '../utils/constants';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Impressions tracker stores impressions in cache and pass them to the listener and integrations manager if provided.
|
|
@@ -25,7 +25,8 @@ export function impressionsTrackerFactory(
|
|
|
25
25
|
// if observer is provided, it implies `shouldAddPreviousTime` flag (i.e., if impressions previous time should be added or not)
|
|
26
26
|
observer?: IImpressionObserver,
|
|
27
27
|
// if countsCache is provided, it implies `isOptimized` flag (i.e., if impressions should be deduped or not)
|
|
28
|
-
countsCache?: IImpressionCountsCacheSync
|
|
28
|
+
countsCache?: IImpressionCountsCacheSync,
|
|
29
|
+
telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync
|
|
29
30
|
): IImpressionsTracker {
|
|
30
31
|
|
|
31
32
|
const { log, impressionListener, runtime: { ip, hostname }, version } = settings;
|
|
@@ -65,6 +66,13 @@ export function impressionsTrackerFactory(
|
|
|
65
66
|
}).catch(err => {
|
|
66
67
|
log.error(ERROR_IMPRESSIONS_TRACKER, [impressionsCount, err]);
|
|
67
68
|
});
|
|
69
|
+
} else {
|
|
70
|
+
// Record when impressionsCache is sync only (standalone mode)
|
|
71
|
+
// @TODO we are not dropping impressions on full queue yet, so DROPPED stats are not recorded
|
|
72
|
+
if (telemetryCache) {
|
|
73
|
+
(telemetryCache as ITelemetryCacheSync).recordImpressionStats(QUEUED, impressionsToStore.length);
|
|
74
|
+
(telemetryCache as ITelemetryCacheSync).recordImpressionStats(DEDUPED, impressions.length - impressionsToStore.length);
|
|
75
|
+
}
|
|
68
76
|
}
|
|
69
77
|
|
|
70
78
|
// @TODO next block might be handled by the integration manager. In that case, the metadata object doesn't need to be passed in the constructor
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ITelemetryCacheSync, ITelemetryCacheAsync } from '../storages/types';
|
|
2
|
+
import { EXCEPTION, SDK_NOT_READY } from '../utils/labels';
|
|
3
|
+
import { ITelemetryTracker } from './types';
|
|
4
|
+
import { timer } from '../utils/timeTracker/timer';
|
|
5
|
+
import { TOKEN_REFRESH, AUTH_REJECTION } from '../utils/constants';
|
|
6
|
+
|
|
7
|
+
export function telemetryTrackerFactory(
|
|
8
|
+
telemetryCache?: ITelemetryCacheSync | ITelemetryCacheAsync,
|
|
9
|
+
now?: () => number
|
|
10
|
+
): ITelemetryTracker {
|
|
11
|
+
|
|
12
|
+
if (telemetryCache && now) {
|
|
13
|
+
const startTime = timer(now);
|
|
14
|
+
|
|
15
|
+
return {
|
|
16
|
+
trackEval(method) {
|
|
17
|
+
const evalTime = timer(now);
|
|
18
|
+
|
|
19
|
+
return (label) => {
|
|
20
|
+
switch (label) {
|
|
21
|
+
case EXCEPTION:
|
|
22
|
+
telemetryCache.recordException(method);
|
|
23
|
+
return; // Don't track latency on exceptions
|
|
24
|
+
case SDK_NOT_READY: // @ts-ignore ITelemetryCacheAsync doesn't implement the method
|
|
25
|
+
if (telemetryCache.recordNonReadyUsage) telemetryCache.recordNonReadyUsage();
|
|
26
|
+
}
|
|
27
|
+
telemetryCache.recordLatency(method, evalTime());
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
trackHttp(operation) {
|
|
31
|
+
const httpTime = timer(now);
|
|
32
|
+
|
|
33
|
+
return (error) => {
|
|
34
|
+
(telemetryCache as ITelemetryCacheSync).recordHttpLatency(operation, httpTime());
|
|
35
|
+
if (error && error.statusCode) (telemetryCache as ITelemetryCacheSync).recordHttpError(operation, error.statusCode);
|
|
36
|
+
else (telemetryCache as ITelemetryCacheSync).recordSuccessfulSync(operation, now());
|
|
37
|
+
};
|
|
38
|
+
},
|
|
39
|
+
sessionLength() { // @ts-ignore ITelemetryCacheAsync doesn't implement the method
|
|
40
|
+
if (telemetryCache.recordSessionLength) telemetryCache.recordSessionLength(startTime());
|
|
41
|
+
},
|
|
42
|
+
streamingEvent(e, d) {
|
|
43
|
+
if (e === AUTH_REJECTION) {
|
|
44
|
+
(telemetryCache as ITelemetryCacheSync).recordAuthRejections();
|
|
45
|
+
} else {
|
|
46
|
+
(telemetryCache as ITelemetryCacheSync).recordStreamingEvents({
|
|
47
|
+
e, d, t: now()
|
|
48
|
+
});
|
|
49
|
+
if (e === TOKEN_REFRESH) (telemetryCache as ITelemetryCacheSync).recordTokenRefreshes();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
} else { // If there is not `telemetryCache` or `now` time tracker, return a no-op telemetry tracker
|
|
55
|
+
const noopTrack = () => () => { };
|
|
56
|
+
return {
|
|
57
|
+
trackEval: noopTrack,
|
|
58
|
+
trackHttp: noopTrack,
|
|
59
|
+
sessionLength: () => { },
|
|
60
|
+
streamingEvent: () => { },
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
}
|
package/src/trackers/types.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { SplitIO, ImpressionDTO } from '../types';
|
|
2
|
+
import { StreamingEventType, Method, OperationType } from '../sync/submitters/types';
|
|
2
3
|
import { IEventsCacheBase } from '../storages/types';
|
|
4
|
+
import { NetworkError } from '../services/types';
|
|
3
5
|
|
|
4
6
|
/** Events tracker */
|
|
5
7
|
|
|
@@ -18,3 +20,25 @@ export interface IImpressionsHandler {
|
|
|
18
20
|
export interface IImpressionsTracker {
|
|
19
21
|
track(impressions: ImpressionDTO[], attributes?: SplitIO.Attributes): void
|
|
20
22
|
}
|
|
23
|
+
|
|
24
|
+
/** Telemetry tracker */
|
|
25
|
+
export type AUTH_REJECTION = 80;
|
|
26
|
+
|
|
27
|
+
export interface ITelemetryTracker {
|
|
28
|
+
/**
|
|
29
|
+
* Creates a telemetry evaluator tracker, to record Latencies, Exceptions and NonReadyUsage of client operations (getTreatments and track method calls)
|
|
30
|
+
*/
|
|
31
|
+
trackEval(method: Method): (label?: string) => void
|
|
32
|
+
/**
|
|
33
|
+
* Creates a telemetry runtime tracker, to record Latencies and Exceptions of HTTP requests
|
|
34
|
+
*/
|
|
35
|
+
trackHttp(method: OperationType): (error?: NetworkError) => void
|
|
36
|
+
/**
|
|
37
|
+
* Records session length
|
|
38
|
+
*/
|
|
39
|
+
sessionLength(): void
|
|
40
|
+
/**
|
|
41
|
+
* Records streaming event
|
|
42
|
+
*/
|
|
43
|
+
streamingEvent(e: StreamingEventType | AUTH_REJECTION, d?: number): void
|
|
44
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ISplitFiltersValidation } from './dtos/types';
|
|
2
2
|
import { IIntegration, IIntegrationFactoryParams } from './integrations/types';
|
|
3
3
|
import { ILogger } from './logger/types';
|
|
4
|
+
import { ISdkFactoryContext } from './sdkFactory/types';
|
|
4
5
|
/* eslint-disable no-use-before-define */
|
|
5
6
|
|
|
6
7
|
import { IStorageFactoryParams, IStorageSync, IStorageAsync, IStorageSyncFactory, IStorageAsyncFactory } from './storages/types';
|
|
7
|
-
import {
|
|
8
|
+
import { ISyncManagerCS } from './sync/types';
|
|
8
9
|
|
|
9
10
|
/**
|
|
10
11
|
* Reduced version of NodeJS.EventEmitter interface with the minimal methods used by the SDK
|
|
@@ -79,7 +80,11 @@ export interface ISettings {
|
|
|
79
80
|
featuresRefreshRate: number,
|
|
80
81
|
impressionsRefreshRate: number,
|
|
81
82
|
impressionsQueueSize: number,
|
|
82
|
-
|
|
83
|
+
/**
|
|
84
|
+
* @deprecated
|
|
85
|
+
*/
|
|
86
|
+
metricsRefreshRate?: number,
|
|
87
|
+
telemetryRefreshRate: number,
|
|
83
88
|
segmentsRefreshRate: number,
|
|
84
89
|
offlineRefreshRate: number,
|
|
85
90
|
eventsPushRate: number,
|
|
@@ -93,12 +98,16 @@ export interface ISettings {
|
|
|
93
98
|
eventsFirstPushWindow: number
|
|
94
99
|
},
|
|
95
100
|
readonly storage: IStorageSyncFactory | IStorageAsyncFactory,
|
|
96
|
-
readonly integrations
|
|
101
|
+
readonly integrations: Array<{
|
|
102
|
+
readonly type: string,
|
|
103
|
+
(params: IIntegrationFactoryParams): IIntegration | void
|
|
104
|
+
}>,
|
|
97
105
|
readonly urls: {
|
|
98
106
|
events: string,
|
|
99
107
|
sdk: string,
|
|
100
108
|
auth: string,
|
|
101
|
-
streaming: string
|
|
109
|
+
streaming: string,
|
|
110
|
+
telemetry: string
|
|
102
111
|
},
|
|
103
112
|
readonly debug: boolean | LogLevel | ILogger,
|
|
104
113
|
readonly version: string,
|
|
@@ -273,8 +282,15 @@ interface INodeBasicSettings extends ISharedSettings {
|
|
|
273
282
|
* The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
|
|
274
283
|
* @property {number} metricsRefreshRate
|
|
275
284
|
* @default 120
|
|
285
|
+
* @deprecated This parameter is ignored now.
|
|
276
286
|
*/
|
|
277
287
|
metricsRefreshRate?: number,
|
|
288
|
+
/**
|
|
289
|
+
* The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
|
|
290
|
+
* @property {number} telemetryRefreshRate
|
|
291
|
+
* @default 3600
|
|
292
|
+
*/
|
|
293
|
+
telemetryRefreshRate?: number,
|
|
278
294
|
/**
|
|
279
295
|
* The SDK polls Split servers for changes to segment definitions. This parameter controls this polling period in seconds.
|
|
280
296
|
* @property {number} segmentsRefreshRate
|
|
@@ -607,7 +623,7 @@ export namespace SplitIO {
|
|
|
607
623
|
*/
|
|
608
624
|
export type LocalhostFactory = {
|
|
609
625
|
type: 'LocalhostFromObject' | 'LocalhostFromFile'
|
|
610
|
-
(params:
|
|
626
|
+
(params: ISdkFactoryContext): ISyncManagerCS
|
|
611
627
|
}
|
|
612
628
|
/**
|
|
613
629
|
* Impression listener interface. This is the interface that needs to be implemented
|
|
@@ -664,7 +680,13 @@ export namespace SplitIO {
|
|
|
664
680
|
* @property {string} streaming
|
|
665
681
|
* @default 'https://streaming.split.io'
|
|
666
682
|
*/
|
|
667
|
-
streaming?: string
|
|
683
|
+
streaming?: string,
|
|
684
|
+
/**
|
|
685
|
+
* String property to override the base URL where the SDK will post telemetry data.
|
|
686
|
+
* @property {string} telemetry
|
|
687
|
+
* @default 'https://telemetry.split.io/api'
|
|
688
|
+
*/
|
|
689
|
+
telemetry?: string
|
|
668
690
|
};
|
|
669
691
|
/**
|
|
670
692
|
* SplitFilter type.
|
|
@@ -794,8 +816,15 @@ export namespace SplitIO {
|
|
|
794
816
|
* The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
|
|
795
817
|
* @property {number} metricsRefreshRate
|
|
796
818
|
* @default 120
|
|
819
|
+
* @deprecated This parameter is ignored now.
|
|
797
820
|
*/
|
|
798
821
|
metricsRefreshRate?: number,
|
|
822
|
+
/**
|
|
823
|
+
* The SDK sends diagnostic metrics to Split servers. This parameters controls this metric flush period in seconds.
|
|
824
|
+
* @property {number} telemetryRefreshRate
|
|
825
|
+
* @default 3600
|
|
826
|
+
*/
|
|
827
|
+
telemetryRefreshRate?: number,
|
|
799
828
|
/**
|
|
800
829
|
* The SDK polls Split servers for changes to segment definitions. This parameter controls this polling period in seconds.
|
|
801
830
|
* @property {number} segmentsRefreshRate
|
|
@@ -37,3 +37,48 @@ export const STORAGE_PLUGGABLE: StorageType = 'PLUGGABLE';
|
|
|
37
37
|
export const CONSENT_GRANTED = 'GRANTED'; // The user has granted consent for tracking events and impressions
|
|
38
38
|
export const CONSENT_DECLINED = 'DECLINED'; // The user has declined consent for tracking events and impressions
|
|
39
39
|
export const CONSENT_UNKNOWN = 'UNKNOWN'; // The user has neither granted nor declined consent for tracking events and impressions
|
|
40
|
+
|
|
41
|
+
// Telemetry
|
|
42
|
+
export const QUEUED = 0;
|
|
43
|
+
export const DROPPED = 1;
|
|
44
|
+
export const DEDUPED = 2;
|
|
45
|
+
|
|
46
|
+
export const STANDALONE_ENUM = 0;
|
|
47
|
+
export const CONSUMER_ENUM = 1;
|
|
48
|
+
export const CONSUMER_PARTIAL_ENUM = 2;
|
|
49
|
+
|
|
50
|
+
export const OPTIMIZED_ENUM = 0;
|
|
51
|
+
export const DEBUG_ENUM = 1;
|
|
52
|
+
|
|
53
|
+
export const SPLITS = 'sp';
|
|
54
|
+
export const IMPRESSIONS = 'im';
|
|
55
|
+
export const IMPRESSIONS_COUNT = 'ic';
|
|
56
|
+
export const EVENTS = 'ev';
|
|
57
|
+
export const TELEMETRY = 'te';
|
|
58
|
+
export const TOKEN = 'to';
|
|
59
|
+
export const SEGMENT = 'se';
|
|
60
|
+
export const MY_SEGMENT = 'ms';
|
|
61
|
+
|
|
62
|
+
export const TREATMENT = 't';
|
|
63
|
+
export const TREATMENTS = 'ts';
|
|
64
|
+
export const TREATMENT_WITH_CONFIG = 'tc';
|
|
65
|
+
export const TREATMENTS_WITH_CONFIG = 'tcs';
|
|
66
|
+
export const TRACK = 'tr';
|
|
67
|
+
|
|
68
|
+
export const CONNECTION_ESTABLISHED = 0;
|
|
69
|
+
export const OCCUPANCY_PRI = 10;
|
|
70
|
+
export const OCCUPANCY_SEC = 20;
|
|
71
|
+
export const STREAMING_STATUS = 30;
|
|
72
|
+
export const SSE_CONNECTION_ERROR = 40;
|
|
73
|
+
export const TOKEN_REFRESH = 50;
|
|
74
|
+
export const ABLY_ERROR = 60;
|
|
75
|
+
export const SYNC_MODE_UPDATE = 70;
|
|
76
|
+
export const AUTH_REJECTION = 80;
|
|
77
|
+
|
|
78
|
+
export const STREAMING = 0;
|
|
79
|
+
export const POLLING = 1;
|
|
80
|
+
export const REQUESTED = 0;
|
|
81
|
+
export const NON_REQUESTED = 1;
|
|
82
|
+
export const DISABLED = 0;
|
|
83
|
+
export const ENABLED = 1;
|
|
84
|
+
export const PAUSED = 2;
|
|
@@ -21,7 +21,8 @@ export function validateApiKey(log: ILogger, maybeApiKey: any): string | false {
|
|
|
21
21
|
return apiKey;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
// Exported for telemetry
|
|
25
|
+
export const usedKeysMap: Record<string, number> = {};
|
|
25
26
|
|
|
26
27
|
/** validates the given api key and also warns if it is in use */
|
|
27
28
|
export function validateAndTrackApiKey(log: ILogger, maybeApiKey: any): string | false {
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import { merge } from '../lang';
|
|
2
2
|
import { mode } from './mode';
|
|
3
3
|
import { validateSplitFilters } from './splitFilters';
|
|
4
|
-
import { STANDALONE_MODE, OPTIMIZED, LOCALHOST_MODE } from '../constants';
|
|
4
|
+
import { STANDALONE_MODE, OPTIMIZED, LOCALHOST_MODE, DEBUG } from '../constants';
|
|
5
5
|
import { validImpressionsMode } from './impressionsMode';
|
|
6
6
|
import { ISettingsValidationParams } from './types';
|
|
7
7
|
import { ISettings } from '../../types';
|
|
8
8
|
import { validateKey } from '../inputValidation/key';
|
|
9
9
|
import { validateTrafficType } from '../inputValidation/trafficType';
|
|
10
|
+
import { ERROR_MIN_CONFIG_PARAM } from '../../logger/constants';
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
// Exported for telemetry
|
|
13
|
+
export const base = {
|
|
12
14
|
// Define which kind of object you want to retrieve from SplitFactory
|
|
13
15
|
mode: STANDALONE_MODE,
|
|
14
16
|
|
|
@@ -30,10 +32,10 @@ const base = {
|
|
|
30
32
|
featuresRefreshRate: 30,
|
|
31
33
|
// fetch segments updates each 60 sec
|
|
32
34
|
segmentsRefreshRate: 60,
|
|
33
|
-
// publish
|
|
34
|
-
|
|
35
|
-
// publish evaluations each
|
|
36
|
-
impressionsRefreshRate:
|
|
35
|
+
// publish telemetry stats each 3600 secs (1 hour)
|
|
36
|
+
telemetryRefreshRate: 3600,
|
|
37
|
+
// publish evaluations each 300 sec (default value for OPTIMIZED impressions mode)
|
|
38
|
+
impressionsRefreshRate: 300,
|
|
37
39
|
// fetch offline changes each 15 sec
|
|
38
40
|
offlineRefreshRate: 15,
|
|
39
41
|
// publish events every 60 seconds after the first flush
|
|
@@ -55,6 +57,8 @@ const base = {
|
|
|
55
57
|
auth: 'https://auth.split.io/api',
|
|
56
58
|
// Streaming Server
|
|
57
59
|
streaming: 'https://streaming.split.io',
|
|
60
|
+
// Telemetry Server
|
|
61
|
+
telemetry: 'https://telemetry.split.io/api',
|
|
58
62
|
},
|
|
59
63
|
|
|
60
64
|
// Defines which kind of storage we should instanciate.
|
|
@@ -109,14 +113,37 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
|
|
|
109
113
|
const log = logger(withDefaults); // @ts-ignore, modify readonly prop
|
|
110
114
|
withDefaults.log = log;
|
|
111
115
|
|
|
116
|
+
// ensure a valid impressionsMode
|
|
117
|
+
withDefaults.sync.impressionsMode = validImpressionsMode(log, withDefaults.sync.impressionsMode);
|
|
118
|
+
|
|
119
|
+
function validateMinValue(paramName: string, actualValue: number, minValue: number) {
|
|
120
|
+
if (actualValue >= minValue) return actualValue;
|
|
121
|
+
// actualValue is not a number or is lower than minValue
|
|
122
|
+
log.error(ERROR_MIN_CONFIG_PARAM, [paramName, minValue]);
|
|
123
|
+
return minValue;
|
|
124
|
+
}
|
|
125
|
+
|
|
112
126
|
// Scheduler periods
|
|
113
127
|
const { scheduler, startup } = withDefaults;
|
|
114
128
|
scheduler.featuresRefreshRate = fromSecondsToMillis(scheduler.featuresRefreshRate);
|
|
115
129
|
scheduler.segmentsRefreshRate = fromSecondsToMillis(scheduler.segmentsRefreshRate);
|
|
116
|
-
scheduler.metricsRefreshRate = fromSecondsToMillis(scheduler.metricsRefreshRate);
|
|
117
|
-
scheduler.impressionsRefreshRate = fromSecondsToMillis(scheduler.impressionsRefreshRate);
|
|
118
130
|
scheduler.offlineRefreshRate = fromSecondsToMillis(scheduler.offlineRefreshRate);
|
|
119
131
|
scheduler.eventsPushRate = fromSecondsToMillis(scheduler.eventsPushRate);
|
|
132
|
+
scheduler.telemetryRefreshRate = fromSecondsToMillis(validateMinValue('telemetryRefreshRate', scheduler.telemetryRefreshRate, 60));
|
|
133
|
+
|
|
134
|
+
if (scheduler.impressionsRefreshRate !== base.scheduler.impressionsRefreshRate) {
|
|
135
|
+
// Validate impressionsRefreshRate defined by user
|
|
136
|
+
scheduler.impressionsRefreshRate = validateMinValue('impressionsRefreshRate', scheduler.impressionsRefreshRate,
|
|
137
|
+
withDefaults.sync.impressionsMode === DEBUG ? 1 : 60 // Min is 1 sec for DEBUG and 60 secs for OPTIMIZED
|
|
138
|
+
);
|
|
139
|
+
} else {
|
|
140
|
+
// Default impressionsRefreshRate for DEBUG mode is 60 secs
|
|
141
|
+
if (withDefaults.sync.impressionsMode === DEBUG) scheduler.impressionsRefreshRate = 60;
|
|
142
|
+
}
|
|
143
|
+
scheduler.impressionsRefreshRate = fromSecondsToMillis(scheduler.impressionsRefreshRate);
|
|
144
|
+
|
|
145
|
+
// Log deprecation for old telemetry param
|
|
146
|
+
if (scheduler.metricsRefreshRate) log.warn('`metricsRefreshRate` will be deprecated soon. For configuring telemetry rates, update `telemetryRefreshRate` value in configs');
|
|
120
147
|
|
|
121
148
|
// Startup periods
|
|
122
149
|
startup.requestTimeoutBeforeReady = fromSecondsToMillis(startup.requestTimeoutBeforeReady);
|
|
@@ -176,9 +203,6 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
|
|
|
176
203
|
withDefaults.sync.splitFilters = splitFiltersValidation.validFilters;
|
|
177
204
|
withDefaults.sync.__splitFiltersValidation = splitFiltersValidation;
|
|
178
205
|
|
|
179
|
-
// ensure a valid impressionsMode
|
|
180
|
-
withDefaults.sync.impressionsMode = validImpressionsMode(log, withDefaults.sync.impressionsMode);
|
|
181
|
-
|
|
182
206
|
// ensure a valid user consent value
|
|
183
207
|
// @ts-ignore, modify readonly prop
|
|
184
208
|
withDefaults.userConsent = consent(withDefaults);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ISettings } from '../../types';
|
|
2
2
|
|
|
3
|
+
const telemetryEndpointMatcher = /^\/v1\/metrics\/(config|usage)/;
|
|
3
4
|
const eventsEndpointMatcher = /^\/(testImpressions|metrics|events)/;
|
|
4
5
|
const authEndpointMatcher = /^\/v2\/auth/;
|
|
5
6
|
const streamingEndpointMatcher = /^\/(sse|event-stream)/;
|
|
@@ -13,6 +14,9 @@ const streamingEndpointMatcher = /^\/(sse|event-stream)/;
|
|
|
13
14
|
* @return complete url
|
|
14
15
|
*/
|
|
15
16
|
export function url(settings: ISettings, target: string) {
|
|
17
|
+
if (telemetryEndpointMatcher.test(target)) {
|
|
18
|
+
return `${settings.urls.telemetry}${target}`;
|
|
19
|
+
}
|
|
16
20
|
if (eventsEndpointMatcher.test(target)) {
|
|
17
21
|
return `${settings.urls.events}${target}`;
|
|
18
22
|
}
|
|
@@ -148,7 +148,7 @@ export const TrackerAPI = {
|
|
|
148
148
|
* @param {Promise} promise - (optional) The promise we are tracking.
|
|
149
149
|
* @return {Function | Promise} The stop function for this specific task or the promise received with the callbacks registered.
|
|
150
150
|
*/
|
|
151
|
-
start(log: ILogger, task: string, collectors?: Record<string, MetricsCollector>, promise?: Promise<IResponse>, now
|
|
151
|
+
start(log: ILogger, task: string, collectors?: Record<string, MetricsCollector>, promise?: Promise<IResponse>, now: () => number = Date.now): Promise<IResponse> | (() => number) {
|
|
152
152
|
const taskUniqueId = uniqueId();
|
|
153
153
|
const taskCollector = getCollectorForTask(task, collectors);
|
|
154
154
|
let result;
|