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
Add custom metadata to transactions, spans, and events for enhanced filtering and analysis in New Relic dashboards.
Add a custom attribute to both the current transaction and span.
/**
* Add a custom attribute to the current transaction and span.
* Disabled in high security mode.
* @param {string} key - The attribute name
* @param {string|number|boolean} value - The attribute value (must be serializable)
* @returns {false|undefined} Returns false on error, undefined on success
*/
function addCustomAttribute(key, value);Usage Examples:
const newrelic = require('newrelic');
// Add user context
newrelic.addCustomAttribute('userId', user.id);
newrelic.addCustomAttribute('userPlan', 'premium');
newrelic.addCustomAttribute('isNewUser', false);
// Add business context
newrelic.addCustomAttribute('orderValue', 149.99);
newrelic.addCustomAttribute('paymentMethod', 'credit_card');
newrelic.addCustomAttribute('promoCode', 'SAVE20');Add multiple custom attributes at once to transaction and span.
/**
* Add multiple custom attributes to the current transaction and span
* @param {object} attributes - Object containing key-value pairs of attributes
*/
function addCustomAttributes(attributes);Usage Example:
newrelic.addCustomAttributes({
userId: '12345',
planType: 'enterprise',
region: 'us-east-1',
featureFlag: 'new-checkout',
experimentGroup: 'variant-b'
});Add a custom attribute to the current span only (not the transaction).
/**
* Add a custom attribute to the current span only.
* Disabled in high security mode.
* @param {string} key - The attribute name
* @param {string|number|boolean} value - The attribute value (must be serializable)
* @returns {false|undefined} Returns false on error, undefined on success
*/
function addCustomSpanAttribute(key, value);Usage Example:
// Add span-specific context (useful for detailed tracing)
newrelic.addCustomSpanAttribute('cacheHit', true);
newrelic.addCustomSpanAttribute('queryComplexity', 'high');
newrelic.addCustomSpanAttribute('retryCount', 2);Add multiple custom attributes to the current span only.
/**
* Add multiple custom attributes to the current span only
* @param {object} attributes - Object containing key-value pairs of attributes
*/
function addCustomSpanAttributes(attributes);Usage Example:
newrelic.addCustomSpanAttributes({
dbConnectionPool: 'primary',
queryType: 'SELECT',
indexUsed: true,
rowsReturned: 42
});Assign a user identifier that appears on transactions, traces, and errors.
/**
* Set the enduser.id attribute on transactions, traces, and errors
* @param {string} id - Unique user identifier
*/
function setUserID(id);Usage Example:
// Set user ID at login
app.post('/login', (req, res) => {
const user = authenticateUser(req.body);
if (user) {
newrelic.setUserID(user.id);
// This user ID will now appear on all subsequent transactions
}
});
// Clear user ID at logout
app.post('/logout', (req, res) => {
newrelic.setUserID(''); // Clear the user ID
});The following attribute names are reserved and cannot be used:
nr_flatten_leadingCustom attributes must be:
Objects, arrays, functions, and other complex types are not allowed.
When high security mode is enabled:
addCustomAttribute() returns false and logs a warningaddCustomSpanAttribute() returns false and logs a warningCustom attributes can be disabled via configuration:
api.custom_attributes_enabled: false disables all custom attribute methodsfalse when disabled// Middleware to add user context to all transactions
app.use((req, res, next) => {
if (req.user) {
newrelic.addCustomAttributes({
userId: req.user.id,
userRole: req.user.role,
accountType: req.user.accountType,
subscriptionTier: req.user.subscription?.tier
});
newrelic.setUserID(req.user.id);
}
next();
});app.post('/api/orders', (req, res) => {
newrelic.addCustomAttributes({
orderValue: req.body.total,
paymentMethod: req.body.payment.method,
shippingMethod: req.body.shipping.method,
itemCount: req.body.items.length,
hasPromoCode: !!req.body.promoCode
});
// Process order...
});function addExperimentContext(userId, experiments) {
const attributes = {};
experiments.forEach(experiment => {
attributes[`experiment_${experiment.name}`] = experiment.variant;
});
newrelic.addCustomAttributes(attributes);
}
// Usage
addExperimentContext(user.id, [
{ name: 'checkout_flow', variant: 'new_design' },
{ name: 'recommendation_algo', variant: 'ml_based' }
]);async function performDatabaseQuery(query, params) {
newrelic.addCustomSpanAttributes({
queryType: query.type,
tableCount: query.tables.length,
hasJoins: query.joins.length > 0,
paramCount: params.length
});
const result = await database.execute(query, params);
newrelic.addCustomSpanAttribute('rowsAffected', result.rowCount);
return result;
}try {
await processPayment(paymentData);
} catch (error) {
// Add context before reporting error
newrelic.addCustomAttributes({
paymentProvider: paymentData.provider,
paymentAmount: paymentData.amount,
customerTier: customer.tier
});
newrelic.noticeError(error);
throw error;
}function trackPerformanceMetrics(operation, metrics) {
newrelic.addCustomSpanAttributes({
[`${operation}_duration`]: metrics.duration,
[`${operation}_memoryUsed`]: metrics.memoryDelta,
[`${operation}_cpuTime`]: metrics.cpuTime,
[`${operation}_cacheSize`]: metrics.cacheSize
});
}
// Usage
const startTime = Date.now();
const startMemory = process.memoryUsage().heapUsed;
await performOperation();
trackPerformanceMetrics('dataProcessing', {
duration: Date.now() - startTime,
memoryDelta: process.memoryUsage().heapUsed - startMemory,
cpuTime: process.cpuUsage().user,
cacheSize: cache.size
});