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
Create custom timing segments for specific operations and code blocks within transactions.
Wrap a function in a segment to track its execution time and optionally record it as a metric.
/**
* Wraps a function in a segment for custom timing. Must be called within an active transaction.
* @param {string} name - The name for the segment and optional metric
* @param {boolean} record - Whether to record the segment as a metric
* @param {Function} handler - The function to track as a segment
* @param {Function} [callback] - Optional callback for async operations
* @returns {*} The return value of the handler function
*/
function startSegment(name, record, handler, callback);Usage Examples:
const newrelic = require('newrelic');
// Simple synchronous segment
function processData(data) {
return newrelic.startSegment('DataProcessing', true, () => {
// This work will be timed and recorded as a metric
return performExpensiveCalculation(data);
});
}
// Asynchronous segment with callback
function fetchUserData(userId, callback) {
newrelic.startSegment('FetchUser', true, (cb) => {
database.getUser(userId, cb);
}, callback);
}
// Asynchronous segment with promises
async function processOrder(orderId) {
return newrelic.startSegment('OrderProcessing', true, async () => {
const order = await database.getOrder(orderId);
const processed = await processPayment(order);
await updateInventory(order.items);
return processed;
});
}
// Segment without metric recording (for tracing only)
function validateInput(input) {
return newrelic.startSegment('InputValidation', false, () => {
return validator.validate(input);
});
}record: true): Create metrics that appear in transaction breakdown and server breakdown graphsrecord: false): Only appear in transaction traces for detailed timing informationSegments automatically:
async function getUserWithProfile(userId) {
const user = await newrelic.startSegment('Database/GetUser', true, async () => {
return await database.users.findById(userId);
});
const profile = await newrelic.startSegment('Database/GetProfile', true, async () => {
return await database.profiles.findByUserId(userId);
});
return { user, profile };
}async function callPaymentService(paymentData) {
return newrelic.startSegment('External/PaymentService', true, async () => {
const response = await httpClient.post('/api/payments', paymentData);
return response.data;
});
}
async function callMultipleServices(data) {
const [userService, orderService, notificationService] = await Promise.all([
newrelic.startSegment('External/UserService', true, () =>
userServiceClient.updateUser(data.user)
),
newrelic.startSegment('External/OrderService', true, () =>
orderServiceClient.createOrder(data.order)
),
newrelic.startSegment('External/NotificationService', true, () =>
notificationClient.sendEmail(data.notification)
)
]);
return { userService, orderService, notificationService };
}async function processComplexWorkflow(workflowData) {
// Validate input (trace only, no metric)
const validatedData = newrelic.startSegment('Workflow/Validation', false, () => {
return validateWorkflowData(workflowData);
});
// Initialize workflow (recorded as metric)
const workflow = await newrelic.startSegment('Workflow/Initialize', true, async () => {
return await initializeWorkflow(validatedData);
});
// Execute each step with timing
const results = [];
for (let i = 0; i < workflow.steps.length; i++) {
const step = workflow.steps[i];
const result = await newrelic.startSegment(`Workflow/Step${i + 1}`, true, async () => {
return await executeWorkflowStep(step, results);
});
results.push(result);
}
// Finalize workflow
return newrelic.startSegment('Workflow/Finalize', true, async () => {
return await finalizeWorkflow(workflow, results);
});
}async function getCachedData(key) {
// Check cache (trace timing but don't record as metric)
let data = newrelic.startSegment('Cache/Get', false, () => {
return cache.get(key);
});
if (!data) {
// Cache miss - fetch from database (record as metric)
data = await newrelic.startSegment('Database/FetchForCache', true, async () => {
return await database.getData(key);
});
// Store in cache (trace only)
newrelic.startSegment('Cache/Set', false, () => {
cache.set(key, data, 3600); // 1 hour TTL
});
}
return data;
}const fs = require('fs').promises;
async function processFile(filePath) {
// Read file with timing
const content = await newrelic.startSegment('FileSystem/Read', true, async () => {
return await fs.readFile(filePath, 'utf8');
});
// Process content
const processed = newrelic.startSegment('FileProcessing/Parse', true, () => {
return parseFileContent(content);
});
// Transform data
const transformed = newrelic.startSegment('FileProcessing/Transform', true, () => {
return transformData(processed);
});
// Write result
await newrelic.startSegment('FileSystem/Write', true, async () => {
const outputPath = filePath.replace('.input', '.output');
return await fs.writeFile(outputPath, JSON.stringify(transformed));
});
return transformed;
}function performAnalytics(dataset) {
// Data preparation
const prepared = newrelic.startSegment('Analytics/DataPrep', true, () => {
return dataset.map(item => normalizeData(item));
});
// Statistical calculations
const stats = newrelic.startSegment('Analytics/Statistics', true, () => {
return {
mean: calculateMean(prepared),
median: calculateMedian(prepared),
standardDeviation: calculateStdDev(prepared)
};
});
// Generate report
const report = newrelic.startSegment('Analytics/ReportGeneration', true, () => {
return generateAnalyticsReport(prepared, stats);
});
return report;
}async function robustOperation(data) {
try {
return await newrelic.startSegment('RobustOperation/Execute', true, async () => {
const validated = validateData(data);
const processed = await processData(validated);
return processed;
});
} catch (error) {
// Errors are automatically captured by the segment
// Add additional context if needed
newrelic.addCustomAttribute('operationFailed', true);
newrelic.noticeError(error, {
operation: 'RobustOperation',
dataSize: data?.length || 0
});
throw error;
}
}async function nestedOperations(data) {
return newrelic.startSegment('MainOperation', true, async () => {
// Level 1 nested segment
const prepared = await newrelic.startSegment('MainOperation/Preparation', true, async () => {
// Level 2 nested segments
const cleaned = newrelic.startSegment('Preparation/DataCleaning', false, () => {
return cleanData(data);
});
const validated = newrelic.startSegment('Preparation/Validation', false, () => {
return validateData(cleaned);
});
return { cleaned, validated };
});
// Another level 1 segment
const result = await newrelic.startSegment('MainOperation/Processing', true, async () => {
return await processData(prepared.validated);
});
return result;
});
}function adaptiveSegmentRecording(data, options = {}) {
const shouldRecord = options.recordMetrics !== false;
const segmentName = options.segmentName || 'AdaptiveOperation';
return newrelic.startSegment(segmentName, shouldRecord, () => {
if (data.length > 1000) {
// For large datasets, add sub-segments
return newrelic.startSegment(`${segmentName}/LargeDataset`, shouldRecord, () => {
return processLargeDataset(data);
});
} else {
return processSmallDataset(data);
}
});
}