Application Performance Monitoring (APM) agent for Node.js applications with transaction tracing, error tracking, custom metrics, and distributed tracing capabilities.
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Record custom metrics and events for business analytics and performance tracking beyond standard APM data.
Record a custom metric with name and value for performance tracking.
/**
* Record a custom metric, usually associated with a particular duration.
* The name gets prefixed with 'Custom/' when sent to New Relic.
* @param {string} name - The metric name following standard naming rules
* @param {number|object} value - Numeric value or metrics object
*/
function recordMetric(name, value);Usage Examples:
const newrelic = require('newrelic');
// Simple numeric metrics
newrelic.recordMetric('API/ResponseTime', 245.5);
newrelic.recordMetric('Cache/HitRate', 0.85);
newrelic.recordMetric('Queue/Size', 127);
// Advanced metrics object with full statistics
newrelic.recordMetric('Custom/BatchProcessor/Duration', {
count: 50, // Number of measurements
total: 12500, // Total time across all measurements (ms)
min: 100, // Minimum value (ms)
max: 500, // Maximum value (ms)
sumOfSquares: 425000, // Sum of squares for standard deviation
totalExclusive: 11800 // Optional: exclusive time
});Create or update a counter metric by incrementing its count.
/**
* Create or update a custom metric that acts as a simple counter.
* @param {string} name - The metric name
* @param {number} [value] - Amount to increment by (defaults to 1, must be integer)
*/
function incrementMetric(name, value);Usage Examples:
// Simple counters
newrelic.incrementMetric('API/Requests'); // Increment by 1
newrelic.incrementMetric('Errors/ValidationFailed', 1);
newrelic.incrementMetric('Queue/Messages', 5); // Increment by 5
// Tracking business events
newrelic.incrementMetric('Business/Orders');
newrelic.incrementMetric('Business/SignUps');
newrelic.incrementMetric('Business/Cancellations');Record custom events for New Relic Insights analytics and querying.
/**
* Record custom event data which can be queried in New Relic Insights.
* Disabled in high security mode.
* @param {string} eventType - Event type name (alphanumeric, <255 chars, matches /^[a-zA-Z0-9:_ ]+$/)
* @param {object} attributes - Event attributes (keys <255 chars, values must be string/number/boolean)
* @returns {false|undefined} Returns false on error/disabled, undefined on success
*/
function recordCustomEvent(eventType, attributes);Usage Examples:
// User behavior events
newrelic.recordCustomEvent('UserAction', {
action: 'purchase',
userId: '12345',
amount: 99.99,
category: 'electronics',
paymentMethod: 'credit_card',
timestamp: Date.now()
});
// Business process events
newrelic.recordCustomEvent('OrderProcessed', {
orderId: 'ORD-789123',
customerId: 'CUST-456',
orderValue: 249.50,
shippingMethod: 'express',
processingTime: 1250,
warehouseLocation: 'US-EAST-1'
});
// System performance events
newrelic.recordCustomEvent('CacheRefresh', {
cacheType: 'user_sessions',
itemCount: 15000,
refreshDuration: 3400,
memoryUsage: 128.5,
hitRateImprovement: 0.15
});Send application log messages to New Relic for centralized logging.
/**
* Send an application log message to New Relic.
* Only works if application log forwarding is enabled.
* @param {object} logEvent - Log event object
* @param {string} logEvent.message - Log message (required)
* @param {string} [logEvent.level] - Log level (defaults to 'UNKNOWN')
* @param {number} [logEvent.timestamp] - Timestamp (defaults to Date.now())
* @param {Error} [logEvent.error] - Associated error object
*/
function recordLogEvent(logEvent);Usage Examples:
// Basic log event
newrelic.recordLogEvent({
message: 'User login successful',
level: 'INFO'
});
// Log with custom timestamp
newrelic.recordLogEvent({
message: 'Payment processing started',
level: 'INFO',
timestamp: Date.now(),
userId: '12345',
orderId: 'ORD-789'
});
// Log with error
newrelic.recordLogEvent({
message: 'Database connection failed',
level: 'ERROR',
error: new Error('Connection timeout'),
retryAttempt: 3,
databaseHost: 'db-primary.example.com'
});
// Structured log event
newrelic.recordLogEvent({
message: 'API request processed',
level: 'INFO',
endpoint: '/api/users',
method: 'POST',
statusCode: 201,
responseTime: 145,
userId: 'user-456'
});Event types must:
/^[a-zA-Z0-9:_ ]+$/Event attributes must have:
When high security mode is enabled:
recordCustomEvent() returns false and logs warningapi.custom_events_enabled: false - Disables custom eventscustom_insights_events.enabled: false - Disables custom eventsapplication_logging.forwarding.enabled: false - Disables log forwarding// E-commerce tracking
function trackPurchase(order) {
newrelic.recordCustomEvent('Purchase', {
orderId: order.id,
customerId: order.customerId,
totalAmount: order.total,
itemCount: order.items.length,
paymentMethod: order.payment.method,
shippingCost: order.shipping.cost,
discountAmount: order.discount || 0,
isFirstPurchase: order.customer.isNew
});
newrelic.incrementMetric('Business/Orders');
newrelic.recordMetric('Business/Revenue', order.total);
}// Custom performance tracking
function trackOperationPerformance(operationName, duration, metadata = {}) {
newrelic.recordMetric(`Operations/${operationName}/Duration`, duration);
newrelic.recordCustomEvent('OperationCompleted', {
operation: operationName,
duration: duration,
...metadata
});
if (duration > 5000) {
newrelic.incrementMetric(`Operations/${operationName}/SlowOperations`);
}
}
// Usage
const startTime = Date.now();
await performDatabaseMigration();
const duration = Date.now() - startTime;
trackOperationPerformance('DatabaseMigration', duration, {
recordsProcessed: 150000,
tablesUpdated: 12,
memoryPeak: process.memoryUsage().heapUsed
});// Feature adoption metrics
function trackFeatureUsage(featureName, userId, metadata = {}) {
newrelic.incrementMetric(`Features/${featureName}/Usage`);
newrelic.recordCustomEvent('FeatureUsed', {
feature: featureName,
userId: userId,
timestamp: Date.now(),
...metadata
});
}
// Usage examples
trackFeatureUsage('AdvancedSearch', user.id, {
searchTerms: 3,
filtersUsed: ['category', 'price_range'],
resultsFound: 47
});
trackFeatureUsage('ExportData', user.id, {
format: 'csv',
recordCount: 2500,
fileSize: '1.2MB'
});// Custom error tracking with metrics
function trackApplicationError(errorType, error, context = {}) {
newrelic.incrementMetric(`Errors/${errorType}`);
newrelic.recordCustomEvent('ApplicationError', {
errorType: errorType,
errorMessage: error.message,
stack: error.stack,
userId: context.userId,
operation: context.operation,
timestamp: Date.now()
});
newrelic.recordLogEvent({
message: `${errorType}: ${error.message}`,
level: 'ERROR',
error: error,
...context
});
}
// Usage
try {
await processPayment(paymentData);
} catch (error) {
trackApplicationError('PaymentProcessingError', error, {
userId: user.id,
operation: 'processPayment',
paymentMethod: paymentData.method,
amount: paymentData.amount
});
throw error;
}// System metrics collection
function recordSystemMetrics() {
const memoryUsage = process.memoryUsage();
const cpuUsage = process.cpuUsage();
// Memory metrics
newrelic.recordMetric('System/Memory/HeapUsed', memoryUsage.heapUsed);
newrelic.recordMetric('System/Memory/HeapTotal', memoryUsage.heapTotal);
newrelic.recordMetric('System/Memory/RSS', memoryUsage.rss);
// CPU metrics
newrelic.recordMetric('System/CPU/User', cpuUsage.user);
newrelic.recordMetric('System/CPU/System', cpuUsage.system);
// System health event
newrelic.recordCustomEvent('SystemHealth', {
memoryHeapUsed: memoryUsage.heapUsed,
memoryHeapTotal: memoryUsage.heapTotal,
memoryRSS: memoryUsage.rss,
cpuUser: cpuUsage.user,
cpuSystem: cpuUsage.system,
uptime: process.uptime(),
loadAverage: os.loadavg()[0]
});
}
// Run every 60 seconds
setInterval(recordSystemMetrics, 60000);