@vtex/api
Version:
VTEX I/O API client
87 lines (86 loc) • 4.6 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.timings = void 0;
const chalk_1 = __importDefault(require("chalk"));
const constants_1 = require("../../../../../constants");
const status_1 = require("../../../../../utils/status");
const time_1 = require("../../../../../utils/time");
const APP_ELAPSED_TIME_LOCATOR = (0, time_1.shrinkTimings)((0, time_1.formatTimingName)({
hopNumber: 0,
source: process.env.VTEX_APP_NAME,
target: '',
}));
const pid = chalk_1.default.magenta('[' + constants_1.PID + ']');
const formatDate = (date) => chalk_1.default.dim('[' + date.toISOString().split('T')[1] + ']');
const formatStatus = (status) => status >= 500 ? chalk_1.default.red(status.toString()) : (status >= 200 && status < 300 ? chalk_1.default.green(status.toString()) : status);
const formatMillis = (millis) => millis >= 500 ? chalk_1.default.red(millis.toString()) : millis >= 200 ? chalk_1.default.yellow(millis.toString()) : chalk_1.default.green(millis.toString());
const log = ({ vtex: { account, workspace, route: { id } }, path, method, status }, millis) => `${formatDate(new Date())}\t${pid}\t${account}/${workspace}:${id}\t${formatStatus(status)}\t${method}\t${path}\t${formatMillis(millis)} ms`;
const logBillingInfo = ({ account, workspace, production, route: { id, type } }, millis) => JSON.stringify({
'__VTEX_IO_BILLING': 'true',
'account': account,
'app': constants_1.APP.ID,
'handler': id,
'isLink': constants_1.LINKED,
'production': production,
'routeType': type === 'public' ? 'public_route' : 'private_route',
'timestamp': Date.now(),
'type': 'process-time',
'value': millis,
'vendor': constants_1.APP.VENDOR,
'workspace': workspace,
});
async function timings(ctx, next) {
const { vtex: { route: { id, type } }, vtex } = ctx;
// Set base attributes for all metrics recorded during this request.
// This includes metrics recorded by VTEX IO apps during handler execution.
// These attributes will be automatically merged with custom attributes.
const baseAttributes = {
[constants_1.AttributeKeys.VTEX_ACCOUNT_NAME]: vtex.account,
component: 'http-handler',
route_id: id,
route_type: type,
};
// Wrap the request handling with base attributes context.
// All metrics recorded during next() will automatically include these attributes.
const executeWithBaseAttributes = async () => {
// Errors will be caught by the next middleware so we don't have to catch.
await next();
const { status: statusCode, timings: { total } } = ctx;
const totalMillis = (0, time_1.hrToMillis)(total);
console.log(log(ctx, totalMillis));
console.log(logBillingInfo(vtex, totalMillis));
const status = (0, status_1.statusLabel)(statusCode);
// Legacy metrics (backward compatibility)
// Only batch successful responses so metrics don't consider errors
metrics.batch(`http-handler-${id}`, status === 'success' ? total : undefined, { [status]: 1 });
// New diagnostics metrics with stable names and attributes
// Note: base attributes (account, route_id, route_type) are automatically merged
// We only need to provide the response-specific attributes here
if (global.diagnosticsMetrics) {
const responseAttributes = {
status,
status_code: statusCode,
};
// Record latency histogram (record all requests, not just successful ones)
global.diagnosticsMetrics.recordLatency(total, responseAttributes);
// Increment counter (status is an attribute, not in metric name)
global.diagnosticsMetrics.incrementCounter('http_handler_requests_total', 1, responseAttributes);
}
else {
console.warn('DiagnosticsMetrics not available. HTTP handler metrics not reported.');
}
};
// If diagnosticsMetrics is available, run with base attributes context
// Otherwise, run without context (fallback for graceful degradation)
if (global.diagnosticsMetrics) {
await global.diagnosticsMetrics.runWithBaseAttributes(baseAttributes, executeWithBaseAttributes);
}
else {
console.warn('DiagnosticsMetrics not available. HTTP handler metrics not reported.');
await executeWithBaseAttributes();
}
}
exports.timings = timings;