🚀 Big News: Socket Acquires Coana to Bring Reachability Analysis to Every Appsec Team.Learn more
Socket
Sign inDemoInstall
Socket

@evo/gotcha-log

Package Overview
Dependencies
Maintainers
14
Versions
18
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@evo/gotcha-log - npm Package Compare versions

Comparing version

to
1.5.1

dist/metrics/config.js

51

dist/config.js

@@ -1,5 +0,5 @@

'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true
});

@@ -9,35 +9,40 @@ exports.initConfig = initConfig;

var _utils = require('./utils');
var _utils = require("./utils");
function Config(site, host, txid) {
if (!site) (0, _utils.logWarn)('missing site for gotcha');
if (!host) (0, _utils.logWarn)('missing host for gotcha');
this.getSite = function () {
return site;
};
this.getHost = function () {
return host;
};
this.getTXID = function () {
return txid;
};
if (!site) (0, _utils.logWarn)('missing site for gotcha');
if (!host) (0, _utils.logWarn)('missing host for gotcha');
this.getSite = function () {
return site;
};
this.getHost = function () {
return host;
};
this.getTXID = function () {
return txid;
};
}
var config = void 0;
var config;
function hasGlobalGotcha() {
return window && window._GOTCHA_IS_HERE;
return window && window._GOTCHA_IS_HERE;
}
function initConfig(site, host, txid) {
config = new Config(site, host, txid);
config = new Config(site, host, txid);
}
function getConfig() {
if (config) return config;
if (hasGlobalGotcha()) {
config = new Config(window.GOTCHA_SITE, window.GOTCHA_HOST, window.GOTCHA_TXID);
return config;
}
throw new Error('[GOTCHA-LOG] You should call initGotchaLogger before log');
if (config) return config;
if (hasGlobalGotcha()) {
config = new Config(window.GOTCHA_SITE, window.GOTCHA_HOST, window.GOTCHA_TXID);
return config;
}
throw new Error('[GOTCHA-LOG] You should call initGotchaLogger before log');
}

@@ -1,2 +0,2 @@

'use strict';
"use strict";

@@ -6,5 +6,10 @@ Object.defineProperty(exports, "__esModule", {

});
var ERROR_TYPE = exports.ERROR_TYPE = 'error';
var LOG_TYPE = exports.LOG_TYPE = 'log';
var LOG_EVENT = exports.LOG_EVENT = 'gotchaLog';
var ERR_EVENT = exports.ERR_EVENT = 'gotchaErr';
exports.ERR_EVENT = exports.LOG_EVENT = exports.LOG_TYPE = exports.ERROR_TYPE = void 0;
var ERROR_TYPE = 'error';
exports.ERROR_TYPE = ERROR_TYPE;
var LOG_TYPE = 'log';
exports.LOG_TYPE = LOG_TYPE;
var LOG_EVENT = 'gotchaLog';
exports.LOG_EVENT = LOG_EVENT;
var ERR_EVENT = 'gotchaErr';
exports.ERR_EVENT = ERR_EVENT;

@@ -1,82 +0,104 @@

