autotel
Version:
Write Once, Observe Anywhere
289 lines (286 loc) • 7.86 kB
JavaScript
'use strict';
var chunkESLWRGAG_cjs = require('./chunk-ESLWRGAG.cjs');
require('@opentelemetry/api');
var Metric = class {
serviceName;
eventCounter;
funnelCounter;
outcomeCounter;
valueHistogram;
logger;
collector;
/**
* Create a new Metrics instance
*
* @param serviceName - Service name for metric namespacing
* @param options - Optional configuration (logger, collector, namespace, metrics)
*
* @example Basic usage (default 'metrics' namespace)
* ```typescript
* const metrics = new Metric('checkout');
* // Creates: checkout.metrics.events, checkout.metrics.funnel, etc.
* ```
*
* @example Custom namespace
* ```typescript
* const metrics = new Metric('api', { namespace: 'business' });
* // Creates: api.business.events, api.business.funnel, etc.
* ```
*
* @example Custom metric names and descriptions
* ```typescript
* const metrics = new Metric('payments', {
* metrics: {
* outcomes: {
* name: 'payments.transactions',
* description: 'Payment transaction outcomes',
* unit: 'transactions'
* },
* value: {
* name: 'payments.revenue',
* description: 'Payment revenue in USD',
* unit: 'USD'
* }
* }
* });
* ```
*/
constructor(serviceName, options = {}) {
this.serviceName = serviceName;
this.logger = options.logger;
this.collector = options.collector;
const config = chunkESLWRGAG_cjs.getConfig();
const meter = config.meter;
const namespace = options.namespace || "metrics";
const metricsConfig = options.metrics || {};
const eventsConfig = metricsConfig.events || {};
this.eventCounter = meter.createCounter(
eventsConfig.name || `${serviceName}.${namespace}.events`,
{
description: eventsConfig.description || "Count of business events",
unit: eventsConfig.unit || "1"
}
);
const funnelConfig = metricsConfig.funnel || {};
this.funnelCounter = meter.createCounter(
funnelConfig.name || `${serviceName}.${namespace}.funnel`,
{
description: funnelConfig.description || "Conversion funnel tracking",
unit: funnelConfig.unit || "1"
}
);
const outcomesConfig = metricsConfig.outcomes || {};
this.outcomeCounter = meter.createCounter(
outcomesConfig.name || `${serviceName}.${namespace}.outcomes`,
{
description: outcomesConfig.description || "Outcome tracking (success/failure)",
unit: outcomesConfig.unit || "1"
}
);
const valueConfig = metricsConfig.value || {};
this.valueHistogram = meter.createHistogram(
valueConfig.name || `${serviceName}.${namespace}.value`,
{
description: valueConfig.description || "Value metrics (revenue, counts, etc.)",
unit: valueConfig.unit || "1"
}
);
}
/**
* Track a business event as a metric
*
* Use this for tracking user actions, business events, product usage as metrics:
* - "user.signup"
* - "order.completed"
* - "feature.used"
*
* @example
* ```typescript
* // Track user signup as metric
* metrics.trackEvent('user.signup', {
* userId: '123',
* plan: 'pro'
* })
*
* // Track order as metric
* metrics.trackEvent('order.completed', {
* orderId: 'ord_123',
* amount: 99.99
* })
* ```
*/
trackEvent(eventName, attributes) {
const attrs = {
service: this.serviceName,
event: eventName,
...attributes
};
this.eventCounter.add(1, attrs);
this.logger?.info(
{
event: eventName,
attributes
},
"Metric event tracked"
);
this.collector?.recordEvent({
event: eventName,
attributes,
service: this.serviceName,
timestamp: Date.now()
});
}
/**
* Track conversion funnel steps as metrics
*
* Monitor where users drop off in multi-step processes.
*
* @example
* ```typescript
* // Track signup funnel
* metrics.trackFunnelStep('signup', 'started', { userId: '123' })
* metrics.trackFunnelStep('signup', 'email_verified', { userId: '123' })
* metrics.trackFunnelStep('signup', 'completed', { userId: '123' })
*
* // Track checkout flow
* metrics.trackFunnelStep('checkout', 'started', { cartValue: 99.99 })
* metrics.trackFunnelStep('checkout', 'payment_info', { cartValue: 99.99 })
* metrics.trackFunnelStep('checkout', 'completed', { cartValue: 99.99 })
* ```
*/
trackFunnelStep(funnelName, status, attributes) {
const attrs = {
service: this.serviceName,
funnel: funnelName,
status,
...attributes
};
this.funnelCounter.add(1, attrs);
this.logger?.info(
{
funnel: funnelName,
status,
attributes
},
"Funnel step tracked"
);
this.collector?.recordFunnelStep({
funnel: funnelName,
status,
attributes,
service: this.serviceName,
timestamp: Date.now()
});
}
/**
* Track outcomes (success/failure/partial) as metrics
*
* Monitor success rates of critical operations.
*
* @example
* ```typescript
* // Track email delivery
* metrics.trackOutcome('email.delivery', 'success', {
* recipientType: 'user',
* emailType: 'welcome'
* })
*
* metrics.trackOutcome('email.delivery', 'failure', {
* recipientType: 'user',
* errorCode: 'invalid_email'
* })
*
* // Track payment processing
* metrics.trackOutcome('payment.process', 'success', { amount: 99.99 })
* metrics.trackOutcome('payment.process', 'failure', { error: 'insufficient_funds' })
* ```
*/
trackOutcome(operationName, status, attributes) {
const attrs = {
service: this.serviceName,
operation: operationName,
status,
...attributes
};
this.outcomeCounter.add(1, attrs);
this.logger?.info(
{
operation: operationName,
status,
attributes
},
"Outcome tracked"
);
this.collector?.recordOutcome({
operation: operationName,
status,
attributes,
service: this.serviceName,
timestamp: Date.now()
});
}
/**
* Track value metrics
*
* Record numerical values like revenue, transaction amounts,
* item counts, processing times, engagement scores, etc.
*
* @example
* ```typescript
* // Track revenue
* metrics.trackValue('order.revenue', 149.99, {
* currency: 'USD',
* productCategory: 'electronics'
* })
*
* // Track items per cart
* metrics.trackValue('cart.item_count', 5, {
* userId: '123'
* })
*
* // Track processing time
* metrics.trackValue('api.response_time', 250, {
* unit: 'ms',
* endpoint: '/api/checkout'
* })
* ```
*/
trackValue(metricName, value, attributes) {
const attrs = {
service: this.serviceName,
metric: metricName,
...attributes
};
this.valueHistogram.record(value, attrs);
this.logger?.debug(
{
metric: metricName,
value,
attributes
},
"Value metric tracked"
);
this.collector?.recordValue({
metric: metricName,
value,
attributes,
service: this.serviceName,
timestamp: Date.now()
});
}
};
var metricsInstances = /* @__PURE__ */ new Map();
function getMetrics(serviceName, logger) {
if (!metricsInstances.has(serviceName)) {
metricsInstances.set(serviceName, new Metric(serviceName, { logger }));
}
return metricsInstances.get(serviceName);
}
function resetMetrics() {
metricsInstances.clear();
}
exports.Metric = Metric;
exports.getMetrics = getMetrics;
exports.resetMetrics = resetMetrics;
//# sourceMappingURL=chunk-TC5ZPWM4.cjs.map
//# sourceMappingURL=chunk-TC5ZPWM4.cjs.map