@vtex/api
Version:
VTEX I/O API client
151 lines (150 loc) • 5.38 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MetricsLogger = void 0;
const fast_json_stable_stringify_1 = __importDefault(require("fast-json-stable-stringify"));
const ramda_1 = require("ramda");
const stats_lite_1 = require("stats-lite");
const constants_1 = require("../../constants");
const diff_1 = require("../worker/runtime/utils/diff");
const runtimeBaseDefaultMetricNames = ['routeStats'];
const runtimeNodeDefaultMetricNames = {
cpuUsage: 'cpuUsage',
memoryUsage: 'memoryUsage',
};
const invalidMetricNames = runtimeBaseDefaultMetricNames.concat(Object.values(runtimeNodeDefaultMetricNames));
class MetricsLogger {
constructor() {
//////////////////////
// private attributes
//////////////////////
let samples = {};
let lastCpu = (0, diff_1.cpuSnapshot)();
//////////////////////
// private methods definitions
//////////////////////
const summaries = (0, ramda_1.compose)((0, ramda_1.reject)(ramda_1.isNil), ramda_1.values, (0, ramda_1.mapObjIndexed)(getSummary));
function getDefaultStoredashProperties() {
return {
Count: 1,
Max: 0,
Min: 0,
Name: 'runtime',
Sum: 0,
Timestamp: (new Date()).getTime(),
Unit: '',
};
}
function getProcessEnv() {
return {
appName: process.env.VTEX_APP_NAME || '',
appVersion: process.env.VTEX_APP_VERSION || '',
production: constants_1.PRODUCTION,
region: process.env.VTEX_REGION || '',
vendor: process.env.VTEX_APP_VENDOR || '',
};
}
function getCpuUsage() {
const cpu = (0, diff_1.cpuSnapshot)();
const cpuDiff = (0, diff_1.snapshotDiff)(cpu, lastCpu);
lastCpu = cpu;
const metric = {
Data: {
key: {
name: runtimeNodeDefaultMetricNames.cpuUsage,
},
processEnv: getProcessEnv(),
summary: cpuDiff,
},
...getDefaultStoredashProperties(),
};
return metric;
}
function getMemoryUsage() {
const metric = {
Data: {
key: {
name: runtimeNodeDefaultMetricNames.memoryUsage,
},
processEnv: getProcessEnv(),
summary: process.memoryUsage(),
},
...getDefaultStoredashProperties(),
};
return metric;
}
function getRuntimeSummaries() {
return [getCpuUsage(), getMemoryUsage()];
}
function getSummary(vals, strKey) {
if (strKey in samples) {
const summary = getNumericSummary(vals);
const keyObj = JSON.parse(strKey);
const metric = {
Data: {
key: keyObj,
processEnv: getProcessEnv(),
summary,
},
...getDefaultStoredashProperties(),
};
return metric;
}
return null;
}
// TODO: create some kind of alert/log if metric is not valid
function validKey(key) {
if (!('name' in key)) {
return false;
}
if (invalidMetricNames.includes(key.name)) {
return false;
}
try {
(0, fast_json_stable_stringify_1.default)(key);
}
catch {
return false;
}
return true;
}
function getStrKey(key) {
return (0, fast_json_stable_stringify_1.default)(key);
}
function getNumericSummary(vals) {
return {
count: vals.length,
max: Math.max(...vals),
median: (0, stats_lite_1.median)(vals),
min: Math.min(...vals),
percentile95: (0, stats_lite_1.percentile)(vals, 0.95),
percentile99: (0, stats_lite_1.percentile)(vals, 0.99),
sum: (0, stats_lite_1.sum)(vals),
};
}
//////////////////////
// public methods definitions
//////////////////////
this.add = (key, value) => {
if (validKey(key)) {
const strKey = getStrKey(key);
if (!(strKey in samples)) {
samples[strKey] = [];
}
samples[strKey].push(value);
}
};
this.getSummaries = () => {
const appSummaries = summaries(samples);
samples = {};
const runtimeSummaries = getRuntimeSummaries();
return runtimeSummaries.concat(appSummaries);
};
//////////////////////
// real constructor
//////////////////////
}
}
exports.MetricsLogger = MetricsLogger;