'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true
});
exports.isObject = isObject;
exports.formatExtra = exports.extractKeysValues = exports.addTypeToKey = void 0;
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
exports.isObject = isObject;
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr && (typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]); if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function isObject(obj) {
try {
return Boolean(Object.keys(obj).length && obj.constructor === Object);
} catch (err) {
return false;
}
try {
return Boolean(Object.keys(obj).length && obj.constructor === Object);
} catch (err) {
return false;
}
}
var TYPE_MAP = {
number: 'int',
string: 'str',
boolean: 'bool'
number: 'int',
string: 'str',
"boolean": 'bool'
};
var addTypeToKey = exports.addTypeToKey = function addTypeToKey(key, value) {
var valueType = typeof value === 'undefined' ? 'undefined' : _typeof(value);
if (TYPE_MAP[valueType]) {
return key + '_' + TYPE_MAP[valueType];
}
return '';
var addTypeToKey = function addTypeToKey(key, value) {
var valueType = _typeof(value);
if (TYPE_MAP[valueType]) {
return "".concat(key, "_").concat(TYPE_MAP[valueType]);
}
return '';
};
var extractKeysValues = exports.extractKeysValues = function extractKeysValues(obj) {
var parentKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
exports.addTypeToKey = addTypeToKey;
return Object.keys(obj).reduce(function (result, key) {
var value = obj[key];
var pKey = parentKey ? parentKey + '_' + key : key;
if (isObject(value)) {
return result.concat(extractKeysValues(value, pKey));
}
return result.concat([[pKey, value]]);
}, []);
var extractKeysValues = function extractKeysValues(obj) {
var parentKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
return Object.keys(obj).reduce(function (result, key) {
var value = obj[key];
var pKey = parentKey ? "".concat(parentKey, "_").concat(key) : key;
if (isObject(value)) {
return result.concat(extractKeysValues(value, pKey));
}
return result.concat([[pKey, value]]);
}, []);
};
exports.extractKeysValues = extractKeysValues;
function getArrayTypeMap(arr, key) {
var arrTypeKeys = {};
arr.forEach(function (v) {
var arrKey = addTypeToKey(key, v);
if (!arrKey) return;
if (!arrTypeKeys[arrKey]) {
arrTypeKeys[arrKey] = [];
}
arrTypeKeys[arrKey].push(v);
});
return arrTypeKeys;
var arrTypeKeys = {};
arr.forEach(function (v) {
var arrKey = addTypeToKey(key, v);
if (!arrKey) return;
if (!arrTypeKeys[arrKey]) {
arrTypeKeys[arrKey] = [];
}
arrTypeKeys[arrKey].push(v);
});
return arrTypeKeys;
}
var formatExtra = exports.formatExtra = function formatExtra(extra) {
var result = {};
var formatExtra = function formatExtra(extra) {
var result = {};
extractKeysValues(extra).forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
key = _ref2[0],
value = _ref2[1];
extractKeysValues(extra).forEach(function (_ref) {
var _ref2 = _slicedToArray(_ref, 2),
key = _ref2[0],
value = _ref2[1];
if (Array.isArray(value)) {
var arrayTypeMap = getArrayTypeMap(value, key);
Object.keys(arrayTypeMap).forEach(function (k) {
result[k] = arrayTypeMap[k];
});
return;
}
if (Array.isArray(value)) {
var arrayTypeMap = getArrayTypeMap(value, key);
Object.keys(arrayTypeMap).forEach(function (k) {
result[k] = arrayTypeMap[k];
});
return;
}
var formattedKey = addTypeToKey(key, value);
if (formattedKey) {
result[formattedKey] = value;
}
});
var formattedKey = addTypeToKey(key, value);
return result;
};
if (formattedKey) {
result[formattedKey] = value;
}
});
return result;
};
exports.formatExtra = formatExtra;

@@ -1,5 +0,5 @@

'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true
});

@@ -10,26 +10,28 @@ exports.log = log;

var _formatExtra = require('./formatExtra');
var _formatExtra = require("./formatExtra");
var _config = require('./config');
var _config = require("./config");
var _transport = require('./transport');
var _transport = require("./transport");
function log(msg, extra) {
if (extra) {
extra = (0, _formatExtra.formatExtra)(extra);
}
var conf = (0, _config.getConfig)();
(0, _transport.postLog)(msg, extra, conf);
if (extra) {
extra = (0, _formatExtra.formatExtra)(extra);
}
var conf = (0, _config.getConfig)();
(0, _transport.postLog)(msg, extra, conf);
}
function error(msg, extra) {
if (extra) {
extra = (0, _formatExtra.formatExtra)(extra);
}
var conf = (0, _config.getConfig)();
(0, _transport.postErr)(msg, extra, conf);
if (extra) {
extra = (0, _formatExtra.formatExtra)(extra);
}
var conf = (0, _config.getConfig)();
(0, _transport.postErr)(msg, extra, conf);
}
function initGotchaLogger(site, host, txid) {
(0, _config.initConfig)(site, host, txid);
(0, _config.initConfig)(site, host, txid);
}

