genesys-cloud-client-logger
Advanced tools
Comparing version 4.1.2-develop.8 to 4.2.0-PCM-1992.2
{ | ||
"name": "genesys-cloud-client-logger", | ||
"version": "develop", | ||
"version": "PCM-1992", | ||
"ecosystem": "pc", | ||
@@ -20,16 +20,16 @@ "team": "Genesys Client Media (WebRTC)", | ||
{ | ||
"file": "/v4.1.2/genesys-cloud-client-logger.min.js.map" | ||
"file": "/v4.2.0/genesys-cloud-client-logger.min.js.map" | ||
}, | ||
{ | ||
"file": "/v4.1.2/genesys-cloud-client-logger.min.js" | ||
"file": "/v4.2.0/genesys-cloud-client-logger.min.js" | ||
}, | ||
{ | ||
"file": "/v4.1.2/genesys-cloud-client-logger.js.map" | ||
"file": "/v4.2.0/genesys-cloud-client-logger.js.map" | ||
}, | ||
{ | ||
"file": "/v4.1.2/genesys-cloud-client-logger.js" | ||
"file": "/v4.2.0/genesys-cloud-client-logger.js" | ||
} | ||
], | ||
"build": "8", | ||
"buildDate": "2022-09-14T14:17:29.318451Z" | ||
"build": "2", | ||
"buildDate": "2022-09-14T14:26:07.180402Z" | ||
} |
@@ -175,4 +175,6 @@ export interface ILoggerConfig { | ||
} | ||
export interface ISendLogRequest { | ||
export interface ISendLogRequest extends ILogRequest { | ||
accessToken: string; | ||
} | ||
export interface ILogRequest { | ||
app: { | ||
@@ -179,0 +181,0 @@ appId: string; |
@@ -1,2 +0,2 @@ | ||
import { IDeferred, ISendLogRequest } from './interfaces'; | ||
import { IDeferred, ILogRequest, ISendLogRequest } from './interfaces'; | ||
export interface IQueueItem { | ||
@@ -11,11 +11,17 @@ deferred: IDeferred; | ||
sendQueue: IQueueItem[]; | ||
private hasPendingRequest; | ||
private pendingRequest?; | ||
constructor(url: string, debugMode?: boolean); | ||
postLogsToEndpoint(requestParams: ISendLogRequest): Promise<any>; | ||
postLogsToEndpointInstantly(requestParams: ISendLogRequest): Promise<any>; | ||
postLogsToEndpointInstantly(requestParams: ISendLogRequest, opts?: { | ||
saveOnFailure: boolean; | ||
}): Promise<any>; | ||
saveRequestForLater(request: ISendLogRequest): void; | ||
getSavedRequests(): ILogRequest[] | undefined; | ||
sendEntireQueue(): Promise<any>[]; | ||
resetSendQueue(): void; | ||
private sendNextQueuedLogToServer; | ||
private handleBackoffError; | ||
private backoffFn; | ||
private sendPostRequest; | ||
private debug; | ||
} |
@@ -13,2 +13,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { getDeferred, deepClone } from './utils'; | ||
const SAVED_REQUESTS_KEY = 'gc_logger_requests'; | ||
const STATUS_CODES_TO_RETRY_IMMEDIATELY = [ | ||
408, | ||
429, | ||
500, | ||
503, | ||
504 | ||
]; | ||
const STATUS_CODES_TO_RETRY_LATER = [ | ||
401 | ||
]; | ||
const logUploaderMap = new Map(); | ||
@@ -29,3 +40,2 @@ export const getOrCreateLogUploader = (url, debugMode = false) => { | ||
this.sendQueue = []; | ||
this.hasPendingRequest = false; | ||
} | ||
@@ -39,10 +49,41 @@ postLogsToEndpoint(requestParams) { | ||
updatedSendQueue: this.sendQueue.map(i => i.requestParams), | ||
hasPendingRequest: this.hasPendingRequest | ||
hasPendingRequest: !!this.pendingRequest | ||
}); | ||
return deferred.promise; | ||
} | ||
postLogsToEndpointInstantly(requestParams) { | ||
this.debug('sending request instantly', { requestParams, sendQueue: this.sendQueue.map(i => i.requestParams) }); | ||
return this.sendPostRequest(requestParams); | ||
postLogsToEndpointInstantly(requestParams, opts) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
this.debug('sending request instantly', { requestParams, sendQueue: this.sendQueue.map(i => i.requestParams) }); | ||
if (!navigator.onLine) { | ||
return this.saveRequestForLater(requestParams); | ||
} | ||
try { | ||
yield this.sendPostRequest(requestParams); | ||
} | ||
catch (e) { | ||
if (opts === null || opts === void 0 ? void 0 : opts.saveOnFailure) { | ||
this.saveRequestForLater(requestParams); | ||
} | ||
throw e; | ||
} | ||
}); | ||
} | ||
saveRequestForLater(request) { | ||
const savedRequests = this.getSavedRequests() || []; | ||
const sanitizedRequest = Object.assign({}, request); | ||
delete sanitizedRequest.accessToken; | ||
savedRequests.push(sanitizedRequest); | ||
window.localStorage.setItem(SAVED_REQUESTS_KEY, JSON.stringify(savedRequests)); | ||
} | ||
getSavedRequests() { | ||
const jsonStr = window.localStorage.getItem(SAVED_REQUESTS_KEY); | ||
if (jsonStr) { | ||
try { | ||
return JSON.parse(jsonStr); | ||
} | ||
catch (e) { | ||
console.error('Failed to parse saved messages, ignoring', { savedMessagesStr: jsonStr }); | ||
} | ||
} | ||
} | ||
sendEntireQueue() { | ||
@@ -56,3 +97,3 @@ this.debug('sending all queued requests instantly to clear out sendQueue', { | ||
while (queueItem = this.sendQueue.shift()) { | ||
promises.push(this.postLogsToEndpointInstantly(queueItem.requestParams)); | ||
promises.push(this.postLogsToEndpointInstantly(queueItem.requestParams, { saveOnFailure: true })); | ||
} | ||
@@ -68,5 +109,5 @@ /* don't want this to be async because this is called from the window 'unload' event */ | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (this.hasPendingRequest || this.sendQueue.length === 0) { | ||
if (this.pendingRequest || this.sendQueue.length === 0) { | ||
this.debug('sendNextQueuedLogToServer() but not sending request', { | ||
hasPendingRequest: this.hasPendingRequest, | ||
hasPendingRequest: !!this.pendingRequest, | ||
sendQueueLength: this.sendQueue.length | ||
@@ -83,11 +124,16 @@ }); | ||
/* reset state and send the next item in the queue */ | ||
this.hasPendingRequest = false; | ||
this.pendingRequest = undefined; | ||
this.sendNextQueuedLogToServer(); | ||
}); | ||
this.hasPendingRequest = true; | ||
this.pendingRequest = queueItem; | ||
this.debug('sending logs to server', { queueItem: queueItem.requestParams, sendQueue: this.sendQueue.map(i => i.requestParams) }); | ||
// return backOff(this.sendPostRequest.bind(this, queueItem.requestParams), { | ||
return backOff(() => this.sendPostRequest(queueItem.requestParams), { | ||
return backOff(() => this.backoffFn(queueItem.requestParams), { | ||
retry: (err) => { | ||
return !!(err && err.status === 429); | ||
var _a; | ||
const status = (_a = err.response) === null || _a === void 0 ? void 0 : _a.status; | ||
const code = err.code; | ||
// we get a "ERR_NETWORK" in the case of a network blip failure. if this happens, we will want to try again. | ||
// this is akin to not getting a response at all | ||
return (status && STATUS_CODES_TO_RETRY_IMMEDIATELY.includes(status)) || code === "ERR_NETWORK"; | ||
}, | ||
@@ -103,8 +149,36 @@ numOfAttempts: 10, | ||
}) | ||
.catch((error) => { | ||
this.debug('ERROR sending logs to server', { requestParams: queueItem.requestParams, error }); | ||
return queueItem.deferred.reject(error); | ||
}); | ||
.catch(this.handleBackoffError.bind(this, queueItem)); | ||
}); | ||
} | ||
handleBackoffError(queueItem, error) { | ||
var _a; | ||
// there are certain errors we know we don't want to try again, and certain errors/responses that *may* work in the future. | ||
const status = (_a = error.response) === null || _a === void 0 ? void 0 : _a.status; | ||
const isRetriableStatus = status && STATUS_CODES_TO_RETRY_IMMEDIATELY.includes(status) || STATUS_CODES_TO_RETRY_LATER.includes(status); | ||
if (isRetriableStatus || error.code === "ERR_NETWORK") { | ||
this.debug('Failed to sends logs to the server, moving request to the end of the queue', { requestParams: queueItem.requestParams, error }); | ||
this.saveRequestForLater(queueItem.requestParams); | ||
} | ||
else { | ||
this.debug('ERROR sending logs to server', { requestParams: queueItem.requestParams, error }); | ||
} | ||
queueItem.deferred.reject(Object.assign(Object.assign({}, error), { id: "rejectionSpot1" })); | ||
} | ||
backoffFn(requestParams) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const accessToken = requestParams.accessToken; | ||
const response = yield this.sendPostRequest(requestParams); | ||
// add any saved queue items to the queue using the access token | ||
const savedRequests = this.getSavedRequests(); | ||
if (savedRequests) { | ||
window.localStorage.removeItem(SAVED_REQUESTS_KEY); | ||
savedRequests.map(request => { | ||
const reqWithToken = Object.assign({ accessToken }, request); | ||
// this adds it to the send queue, it doesn't send it immediately | ||
this.postLogsToEndpoint(reqWithToken); | ||
}); | ||
} | ||
return response; | ||
}); | ||
} | ||
sendPostRequest(requestParams) { | ||
@@ -111,0 +185,0 @@ this.debug('issuing POST request', { requestParams }); |
@@ -177,2 +177,2 @@ import { EventEmitter } from 'events'; | ||
/* eslint-disable @typescript-eslint/naming-convention */ | ||
Logger.VERSION = '4.1.2'; | ||
Logger.VERSION = '4.2.0'; |
@@ -116,3 +116,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
/* this will send any items in the buffer still */ | ||
this.logBuffer.map((item) => this.logUploader.postLogsToEndpointInstantly(this.convertToRequestParams(item.traces.reverse())))); | ||
this.logBuffer.map((item) => this.logUploader.postLogsToEndpointInstantly(this.convertToRequestParams(item.traces.reverse()), { saveOnFailure: true }))); | ||
} | ||
@@ -119,0 +119,0 @@ sendLogsToServer(immediate = false) { |
{ | ||
"name": "genesys-cloud-client-logger", | ||
"version": "develop", | ||
"version": "PCM-1992", | ||
"indexFiles": [ | ||
@@ -18,14 +18,14 @@ { | ||
{ | ||
"file": "/v4.1.2/genesys-cloud-client-logger.min.js.map" | ||
"file": "/v4.2.0/genesys-cloud-client-logger.min.js.map" | ||
}, | ||
{ | ||
"file": "/v4.1.2/genesys-cloud-client-logger.min.js" | ||
"file": "/v4.2.0/genesys-cloud-client-logger.min.js" | ||
}, | ||
{ | ||
"file": "/v4.1.2/genesys-cloud-client-logger.js.map" | ||
"file": "/v4.2.0/genesys-cloud-client-logger.js.map" | ||
}, | ||
{ | ||
"file": "/v4.1.2/genesys-cloud-client-logger.js" | ||
"file": "/v4.2.0/genesys-cloud-client-logger.js" | ||
} | ||
] | ||
} |
@@ -175,4 +175,6 @@ export interface ILoggerConfig { | ||
} | ||
export interface ISendLogRequest { | ||
export interface ISendLogRequest extends ILogRequest { | ||
accessToken: string; | ||
} | ||
export interface ILogRequest { | ||
app: { | ||
@@ -179,0 +181,0 @@ appId: string; |
@@ -1,2 +0,2 @@ | ||
import { IDeferred, ISendLogRequest } from './interfaces'; | ||
import { IDeferred, ILogRequest, ISendLogRequest } from './interfaces'; | ||
export interface IQueueItem { | ||
@@ -11,11 +11,17 @@ deferred: IDeferred; | ||
sendQueue: IQueueItem[]; | ||
private hasPendingRequest; | ||
private pendingRequest?; | ||
constructor(url: string, debugMode?: boolean); | ||
postLogsToEndpoint(requestParams: ISendLogRequest): Promise<any>; | ||
postLogsToEndpointInstantly(requestParams: ISendLogRequest): Promise<any>; | ||
postLogsToEndpointInstantly(requestParams: ISendLogRequest, opts?: { | ||
saveOnFailure: boolean; | ||
}): Promise<any>; | ||
saveRequestForLater(request: ISendLogRequest): void; | ||
getSavedRequests(): ILogRequest[] | undefined; | ||
sendEntireQueue(): Promise<any>[]; | ||
resetSendQueue(): void; | ||
private sendNextQueuedLogToServer; | ||
private handleBackoffError; | ||
private backoffFn; | ||
private sendPostRequest; | ||
private debug; | ||
} |
@@ -57,2 +57,13 @@ "use strict"; | ||
var utils_1 = require("./utils"); | ||
var SAVED_REQUESTS_KEY = 'gc_logger_requests'; | ||
var STATUS_CODES_TO_RETRY_IMMEDIATELY = [ | ||
408, | ||
429, | ||
500, | ||
503, | ||
504 | ||
]; | ||
var STATUS_CODES_TO_RETRY_LATER = [ | ||
401 | ||
]; | ||
var logUploaderMap = new Map(); | ||
@@ -76,3 +87,2 @@ var getOrCreateLogUploader = function (url, debugMode) { | ||
this.sendQueue = []; | ||
this.hasPendingRequest = false; | ||
} | ||
@@ -86,10 +96,52 @@ LogUploader.prototype.postLogsToEndpoint = function (requestParams) { | ||
updatedSendQueue: this.sendQueue.map(function (i) { return i.requestParams; }), | ||
hasPendingRequest: this.hasPendingRequest | ||
hasPendingRequest: !!this.pendingRequest | ||
}); | ||
return deferred.promise; | ||
}; | ||
LogUploader.prototype.postLogsToEndpointInstantly = function (requestParams) { | ||
this.debug('sending request instantly', { requestParams: requestParams, sendQueue: this.sendQueue.map(function (i) { return i.requestParams; }) }); | ||
return this.sendPostRequest(requestParams); | ||
LogUploader.prototype.postLogsToEndpointInstantly = function (requestParams, opts) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var e_1; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
this.debug('sending request instantly', { requestParams: requestParams, sendQueue: this.sendQueue.map(function (i) { return i.requestParams; }) }); | ||
if (!navigator.onLine) { | ||
return [2 /*return*/, this.saveRequestForLater(requestParams)]; | ||
} | ||
_a.label = 1; | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.sendPostRequest(requestParams)]; | ||
case 2: | ||
_a.sent(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
e_1 = _a.sent(); | ||
if (opts === null || opts === void 0 ? void 0 : opts.saveOnFailure) { | ||
this.saveRequestForLater(requestParams); | ||
} | ||
throw e_1; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
}); | ||
}; | ||
LogUploader.prototype.saveRequestForLater = function (request) { | ||
var savedRequests = this.getSavedRequests() || []; | ||
var sanitizedRequest = __assign({}, request); | ||
delete sanitizedRequest.accessToken; | ||
savedRequests.push(sanitizedRequest); | ||
window.localStorage.setItem(SAVED_REQUESTS_KEY, JSON.stringify(savedRequests)); | ||
}; | ||
LogUploader.prototype.getSavedRequests = function () { | ||
var jsonStr = window.localStorage.getItem(SAVED_REQUESTS_KEY); | ||
if (jsonStr) { | ||
try { | ||
return JSON.parse(jsonStr); | ||
} | ||
catch (e) { | ||
console.error('Failed to parse saved messages, ignoring', { savedMessagesStr: jsonStr }); | ||
} | ||
} | ||
}; | ||
LogUploader.prototype.sendEntireQueue = function () { | ||
@@ -103,3 +155,3 @@ this.debug('sending all queued requests instantly to clear out sendQueue', { | ||
while (queueItem = this.sendQueue.shift()) { | ||
promises.push(this.postLogsToEndpointInstantly(queueItem.requestParams)); | ||
promises.push(this.postLogsToEndpointInstantly(queueItem.requestParams, { saveOnFailure: true })); | ||
} | ||
@@ -118,5 +170,5 @@ /* don't want this to be async because this is called from the window 'unload' event */ | ||
return __generator(this, function (_a) { | ||
if (this.hasPendingRequest || this.sendQueue.length === 0) { | ||
if (this.pendingRequest || this.sendQueue.length === 0) { | ||
this.debug('sendNextQueuedLogToServer() but not sending request', { | ||
hasPendingRequest: this.hasPendingRequest, | ||
hasPendingRequest: !!this.pendingRequest, | ||
sendQueueLength: this.sendQueue.length | ||
@@ -132,11 +184,16 @@ }); | ||
/* reset state and send the next item in the queue */ | ||
_this.hasPendingRequest = false; | ||
_this.pendingRequest = undefined; | ||
_this.sendNextQueuedLogToServer(); | ||
}); | ||
this.hasPendingRequest = true; | ||
this.pendingRequest = queueItem; | ||
this.debug('sending logs to server', { queueItem: queueItem.requestParams, sendQueue: this.sendQueue.map(function (i) { return i.requestParams; }) }); | ||
// return backOff(this.sendPostRequest.bind(this, queueItem.requestParams), { | ||
return [2 /*return*/, (0, exponential_backoff_1.backOff)(function () { return _this.sendPostRequest(queueItem.requestParams); }, { | ||
return [2 /*return*/, (0, exponential_backoff_1.backOff)(function () { return _this.backoffFn(queueItem.requestParams); }, { | ||
retry: function (err) { | ||
return !!(err && err.status === 429); | ||
var _a; | ||
var status = (_a = err.response) === null || _a === void 0 ? void 0 : _a.status; | ||
var code = err.code; | ||
// we get a "ERR_NETWORK" in the case of a network blip failure. if this happens, we will want to try again. | ||
// this is akin to not getting a response at all | ||
return (status && STATUS_CODES_TO_RETRY_IMMEDIATELY.includes(status)) || code === "ERR_NETWORK"; | ||
}, | ||
@@ -152,9 +209,45 @@ numOfAttempts: 10, | ||
}) | ||
.catch(function (error) { | ||
_this.debug('ERROR sending logs to server', { requestParams: queueItem.requestParams, error: error }); | ||
return queueItem.deferred.reject(error); | ||
})]; | ||
.catch(this.handleBackoffError.bind(this, queueItem))]; | ||
}); | ||
}); | ||
}; | ||
LogUploader.prototype.handleBackoffError = function (queueItem, error) { | ||
var _a; | ||
// there are certain errors we know we don't want to try again, and certain errors/responses that *may* work in the future. | ||
var status = (_a = error.response) === null || _a === void 0 ? void 0 : _a.status; | ||
var isRetriableStatus = status && STATUS_CODES_TO_RETRY_IMMEDIATELY.includes(status) || STATUS_CODES_TO_RETRY_LATER.includes(status); | ||
if (isRetriableStatus || error.code === "ERR_NETWORK") { | ||
this.debug('Failed to sends logs to the server, moving request to the end of the queue', { requestParams: queueItem.requestParams, error: error }); | ||
this.saveRequestForLater(queueItem.requestParams); | ||
} | ||
else { | ||
this.debug('ERROR sending logs to server', { requestParams: queueItem.requestParams, error: error }); | ||
} | ||
queueItem.deferred.reject(__assign(__assign({}, error), { id: "rejectionSpot1" })); | ||
}; | ||
LogUploader.prototype.backoffFn = function (requestParams) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var accessToken, response, savedRequests; | ||
var _this = this; | ||
return __generator(this, function (_a) { | ||
switch (_a.label) { | ||
case 0: | ||
accessToken = requestParams.accessToken; | ||
return [4 /*yield*/, this.sendPostRequest(requestParams)]; | ||
case 1: | ||
response = _a.sent(); | ||
savedRequests = this.getSavedRequests(); | ||
if (savedRequests) { | ||
window.localStorage.removeItem(SAVED_REQUESTS_KEY); | ||
savedRequests.map(function (request) { | ||
var reqWithToken = __assign({ accessToken: accessToken }, request); | ||
// this adds it to the send queue, it doesn't send it immediately | ||
_this.postLogsToEndpoint(reqWithToken); | ||
}); | ||
} | ||
return [2 /*return*/, response]; | ||
} | ||
}); | ||
}); | ||
}; | ||
LogUploader.prototype.sendPostRequest = function (requestParams) { | ||
@@ -161,0 +254,0 @@ this.debug('issuing POST request', { requestParams: requestParams }); |
@@ -226,5 +226,5 @@ "use strict"; | ||
/* eslint-disable @typescript-eslint/naming-convention */ | ||
Logger.VERSION = '4.1.2'; | ||
Logger.VERSION = '4.2.0'; | ||
return Logger; | ||
}(events_1.EventEmitter)); | ||
exports.Logger = Logger; |
@@ -152,3 +152,3 @@ "use strict"; | ||
this.logBuffer.map(function (item) { | ||
return _this.logUploader.postLogsToEndpointInstantly(_this.convertToRequestParams(item.traces.reverse())); | ||
return _this.logUploader.postLogsToEndpointInstantly(_this.convertToRequestParams(item.traces.reverse()), { saveOnFailure: true }); | ||
})); | ||
@@ -155,0 +155,0 @@ }; |
{ | ||
"name": "genesys-cloud-client-logger", | ||
"version": "4.1.2-develop.8", | ||
"version": "4.2.0-PCM-1992.2", | ||
"description": "Common logger for genesys cloud client application to upload logs server", | ||
@@ -5,0 +5,0 @@ "main": "dist/src/index.js", |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
2769558
21472