CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-newrelic

Application Performance Monitoring (APM) agent for Node.js applications with transaction tracing, error tracking, custom metrics, and distributed tracing capabilities.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

url-naming-rules.mddocs/

URL Naming Rules

Configure automatic transaction naming patterns and URL filtering for better metric organization.

Capabilities

Add Naming Rule

Add URL pattern-based naming rules with optional capture groups.

/**
 * Add URL pattern-based transaction naming rule
 * @param {RegExp|string} pattern - URL pattern to match (with optional capture groups)
 * @param {string} name - Replacement name (can use $1, $2, etc. for capture groups)
 */
function addNamingRule(pattern, name);

Add Ignoring Rule

Ignore transactions matching specific URL patterns.

/**
 * Ignore transactions matching URL pattern (useful for health checks, socket.io)  
 * @param {RegExp|string} pattern - URL pattern to ignore
 */
function addIgnoringRule(pattern);

Pattern Syntax

Both functions accept either string patterns or RegExp objects:

// String patterns (converted to RegExp)
newrelic.addNamingRule('^/api/v[0-9]+/users', 'API/Users');

// RegExp objects
newrelic.addNamingRule(/^\/api\/v[0-9]+\/users/, 'API/Users');

// Case-insensitive matching
newrelic.addNamingRule(/^\/API\/Users/i, 'API/Users');

Usage Examples

Basic URL Grouping

const newrelic = require('newrelic');

// Group user endpoints by ID pattern
newrelic.addNamingRule('^/users/[0-9]+$', 'Users/Show');
newrelic.addNamingRule('^/users/[0-9]+/edit$', 'Users/Edit');
newrelic.addNamingRule('^/users/[0-9]+/delete$', 'Users/Delete');

// Group API endpoints by version and resource
newrelic.addNamingRule('^/api/v[0-9]+/users', 'API/Users');
newrelic.addNamingRule('^/api/v[0-9]+/orders', 'API/Orders');
newrelic.addNamingRule('^/api/v[0-9]+/products', 'API/Products');

Advanced Pattern Matching with Capture Groups

// Capture API version and resource type
newrelic.addNamingRule('^/api/(v[1-5])/(users|orders|products|categories)', 'API/$1/$2');
// Matches: /api/v2/users → API/v2/users
// Matches: /api/v1/orders → API/v1/orders

// Capture nested resource patterns
newrelic.addNamingRule('^/(users|customers)/[0-9]+/(orders|invoices)', '$1/$2');
// Matches: /users/123/orders → users/orders
// Matches: /customers/456/invoices → customers/invoices

// Multi-level API grouping
newrelic.addNamingRule('^/api/(v[1-9])/([a-z]+)/(create|update|delete|show)$', 'API/$1/$2/$3');
// Matches: /api/v2/users/create → API/v2/users/create
// Matches: /api/v1/products/update → API/v1/products/update

// Admin vs regular endpoints
newrelic.addNamingRule('^/(admin|api)/([a-z]+)', '$1/$2');
// Matches: /admin/users → admin/users
// Matches: /api/orders → api/orders

Query Parameter Handling

// Remove query parameters for cleaner grouping
newrelic.addNamingRule('^/search([?].*)?$', 'Search');
newrelic.addNamingRule('^/reports([?].*)?$', 'Reports');

// Group by main query parameter
newrelic.addNamingRule('^/search[?]type=([a-z]+)', 'Search/$1');
// Matches: /search?type=products → Search/products
// Matches: /search?type=users&limit=10 → Search/users

Ignoring Unwanted Transactions

// Health checks and monitoring
newrelic.addIgnoringRule('^/health$');
newrelic.addIgnoringRule('^/status$');
newrelic.addIgnoringRule('^/ping$');
newrelic.addIgnoringRule('^/metrics$');
newrelic.addIgnoringRule('^/ready$');
newrelic.addIgnoringRule('^/alive$');

// Static assets (if not handled by web server)
newrelic.addIgnoringRule('^/assets/');
newrelic.addIgnoringRule('^/static/');
newrelic.addIgnoringRule('^/public/');
newrelic.addIgnoringRule('\\.(css|js|png|jpg|gif|ico|woff|woff2)$');