@@ -1,63 +0,78 @@

'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true
});
exports.xhrPOST = xhrPOST;
exports.postLog = postLog;
exports.postErr = postErr;
var _utils = require('./utils');
var _utils = require("./utils");
var _defs = require('./defs');
var _defs = require("./defs");
function buildMessage(_ref) {
var site = _ref.site,
message = _ref.message,
type = _ref.type,
extra = _ref.extra;
var screen = window.screen;
return {
message: message,
filename: 'default',
line: 0,
column: 0,
screenWidth: screen && screen.availWidth,
screenHeight: screen && screen.availHeight,
currentUrl: window.location.href,
site: site,
type: type,
ctx: extra
};
var site = _ref.site,
message = _ref.message,
type = _ref.type,
extra = _ref.extra;
var _window = window,
screen = _window.screen;
return {
message: message,
filename: 'default',
line: 0,
column: 0,
screenWidth: screen && screen.availWidth,
screenHeight: screen && screen.availHeight,
currentUrl: window.location.href,
site: site,
type: type,
ctx: extra
};
}
function xhrPOST(endpoint, jsonPayload, txid) {
var payload = JSON.stringify(jsonPayload);
try {
var xhr = new window.XMLHttpRequest();
if (process.env.NODE_ENV === 'dev') {
xhr.onerror = function () {
(0, _utils.logWarn)('POST request failed');
};
}
var payload = JSON.stringify(jsonPayload);
xhr.open('POST', endpoint, true);
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
if (txid) {
xhr.setRequestHeader('X-Request-ID', txid);
}
xhr.send(payload);
} catch (e) {
(0, _utils.logWarn)('Error sending POST xhr');
try {
var xhr = new window.XMLHttpRequest();
if (process.env.NODE_ENV === 'dev') {
xhr.onerror = function () {
(0, _utils.logWarn)('POST request failed');
};
}
xhr.open('POST', endpoint, true);
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
if (txid) {
xhr.setRequestHeader('X-Request-ID', txid);
}
xhr.send(payload);
} catch (e) {
(0, _utils.logWarn)('Error sending POST xhr');
}
}
function postLog(message, extra, config) {
var payload = buildMessage({ message: message, site: config.getSite(), type: _defs.LOG_TYPE, extra: extra });
xhrPOST(config.getHost(), payload, config.getTXID());
var payload = buildMessage({
message: message,
site: config.getSite(),
type: _defs.LOG_TYPE,
extra: extra
});
xhrPOST(config.getHost(), payload, config.getTXID());
}
function postErr(message, extra, config) {
var payload = buildMessage({ message: message, site: config.getSite(), type: _defs.ERROR_TYPE, extra: extra });
xhrPOST(config.getHost(), payload, config.getTXID());
var payload = buildMessage({
message: message,
site: config.getSite(),
type: _defs.ERROR_TYPE,
extra: extra
});
xhrPOST(config.getHost(), payload, config.getTXID());
}

@@ -1,18 +0,19 @@

'use strict';
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
value: true
});
exports.logWarn = logWarn;
exports.logInfo = logInfo;
function logWarn(msg) {
if (process.env.NODE_ENV !== 'production') {
console.warn && console.warn('[GOTCHA-LOG] ' + msg);
}
if (process.env.NODE_ENV !== 'production') {
console.warn && console.warn("[GOTCHA-LOG] ".concat(msg));
}
}
function logInfo(msg) {
if (process.env.NODE_ENV !== 'production') {
console.log && console.log('[GOTCHA-LOG] ' + msg);
}
if (process.env.NODE_ENV !== 'production') {
console.log && console.log("[GOTCHA-LOG] ".concat(msg));
}
}
{
"name": "@evo/gotcha-log",
"version": "1.4.0",
"version": "1.5.1",
"description": "",

@@ -8,5 +8,8 @@ "main": "dist/index.js",

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"prepublish": "vagga build",
"preversion": "vagga lint && vagga test"
"test": "NODE_ENV=test mocha tests/**/",
"prepublishOnly": "npm run build",
"lint": "eslint --fix src tests",
"preversion": "npm run lint && npm run test",
"prepare": "husky install",
"build": "babel src -d dist"
},

