0
# Auto-Registration
1
2
The auto-registration system provides centralized management for loading, configuring, and lifecycle control of multiple instrumentations with provider integration.
3
4
## Capabilities
5
6
### registerInstrumentations Function
7
8
Main registration function that activates instrumentations and configures them with OpenTelemetry providers.
9
10
```typescript { .api }
11
/**
12
* Register instrumentations and plugins with providers
13
* @param options Configuration options for registration
14
* @returns Function to unregister all instrumentations
15
*/
16
function registerInstrumentations(options: AutoLoaderOptions): () => void;
17
```
18
19
**Usage Example:**
20
21
```typescript
22
import { registerInstrumentations } from "@opentelemetry/instrumentation";
23
import { HttpInstrumentation } from "@opentelemetry/instrumentation-http";
24
import { ExpressInstrumentation } from "@opentelemetry/instrumentation-express";
25
import { trace, metrics } from "@opentelemetry/api";
26
import { logs } from "@opentelemetry/api-logs";
27
28
// Basic registration
29
const unregister = registerInstrumentations({
30
instrumentations: [
31
new HttpInstrumentation(),
32
new ExpressInstrumentation()
33
]
34
});
35
36
// Registration with custom providers
37
const unregisterWithProviders = registerInstrumentations({
38
instrumentations: [
39
new HttpInstrumentation({
40
requestHook: (span, request) => {
41
span.setAttributes({ 'http.custom': 'value' });
42
}
43
})
44
],
45
tracerProvider: trace.getTracerProvider(),
46
meterProvider: metrics.getMeterProvider(),
47
loggerProvider: logs.getLoggerProvider()
48
});
49
50
// Unregister when done
51
process.on('SIGTERM', () => {
52
unregister();
53
unregisterWithProviders();
54
});
55
```
56
57
### AutoLoaderOptions Interface
58
59
Configuration options for the registration system.
60
61
```typescript { .api }
62
/**
63
* Options for registerInstrumentations function
64
*/
65
interface AutoLoaderOptions {
66
/** Array of instrumentations to register (can be nested arrays) */
67
instrumentations?: (Instrumentation | Instrumentation[])[];
68
/** Tracer provider to use (defaults to global provider) */
69
tracerProvider?: TracerProvider;
70
/** Meter provider to use (defaults to global provider) */
71
meterProvider?: MeterProvider;
72
/** Logger provider to use (defaults to global provider) */
73
loggerProvider?: LoggerProvider;
74
}
75
```
76
77
**Usage Examples:**
78
79
```typescript
80
// Minimal registration
81
registerInstrumentations({
82
instrumentations: [new HttpInstrumentation()]
83
});
84
85
// Registration with nested arrays
86
registerInstrumentations({
87
instrumentations: [
88
[new HttpInstrumentation(), new ExpressInstrumentation()],
89
new RedisInstrumentation(),
90
[new DatabaseInstrumentation(), new GraphQLInstrumentation()]
91
]
92
});
93
94
// Registration with all providers
95
registerInstrumentations({
96
instrumentations: [new HttpInstrumentation()],
97
tracerProvider: customTracerProvider,
98
meterProvider: customMeterProvider,
99
loggerProvider: customLoggerProvider
100
});
101
102
// Using global providers (default behavior)
103
registerInstrumentations({
104
instrumentations: [new HttpInstrumentation()]
105
// Providers will be obtained from:
106
// - trace.getTracerProvider()
107
// - metrics.getMeterProvider()
108
// - logs.getLoggerProvider()
109
});
110
```
111
112
### AutoLoaderResult Interface
113
114
Result interface for auto-loader operations (used internally).
115
116
```typescript { .api }
117
/**
118
* Result of auto-loader operations
119
*/
120
interface AutoLoaderResult {
121
/** Flattened array of all instrumentations */
122
instrumentations: Instrumentation[];
123
}
124
```
125
126
### Lifecycle Management
127
128
Complete example showing instrumentation lifecycle management in an application.
129
130
**Usage Example:**
131
132
```typescript
133
import { registerInstrumentations } from "@opentelemetry/instrumentation";
134
import { NodeSDK } from "@opentelemetry/auto-instrumentations-node";
135
136
class InstrumentationManager {
137
private unregisterFn?: () => void;
138
139
async initialize() {
140
// Configure and register instrumentations
141
this.unregisterFn = registerInstrumentations({
142
instrumentations: [
143
new HttpInstrumentation({
144
enabled: true,
145
requestHook: this.onHttpRequest.bind(this),
146
responseHook: this.onHttpResponse.bind(this)
147
}),
148
new ExpressInstrumentation({
149
enabled: true,
150
ignoreLayers: [
151
(name, info) => name === 'router' && info.request.url?.includes('/health')
152
]
153
})
154
]
155
});
156
157
console.log('Instrumentations registered');
158
}
159
160
async shutdown() {
161
if (this.unregisterFn) {
162
this.unregisterFn();
163
console.log('Instrumentations unregistered');
164
}
165
}
166
167
private onHttpRequest(span: Span, request: IncomingMessage) {
168
// Add custom attributes
169
span.setAttributes({
170
'http.request.custom': 'value',
171
'http.user_agent': request.headers['user-agent'] || 'unknown'
172
});
173
}
174
175
private onHttpResponse(span: Span, response: ServerResponse) {
176
// Add response attributes
177
span.setAttributes({
178
'http.response.custom': 'value'
179
});
180
}
181
}
182
183
// Application startup
184
const instrumentationManager = new InstrumentationManager();
185
await instrumentationManager.initialize();
186
187
// Graceful shutdown
188
process.on('SIGTERM', async () => {
189
await instrumentationManager.shutdown();
190
process.exit(0);
191
});
192
```
193
194
### Dynamic Registration
195
196
Advanced patterns for conditional and dynamic instrumentation registration.
197
198
**Usage Example:**
199
200
```typescript
201
import { registerInstrumentations } from "@opentelemetry/instrumentation";
202
203
class DynamicInstrumentationLoader {
204
private registrations: Map<string, () => void> = new Map();
205
206
registerByEnvironment() {
207
const environment = process.env.NODE_ENV || 'development';
208
209
// Base instrumentations for all environments
210
const baseInstrumentations = [
211
new HttpInstrumentation(),
212
new FsInstrumentation()
213
];
214
215
// Environment-specific instrumentations
216
const envInstrumentations: Instrumentation[] = [];
217
218
if (environment === 'production') {
219
envInstrumentations.push(
220
new RedisInstrumentation(),
221
new DatabaseInstrumentation()
222
);
223
}
224
225
if (environment === 'development') {
226
envInstrumentations.push(
227
new DebugInstrumentation({ verbose: true })
228
);
229
}
230
231
const unregister = registerInstrumentations({
232
instrumentations: [...baseInstrumentations, ...envInstrumentations]
233
});
234
235
this.registrations.set(environment, unregister);
236
return unregister;
237
}
238
239
registerConditionally() {
240
const instrumentations: Instrumentation[] = [];
241
242
// Register based on available modules
243
try {
244
require.resolve('express');
245
instrumentations.push(new ExpressInstrumentation());
246
} catch {
247
// Express not available
248
}
249
250
try {
251
require.resolve('redis');
252
instrumentations.push(new RedisInstrumentation());
253
} catch {
254
// Redis not available
255
}
256
257
if (instrumentations.length > 0) {
258
const unregister = registerInstrumentations({ instrumentations });
259
this.registrations.set('conditional', unregister);
260
return unregister;
261
}
262
}
263
264
unregisterAll() {
265
for (const [key, unregister] of this.registrations.entries()) {
266
unregister();
267
console.log(`Unregistered instrumentations for: ${key}`);
268
}
269
this.registrations.clear();
270
}
271
}
272
```
273
274
### Error Handling and Resilience
275
276
Best practices for handling registration failures and instrumentation errors.
277
278
**Usage Example:**
279
280
```typescript
281
import { registerInstrumentations } from "@opentelemetry/instrumentation";
282
import { diag, DiagConsoleLogger, DiagLogLevel } from "@opentelemetry/api";
283
284
// Enable diagnostic logging
285
diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG);
286
287
function safeRegisterInstrumentations(instrumentations: Instrumentation[]) {
288
// Filter out any failed instrumentations
289
const validInstrumentations = instrumentations.filter(instrumentation => {
290
try {
291
// Basic validation
292
if (!instrumentation.instrumentationName || !instrumentation.instrumentationVersion) {
293
console.warn(`Invalid instrumentation: ${instrumentation.constructor.name}`);
294
return false;
295
}
296
return true;
297
} catch (error) {
298
console.error(`Failed to validate instrumentation: ${error}`);
299
return false;
300
}
301
});
302
303
if (validInstrumentations.length === 0) {
304
console.warn('No valid instrumentations to register');
305
return () => {}; // No-op unregister function
306
}
307
308
try {
309
const unregister = registerInstrumentations({
310
instrumentations: validInstrumentations
311
});
312
313
console.log(`Successfully registered ${validInstrumentations.length} instrumentations`);
314
return unregister;
315
} catch (error) {
316
console.error('Failed to register instrumentations:', error);
317
return () => {}; // No-op unregister function
318
}
319
}
320
321
// Usage with error handling
322
const instrumentations = [
323
new HttpInstrumentation(),
324
new ExpressInstrumentation(),
325
// This might fail if Redis is not available
326
new RedisInstrumentation()
327
];
328
329
const unregister = safeRegisterInstrumentations(instrumentations);
330
```