0
# URL Naming Rules
1
2
Configure automatic transaction naming patterns and URL filtering for better metric organization.
3
4
## Capabilities
5
6
### Add Naming Rule
7
8
Add URL pattern-based naming rules with optional capture groups.
9
10
```javascript { .api }
11
/**
12
* Add URL pattern-based transaction naming rule
13
* @param {RegExp|string} pattern - URL pattern to match (with optional capture groups)
14
* @param {string} name - Replacement name (can use $1, $2, etc. for capture groups)
15
*/
16
function addNamingRule(pattern, name);
17
```
18
19
### Add Ignoring Rule
20
21
Ignore transactions matching specific URL patterns.
22
23
```javascript { .api }
24
/**
25
* Ignore transactions matching URL pattern (useful for health checks, socket.io)
26
* @param {RegExp|string} pattern - URL pattern to ignore
27
*/
28
function addIgnoringRule(pattern);
29
```
30
31
## Pattern Syntax
32
33
Both functions accept either string patterns or RegExp objects:
34
35
```javascript
36
// String patterns (converted to RegExp)
37
newrelic.addNamingRule('^/api/v[0-9]+/users', 'API/Users');
38
39
// RegExp objects
40
newrelic.addNamingRule(/^\/api\/v[0-9]+\/users/, 'API/Users');
41
42
// Case-insensitive matching
43
newrelic.addNamingRule(/^\/API\/Users/i, 'API/Users');
44
```
45
46
## Usage Examples
47
48
### Basic URL Grouping
49
50
```javascript
51
const newrelic = require('newrelic');
52
53
// Group user endpoints by ID pattern
54
newrelic.addNamingRule('^/users/[0-9]+$', 'Users/Show');
55
newrelic.addNamingRule('^/users/[0-9]+/edit$', 'Users/Edit');
56
newrelic.addNamingRule('^/users/[0-9]+/delete$', 'Users/Delete');
57
58
// Group API endpoints by version and resource
59
newrelic.addNamingRule('^/api/v[0-9]+/users', 'API/Users');
60
newrelic.addNamingRule('^/api/v[0-9]+/orders', 'API/Orders');
61
newrelic.addNamingRule('^/api/v[0-9]+/products', 'API/Products');
62
```
63
64
### Advanced Pattern Matching with Capture Groups
65
66
```javascript
67
// Capture API version and resource type
68
newrelic.addNamingRule('^/api/(v[1-5])/(users|orders|products|categories)', 'API/$1/$2');
69
// Matches: /api/v2/users → API/v2/users
70
// Matches: /api/v1/orders → API/v1/orders
71
72
// Capture nested resource patterns
73
newrelic.addNamingRule('^/(users|customers)/[0-9]+/(orders|invoices)', '$1/$2');
74
// Matches: /users/123/orders → users/orders
75
// Matches: /customers/456/invoices → customers/invoices
76
77
// Multi-level API grouping
78
newrelic.addNamingRule('^/api/(v[1-9])/([a-z]+)/(create|update|delete|show)$', 'API/$1/$2/$3');
79
// Matches: /api/v2/users/create → API/v2/users/create
80
// Matches: /api/v1/products/update → API/v1/products/update
81
82
// Admin vs regular endpoints
83
newrelic.addNamingRule('^/(admin|api)/([a-z]+)', '$1/$2');
84
// Matches: /admin/users → admin/users
85
// Matches: /api/orders → api/orders
86
```
87
88
### Query Parameter Handling
89
90
```javascript
91
// Remove query parameters for cleaner grouping
92
newrelic.addNamingRule('^/search([?].*)?$', 'Search');
93
newrelic.addNamingRule('^/reports([?].*)?$', 'Reports');
94
95
// Group by main query parameter
96
newrelic.addNamingRule('^/search[?]type=([a-z]+)', 'Search/$1');
97
// Matches: /search?type=products → Search/products
98
// Matches: /search?type=users&limit=10 → Search/users
99
```
100
101
### Ignoring Unwanted Transactions
102
103
```javascript
104
// Health checks and monitoring
105
newrelic.addIgnoringRule('^/health$');
106
newrelic.addIgnoringRule('^/status$');
107
newrelic.addIgnoringRule('^/ping$');
108
newrelic.addIgnoringRule('^/metrics$');
109
newrelic.addIgnoringRule('^/ready$');
110
newrelic.addIgnoringRule('^/alive$');
111
112
// Static assets (if not handled by web server)
113
newrelic.addIgnoringRule('^/assets/');
114
newrelic.addIgnoringRule('^/static/');
115
newrelic.addIgnoringRule('^/public/');
116
newrelic.addIgnoringRule('\\.(css|js|png|jpg|gif|ico|woff|woff2)$');
117
118
// WebSocket and long-polling endpoints
119
newrelic.addIgnoringRule('^/socket\\.io/');
120
newrelic.addIgnoringRule('^/sockjs/');
121
newrelic.addIgnoringRule('^/ws/');
122
newrelic.addIgnoringRule('^/poll/');
123
124
// Development and debugging endpoints
125
newrelic.addIgnoringRule('^/debug/');
126
newrelic.addIgnoringRule('^/test/');
127
newrelic.addIgnoringRule('^/__webpack');
128
```
129
130
### Framework-Specific Patterns
131
132
#### Express.js Routes
133
134
```javascript
135
// Express parameter routes
136
newrelic.addNamingRule('^/users/([0-9a-f-]{36})$', 'Users/Show'); // UUID
137
newrelic.addNamingRule('^/posts/([0-9]+)/comments$', 'Posts/Comments');
138
newrelic.addNamingRule('^/categories/([^/]+)/products$', 'Categories/Products');
139
140
// Express nested routes
141
newrelic.addNamingRule('^/api/v[0-9]+/users/[0-9]+/profile$', 'API/Users/Profile');
142
newrelic.addNamingRule('^/admin/([^/]+)/([^/]+)$', 'Admin/$1/$2');
143
```
144
145
#### REST API Patterns
146
147
```javascript
148
// RESTful resource patterns
149
newrelic.addNamingRule('^/api/([^/]+)$', 'API/$1/Index'); // GET /api/users
150
newrelic.addNamingRule('^/api/([^/]+)/[^/]+$', 'API/$1/Show'); // GET /api/users/123
151
newrelic.addNamingRule('^/api/([^/]+)/[^/]+/([^/]+)$', 'API/$1/$2'); // GET /api/users/123/posts
152
153
// HTTP method-based grouping (when using generic handlers)
154
newrelic.addNamingRule('^/api/([^/]+)/[0-9]+$', function(pattern, url) {
155
const resource = url.match(/^\/api\/([^\/]+)/)[1];
156
// This would need to be combined with method detection in practice
157
return `API/${resource}/Item`;
158
});
159
```
160
161
#### GraphQL Endpoints
162
163
```javascript
164
// Group all GraphQL requests
165
newrelic.addNamingRule('^/graphql$', 'GraphQL/Query');
166
newrelic.addNamingRule('^/api/graphql$', 'GraphQL/Query');
167
168
// Subscription endpoints
169
newrelic.addIgnoringRule('^/graphql/subscriptions');
170
```
171
172
## Best Practices
173
174
### DO: Use Meaningful Groupings
175
176
```javascript
177
// ✅ Good - Groups similar operations
178
newrelic.addNamingRule('^/users/[0-9]+$', 'Users/Show');
179
newrelic.addNamingRule('^/users/[0-9]+/edit$', 'Users/Edit');
180
newrelic.addNamingRule('^/products/[0-9]+$', 'Products/Show');
181
182
// ✅ Good - Uses capture groups for categorization
183
newrelic.addNamingRule('^/api/(v[1-3])/(users|orders)', 'API/$1/$2');
184
```
185
186
### DON'T: Create High-Cardinality Metrics
187
188
```javascript
189
// ❌ Bad - Creates too many unique metrics
190
newrelic.addNamingRule('^/users/([0-9]+)$', 'Users/$1'); // Each user ID = new metric
191
newrelic.addNamingRule('^/sessions/([a-f0-9-]+)$', 'Sessions/$1'); // Each session = new metric
192
193
// ❌ Bad - Includes timestamps or UUIDs
194
newrelic.addNamingRule('^/reports/([0-9]{8})$', 'Reports/$1'); // Date-based
195
newrelic.addNamingRule('^/files/([a-f0-9-]{36})$', 'Files/$1'); // UUID-based
196
```
197
198
### DO: Ignore Noisy Endpoints
199
200
```javascript
201
// ✅ Good - Ignores monitoring and health checks
202
newrelic.addIgnoringRule('^/health');
203
newrelic.addIgnoringRule('^/metrics');
204
newrelic.addIgnoringRule('^/favicon.ico$');
205
206
// ✅ Good - Ignores development endpoints
207
if (process.env.NODE_ENV !== 'production') {
208
newrelic.addIgnoringRule('^/debug/');
209
newrelic.addIgnoringRule('^/__webpack');
210
}
211
```
212
213
### Performance Considerations
214
215
```javascript
216
// ✅ Good - Specific patterns are more efficient
217
newrelic.addNamingRule('^/api/v[1-3]/users$', 'API/Users/List');
218
219
// ❌ Less efficient - Overly broad patterns
220
newrelic.addNamingRule('.*users.*', 'Users'); // Matches too much
221
```
222
223
## Rule Application Order
224
225
Rules are applied in the order they are added. The first matching rule wins:
226
227
```javascript
228
// Order matters!
229
newrelic.addNamingRule('^/api/v1/admin/users$', 'API/Admin/Users'); // More specific first
230
newrelic.addNamingRule('^/api/v1/users$', 'API/Users'); // Less specific second
231
232
// If reversed, admin users would match the generic pattern
233
```
234
235
## Testing Naming Rules
236
237
```javascript
238
// You can test your patterns before deploying
239
function testNamingRule(pattern, testUrls) {
240
const regex = new RegExp(pattern);
241
testUrls.forEach(url => {
242
const match = url.match(regex);
243
console.log(`${url}: ${match ? 'matches' : 'no match'}`, match?.slice(1));
244
});
245
}
246
247
testNamingRule('^/api/(v[1-3])/(users|orders)', [
248
'/api/v1/users', // matches: ['v1', 'users']
249
'/api/v2/orders', // matches: ['v2', 'orders']
250
'/api/v1/products', // no match
251
'/api/v4/users' // no match
252
]);
253
```
254
255
## Common Patterns Library
256
257
### E-commerce Sites
258
259
```javascript
260
// Product catalog
261
newrelic.addNamingRule('^/products/[^/]+$', 'Products/Show');
262
newrelic.addNamingRule('^/categories/[^/]+$', 'Categories/Show');
263
newrelic.addNamingRule('^/search', 'Search');
264
265
// Shopping cart and checkout
266
newrelic.addNamingRule('^/cart$', 'Cart/Show');
267
newrelic.addNamingRule('^/checkout/([^/]+)$', 'Checkout/$1');
268
269
// User account
270
newrelic.addNamingRule('^/account/([^/]+)$', 'Account/$1');
271
newrelic.addNamingRule('^/orders/[0-9]+$', 'Orders/Show');
272
```
273
274
### SaaS Applications
275
276
```javascript
277
// Dashboard and admin
278
newrelic.addNamingRule('^/dashboard$', 'Dashboard');
279
newrelic.addNamingRule('^/admin/([^/]+)$', 'Admin/$1');
280
281
// Settings and configuration
282
newrelic.addNamingRule('^/settings/([^/]+)$', 'Settings/$1');
283
newrelic.addNamingRule('^/config/([^/]+)$', 'Config/$1');
284
285
// Reports and analytics
286
newrelic.addNamingRule('^/reports/([^/]+)$', 'Reports/$1');
287
newrelic.addNamingRule('^/analytics', 'Analytics');
288
```
289
290
### API-First Applications
291
292
```javascript
293
// Versioned API endpoints
294
newrelic.addNamingRule('^/api/(v[1-9])/(auth|token)$', 'API/$1/Auth');
295
newrelic.addNamingRule('^/api/(v[1-9])/([^/]+)$', 'API/$1/$2');
296
newrelic.addNamingRule('^/api/(v[1-9])/([^/]+)/[^/]+$', 'API/$1/$2/Item');
297
298
// Webhooks
299
newrelic.addNamingRule('^/webhooks/([^/]+)$', 'Webhooks/$1');
300
301
// File uploads
302
newrelic.addNamingRule('^/upload', 'Upload');
303
newrelic.addNamingRule('^/files/upload$', 'Files/Upload');
304
```
305
306
## Troubleshooting
307
308
### Common Issues
309
310
1. **Rules not applying**: Check rule order and pattern syntax
311
2. **Too many metrics**: Look for high-cardinality capture groups
312
3. **Performance impact**: Overly complex regex patterns can slow request processing
313
4. **Escaped characters**: Remember to escape special regex characters in strings
314
315
### Debugging Rules
316
317
```javascript
318
// Enable logging to see rule application
319
process.env.NEW_RELIC_LOG_LEVEL = 'debug';
320
321
// Test patterns in isolation
322
const testPattern = /^\/api\/(v[1-3])\/([^\/]+)/;
323
console.log('/api/v2/users'.match(testPattern)); // ['v2', 'users']
324
```
325
326
## Integration with Configuration
327
328
You can also define naming rules in your `newrelic.js` configuration file:
329
330
```javascript
331
// newrelic.js
332
exports.config = {
333
rules: {
334
name: [
335
{ pattern: '^/api/(v[1-3])/(users|orders)', name: 'API/$1/$2' },
336
{ pattern: '^/users/[0-9]+$', name: 'Users/Show' }
337
],
338
ignore: [
339
'^/health$',
340
'^/status$',
341
'^/socket\\.io/'
342
]
343
}
344
// ... other config
345
};
346
```