@@ -20,17 +23,19 @@ "repository": {

"devDependencies": {
"@evo/eslint-config-uaprom": "^2.0.0",
"babel-cli": "^6.24.1",
"babel-core": "^6.24.1",
"babel-preset-env": "^1.3.3",
"babel-register": "6.24.1",
"chai": "^3.5.0",
"eslint": "^3.19.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-jsx-a11y": "^4.0.0",
"eslint-plugin-react": "^6.10.3",
"jsdom": "9.12.0",
"jsdom-global": "2.1.1",
"mocha": "^3.2.0",
"sinon": "4.1.2"
"@babel/cli": "^7.13.16",
"@babel/core": "^7.13.16",
"@babel/preset-env": "^7.13.15",
"@babel/register": "^7.13.16",
"@evo/eslint-config-uaprom": "^6.0.0",
"chai": "^4.3.4",
"eslint": "^7.25.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-react": "^7.23.2",
"eslint-scope": "^5.1.1",
"husky": "^6.0.0",
"jsdom": "16.5.3",
"jsdom-global": "3.0.2",
"mocha": "^8.3.2",
"sinon": "10.0.0"
}
}

@@ -72,1 +72,71 @@ ## gotcha-log

## @evo/gotcha-log/src/metrics
There was a need to transfer the numerical data of event metrics to the backend from the frontend to save them in the Prometheus.
For this purpose a sub-module of metrics was created.
The design of the module has been inspired by the package [prom-client](https://github.com/siimon/prom-client)
All metrics are uploaded to backend using [window.sendBeacon()](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/sendBeacon). If browser does not support this API, it will fallbacks to `XMLHttpRequest()`
> NOTE:
>
> Before add metrics to your project, you must add your project config to [gotcha-server](https://gitlab.evo.dev/gotcha/gotcha-server#write-prometheus-metrics-from-frontend)
### Usage:
Common usage:
```js
// at start of your application, initialize metrics module
import {initGotchaMetrics, metric} from '@evo/gotcha-log/src/metrics';
initGotchaMetrics({
project: <project-id>, // do not forget, to add your project to gotcha-server config
host: <gotcha-backend-host>
});
// create metric: metric(<name>, [<value>], [<labels>])
metric(
'pageview', // metric name
1, // value
{page:'koshyk'} // labels
)
```
Also you can create metric instance manually:
```js
import { Counter } from '@evo/gotcha-log/src/metrics';
const reduxActionsErrorsCounter=new Counter({
name: 'redux-errors'
});
reduxActionsErrorsCounter.inc(123, {action: 'createOrder', version: '1.2.3'})
// or
const incCounter=reduxActionsErrorsCounter.getStandaloneInc( {action: 'createOrder', version: '1.2.3'})
incCounter(3) // which is equivalent to reduxActionsErrorsCounter.inc(3, {action: 'createOrder', version: '1.2.3'})
```
All metrics will upload to backend automatically each 5s. You can stop uploading by calling:
```js
import { stopUploadByInterval } from '@evo/gotcha-log/src/metrics';
stopUploadByInterval()
```
And resume it by calling:
```js
import { startUploadByInterval } from '@evo/gotcha-log/src/metrics';
startUploadByInterval()
```
> NOTE:
>
> `startUploadByInterval` and `stopUploadByInterval` also add `beforeonload` event listener,
> which will upload the last metrics to backend, before user leaves current page
Send metrics to backend immediately:
```js
import { immediatelyUploadMetrics } from '@evo/gotcha-log/src/metrics';
immediatelyUploadMetrics()
```