UNPKG

@vtex/api

Version:
87 lines (86 loc) 4.6 kB
"use strict"; 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;