Skip to main content

Custom Metrics

Track business-specific metrics alongside performance data.

Overview

Custom metrics let you track:

  • Business KPIs (orders, signups, revenue)
  • Feature usage statistics
  • Custom performance measurements
  • Application-specific health indicators

Recording Metrics

Counter Metrics

Track occurrences of events:

import SkySignal from '@skysignal/agent';

// Increment a counter
SkySignal.incrementCounter('orders.created');

// Increment by specific amount
SkySignal.incrementCounter('items.sold', 5);

// With tags for segmentation
SkySignal.incrementCounter('orders.created', 1, {
plan: 'premium',
region: 'us-east'
});

Gauge Metrics

Track values that go up and down:

// Set current value
SkySignal.setGauge('queue.size', 42);

// With tags
SkySignal.setGauge('active.users', 150, {
subscription: 'pro'
});

Histogram Metrics

Track distributions of values:

// Record timing
SkySignal.recordHistogram('checkout.duration', 2500); // ms

// Record size
SkySignal.recordHistogram('upload.size', 1024 * 1024); // bytes

// With tags
SkySignal.recordHistogram('api.latency', 45, {
endpoint: '/users',
method: 'GET'
});

Common Use Cases

E-commerce Metrics

// Track order value
Meteor.methods({
'orders.create'(items) {
const order = Orders.insert({
items,
total: calculateTotal(items),
createdAt: new Date()
});

// Record metrics
SkySignal.incrementCounter('orders.created');
SkySignal.recordHistogram('order.value', order.total);
SkySignal.incrementCounter('items.sold', items.length);

return order;
}
});

User Activity

// Track signups
Accounts.onCreateUser((options, user) => {
SkySignal.incrementCounter('users.signup', 1, {
source: options.profile?.source || 'organic'
});
return user;
});

// Track logins
Accounts.onLogin(({ user }) => {
SkySignal.incrementCounter('users.login', 1, {
method: user.services?.google ? 'google' : 'password'
});
});

Feature Usage

// Track feature adoption
function useFeature(featureName) {
SkySignal.incrementCounter('feature.used', 1, {
feature: featureName
});
}

// In your code
useFeature('dark-mode');
useFeature('export-csv');
useFeature('bulk-edit');

Queue Monitoring

// Monitor job queue depth
import { Jobs } from 'meteor/msavin:sjobs';

Meteor.setInterval(() => {
const pending = Jobs.count({ state: 'pending' });
const processing = Jobs.count({ state: 'processing' });

SkySignal.setGauge('jobs.pending', pending);
SkySignal.setGauge('jobs.processing', processing);
}, 10000);

External API Performance

// Track third-party API calls
async function callExternalAPI(endpoint) {
const start = Date.now();

try {
const result = await fetch(endpoint);
const duration = Date.now() - start;

SkySignal.recordHistogram('external.api.latency', duration, {
endpoint,
status: result.status
});

return result;
} catch (error) {
SkySignal.incrementCounter('external.api.error', 1, {
endpoint
});
throw error;
}
}

Viewing Custom Metrics

Dashboard

Custom metrics appear in your site's Custom Metrics tab:

  • Time-series graphs
  • Aggregations (sum, avg, min, max, p95)
  • Tag-based filtering

Best Practices

1. Use Consistent Naming

// ✅ Good: Hierarchical, consistent
'orders.created'
'orders.completed'
'orders.cancelled'

// ❌ Bad: Inconsistent naming
'newOrder'
'order_complete'
'cancelledOrders'

2. Limit Tag Cardinality

// ✅ Good: Low cardinality tags
SkySignal.incrementCounter('api.request', 1, {
endpoint: '/users', // Limited set
method: 'GET', // 4-5 values
status: '2xx' // Grouped status
});

// ❌ Bad: High cardinality (causes metric explosion)
SkySignal.incrementCounter('api.request', 1, {
userId: user._id, // Unique per user
timestamp: Date.now(), // Unique per request
requestId: uuid() // Unique per request
});

3. Use Appropriate Metric Types

ScenarioMetric Type
Event countsCounter
Current valueGauge
Durations/sizesHistogram
Rate calculationsCounter (derive rate)

4. Batch When Possible

// For high-frequency events, batch updates
let orderCount = 0;

function recordOrder() {
orderCount++;
}

Meteor.setInterval(() => {
if (orderCount > 0) {
SkySignal.incrementCounter('orders.created', orderCount);
orderCount = 0;
}
}, 10000); // Flush every 10 seconds

Alerting on Custom Metrics

Create alerts based on custom metrics:

  1. Go to SettingsAlerts
  2. Select Custom Metric
  3. Choose metric name and aggregation
  4. Set threshold and notification

Example alerts:

  • Order rate drops below 10/hour
  • Queue depth exceeds 1000
  • API error rate exceeds 5%

Next Steps