// WebSocket and long-polling endpoints
newrelic.addIgnoringRule('^/socket\\.io/');
newrelic.addIgnoringRule('^/sockjs/');
newrelic.addIgnoringRule('^/ws/');
newrelic.addIgnoringRule('^/poll/');

// Development and debugging endpoints
newrelic.addIgnoringRule('^/debug/');
newrelic.addIgnoringRule('^/test/');
newrelic.addIgnoringRule('^/__webpack');

Framework-Specific Patterns

Express.js Routes

// Express parameter routes
newrelic.addNamingRule('^/users/([0-9a-f-]{36})$', 'Users/Show'); // UUID
newrelic.addNamingRule('^/posts/([0-9]+)/comments$', 'Posts/Comments');
newrelic.addNamingRule('^/categories/([^/]+)/products$', 'Categories/Products');

// Express nested routes
newrelic.addNamingRule('^/api/v[0-9]+/users/[0-9]+/profile$', 'API/Users/Profile');
newrelic.addNamingRule('^/admin/([^/]+)/([^/]+)$', 'Admin/$1/$2');

REST API Patterns

// RESTful resource patterns
newrelic.addNamingRule('^/api/([^/]+)$', 'API/$1/Index');           // GET /api/users
newrelic.addNamingRule('^/api/([^/]+)/[^/]+$', 'API/$1/Show');      // GET /api/users/123
newrelic.addNamingRule('^/api/([^/]+)/[^/]+/([^/]+)$', 'API/$1/$2'); // GET /api/users/123/posts

// HTTP method-based grouping (when using generic handlers)
newrelic.addNamingRule('^/api/([^/]+)/[0-9]+$', function(pattern, url) {
  const resource = url.match(/^\/api\/([^\/]+)/)[1];
  // This would need to be combined with method detection in practice
  return `API/${resource}/Item`;
});

GraphQL Endpoints

// Group all GraphQL requests
newrelic.addNamingRule('^/graphql$', 'GraphQL/Query');
newrelic.addNamingRule('^/api/graphql$', 'GraphQL/Query');

// Subscription endpoints
newrelic.addIgnoringRule('^/graphql/subscriptions');

Best Practices

DO: Use Meaningful Groupings

// ✅ Good - Groups similar operations
newrelic.addNamingRule('^/users/[0-9]+$', 'Users/Show');
newrelic.addNamingRule('^/users/[0-9]+/edit$', 'Users/Edit');
newrelic.addNamingRule('^/products/[0-9]+$', 'Products/Show');

// ✅ Good - Uses capture groups for categorization
newrelic.addNamingRule('^/api/(v[1-3])/(users|orders)', 'API/$1/$2');

DON'T: Create High-Cardinality Metrics

// ❌ Bad - Creates too many unique metrics
newrelic.addNamingRule('^/users/([0-9]+)$', 'Users/$1'); // Each user ID = new metric
newrelic.addNamingRule('^/sessions/([a-f0-9-]+)$', 'Sessions/$1'); // Each session = new metric

// ❌ Bad - Includes timestamps or UUIDs
newrelic.addNamingRule('^/reports/([0-9]{8})$', 'Reports/$1'); // Date-based
newrelic.addNamingRule('^/files/([a-f0-9-]{36})$', 'Files/$1'); // UUID-based

DO: Ignore Noisy Endpoints

// ✅ Good - Ignores monitoring and health checks
newrelic.addIgnoringRule('^/health');
newrelic.addIgnoringRule('^/metrics');
newrelic.addIgnoringRule('^/favicon.ico$');

// ✅ Good - Ignores development endpoints
if (process.env.NODE_ENV !== 'production') {
  newrelic.addIgnoringRule('^/debug/');
  newrelic.addIgnoringRule('^/__webpack');
}

Performance Considerations

// ✅ Good - Specific patterns are more efficient
newrelic.addNamingRule('^/api/v[1-3]/users$', 'API/Users/List');

// ❌ Less efficient - Overly broad patterns
newrelic.addNamingRule('.*users.*', 'Users'); // Matches too much

Rule Application Order

Rules are applied in the order they are added. The first matching rule wins:

// Order matters!
newrelic.addNamingRule('^/api/v1/admin/users$', 'API/Admin/Users');  // More specific first
newrelic.addNamingRule('^/api/v1/users$', 'API/Users');              // Less specific second

// If reversed, admin users would match the generic pattern

Testing Naming Rules

// You can test your patterns before deploying
function testNamingRule(pattern, testUrls) {
  const regex = new RegExp(pattern);
  testUrls.forEach(url => {
    const match = url.match(regex);
    console.log(`${url}: ${match ? 'matches' : 'no match'}`, match?.slice(1));
  });
}

testNamingRule('^/api/(v[1-3])/(users|orders)', [
  '/api/v1/users',      // matches: ['v1', 'users']
  '/api/v2/orders',     // matches: ['v2', 'orders'] 
  '/api/v1/products',   // no match
  '/api/v4/users'       // no match
]);

Common Patterns Library

E-commerce Sites

// Product catalog
newrelic.addNamingRule('^/products/[^/]+$', 'Products/Show');
newrelic.addNamingRule('^/categories/[^/]+$', 'Categories/Show');
newrelic.addNamingRule('^/search', 'Search');

// Shopping cart and checkout
newrelic.addNamingRule('^/cart$', 'Cart/Show');
newrelic.addNamingRule('^/checkout/([^/]+)$', 'Checkout/$1');

// User account
newrelic.addNamingRule('^/account/([^/]+)$', 'Account/$1');
newrelic.addNamingRule('^/orders/[0-9]+$', 'Orders/Show');

SaaS Applications

// Dashboard and admin
newrelic.addNamingRule('^/dashboard$', 'Dashboard');
newrelic.addNamingRule('^/admin/([^/]+)$', 'Admin/$1');

// Settings and configuration
newrelic.addNamingRule('^/settings/([^/]+)$', 'Settings/$1');
newrelic.addNamingRule('^/config/([^/]+)$', 'Config/$1');

// Reports and analytics
newrelic.addNamingRule('^/reports/([^/]+)$', 'Reports/$1');
newrelic.addNamingRule('^/analytics', 'Analytics');

API-First Applications

// Versioned API endpoints
newrelic.addNamingRule('^/api/(v[1-9])/(auth|token)$', 'API/$1/Auth');
newrelic.addNamingRule('^/api/(v[1-9])/([^/]+)$', 'API/$1/$2');
newrelic.addNamingRule('^/api/(v[1-9])/([^/]+)/[^/]+$', 'API/$1/$2/Item');

// Webhooks
newrelic.addNamingRule('^/webhooks/([^/]+)$', 'Webhooks/$1');

// File uploads
newrelic.addNamingRule('^/upload', 'Upload');
newrelic.addNamingRule('^/files/upload$', 'Files/Upload');

Troubleshooting

Common Issues

  1. Rules not applying: Check rule order and pattern syntax
  2. Too many metrics: Look for high-cardinality capture groups
  3. Performance impact: Overly complex regex patterns can slow request processing
  4. Escaped characters: Remember to escape special regex characters in strings

Debugging Rules

// Enable logging to see rule application
process.env.NEW_RELIC_LOG_LEVEL = 'debug';

// Test patterns in isolation
const testPattern = /^\/api\/(v[1-3])\/([^\/]+)/;
console.log('/api/v2/users'.match(testPattern)); // ['v2', 'users']

Integration with Configuration

You can also define naming rules in your newrelic.js configuration file:

// newrelic.js
exports.config = {
  rules: {
    name: [
      { pattern: '^/api/(v[1-3])/(users|orders)', name: 'API/$1/$2' },
      { pattern: '^/users/[0-9]+$', name: 'Users/Show' }
    ],
    ignore: [
      '^/health$',
      '^/status$',
      '^/socket\\.io/'
    ]
  }
  // ... other config
};

docs

aws-lambda.md

browser-monitoring.md

custom-attributes.md

custom-instrumentation.md

distributed-tracing.md

error-handling.md

index.md

llm-monitoring.md

metrics-events.md

segments-timing.md

transaction-management.md

url-naming-rules.md

utilities.md

tile.json