@adonisjs/otel 1.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,329 @@
1
+ import { getNodeAutoInstrumentations, } from '@opentelemetry/auto-instrumentations-node';
2
+ import { resourceFromAttributes } from '@opentelemetry/resources';
3
+ import { NodeSDK } from '@opentelemetry/sdk-node';
4
+ import { ConsoleSpanExporter, ParentBasedSampler, SimpleSpanProcessor, TraceIdRatioBasedSampler, } from '@opentelemetry/sdk-trace-base';
5
+ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
6
+ import { ATTR_DEPLOYMENT_ENVIRONMENT_NAME, ATTR_SERVICE_INSTANCE_ID, } from '@opentelemetry/semantic-conventions/incubating';
7
+ import { HttpContext } from '@adonisjs/core/http';
8
+ /**
9
+ * OpenTelemetry SDK manager for AdonisJS.
10
+ *
11
+ * Provides sensible defaults and easy configuration for OpenTelemetry
12
+ * while allowing full customization when needed.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * import { OtelManager } from '@adonisjs/otel'
17
+ * import config from '#config/otel'
18
+ *
19
+ * const manager = OtelManager.create(config)
20
+ * manager?.start()
21
+ *
22
+ * // Later, on shutdown
23
+ * await manager?.shutdown()
24
+ * ```
25
+ */
26
+ export class OtelManager {
27
+ static DEFAULT_IGNORED_URLS = [
28
+ '/health',
29
+ '/healthz',
30
+ '/internal/healthz',
31
+ '/ready',
32
+ '/readiness',
33
+ '/metrics',
34
+ '/internal/metrics',
35
+ '/favicon.ico',
36
+ ];
37
+ static #instance = null;
38
+ sdk;
39
+ serviceName;
40
+ serviceVersion;
41
+ environment;
42
+ #config;
43
+ constructor(config) {
44
+ this.#config = config;
45
+ this.serviceName = this.#resolveServiceName();
46
+ this.serviceVersion = this.#resolveServiceVersion();
47
+ this.environment = this.#resolveEnvironment();
48
+ this.sdk = this.#createSdk();
49
+ }
50
+ /**
51
+ * Resolve the service name from config or environment
52
+ */
53
+ #resolveServiceName() {
54
+ return (this.#config.serviceName ||
55
+ process.env.OTEL_SERVICE_NAME ||
56
+ process.env.APP_NAME ||
57
+ 'unknown_service');
58
+ }
59
+ /**
60
+ * Resolve the service version from config or environment
61
+ */
62
+ #resolveServiceVersion() {
63
+ return this.#config.serviceVersion || process.env.APP_VERSION || '0.0.0';
64
+ }
65
+ /**
66
+ * Resolve the environment from config or environment
67
+ */
68
+ #resolveEnvironment() {
69
+ return this.#config.environment || process.env.APP_ENV || 'development';
70
+ }
71
+ /**
72
+ * Build the OpenTelemetry Resource with service metadata
73
+ */
74
+ #buildResource() {
75
+ return resourceFromAttributes({
76
+ [ATTR_SERVICE_NAME]: this.serviceName,
77
+ [ATTR_SERVICE_VERSION]: this.serviceVersion,
78
+ [ATTR_DEPLOYMENT_ENVIRONMENT_NAME]: this.environment,
79
+ [ATTR_SERVICE_INSTANCE_ID]: process.env.HOSTNAME || crypto.randomUUID(),
80
+ ...this.#config.resourceAttributes,
81
+ });
82
+ }
83
+ /**
84
+ * Get the resolved list of ignored URLs from HTTP instrumentation config
85
+ */
86
+ #getIgnoredUrls(httpConfig) {
87
+ const userUrls = httpConfig?.ignoredUrls || [];
88
+ const mergeWithDefaults = httpConfig?.mergeIgnoredUrls !== false;
89
+ if (!mergeWithDefaults) {
90
+ return userUrls;
91
+ }
92
+ return [...OtelManager.DEFAULT_IGNORED_URLS, ...userUrls];
93
+ }
94
+ /**
95
+ * Check if a URL should be ignored based on the ignored URLs list.
96
+ * Supports exact matches and wildcard patterns (e.g., '/internal/*')
97
+ */
98
+ #shouldIgnoreUrl(url, ignoredUrls) {
99
+ if (!url)
100
+ return false;
101
+ return ignoredUrls.some((pattern) => {
102
+ if (pattern.endsWith('/*')) {
103
+ const prefix = pattern.slice(0, -1);
104
+ return url.startsWith(prefix);
105
+ }
106
+ return url.startsWith(pattern);
107
+ });
108
+ }
109
+ /**
110
+ * Check if a value is an Instrumentation instance
111
+ */
112
+ #isInstrumentationInstance(value) {
113
+ return (typeof value === 'object' &&
114
+ value !== null &&
115
+ 'instrumentationName' in value &&
116
+ typeof value.instrumentationName === 'string');
117
+ }
118
+ /**
119
+ * Check if a value is a "disabled" config
120
+ */
121
+ #isDisabledConfig(value) {
122
+ return (typeof value === 'object' &&
123
+ value !== null &&
124
+ 'enabled' in value &&
125
+ value.enabled === false);
126
+ }
127
+ /**
128
+ * Process user instrumentation configuration
129
+ */
130
+ #processUserInstrumentations(userConfig) {
131
+ const customInstances = [];
132
+ const disabledSet = new Set();
133
+ const configOverrides = {};
134
+ let httpConfig;
135
+ let pinoConfig;
136
+ if (!userConfig)
137
+ return { customInstances, disabledSet, configOverrides, httpConfig, pinoConfig };
138
+ for (const [name, value] of Object.entries(userConfig)) {
139
+ if (this.#isDisabledConfig(value)) {
140
+ disabledSet.add(name);
141
+ continue;
142
+ }
143
+ if (this.#isInstrumentationInstance(value)) {
144
+ customInstances.push(value);
145
+ disabledSet.add(name);
146
+ continue;
147
+ }
148
+ if (name === '@opentelemetry/instrumentation-http') {
149
+ httpConfig = value;
150
+ continue;
151
+ }
152
+ if (name === '@opentelemetry/instrumentation-pino') {
153
+ pinoConfig = value;
154
+ continue;
155
+ }
156
+ configOverrides[name] = value;
157
+ }
158
+ return { customInstances, disabledSet, configOverrides, httpConfig, pinoConfig };
159
+ }
160
+ /**
161
+ * Build the base instrumentation configuration
162
+ */
163
+ #buildBaseInstrumentationConfig() {
164
+ return {
165
+ '@opentelemetry/instrumentation-net': { enabled: false },
166
+ '@opentelemetry/instrumentation-dns': { enabled: false },
167
+ '@opentelemetry/instrumentation-socket.io': { enabled: false },
168
+ '@opentelemetry/instrumentation-pg': { enabled: false },
169
+ '@opentelemetry/instrumentation-mysql': { enabled: false },
170
+ '@opentelemetry/instrumentation-mysql2': { enabled: false },
171
+ };
172
+ }
173
+ /**
174
+ * Build instrumentations from user config merged with defaults
175
+ */
176
+ #buildInstrumentations() {
177
+ const { customInstances, disabledSet, configOverrides, httpConfig, pinoConfig } = this.#processUserInstrumentations(this.#config.instrumentations);
178
+ const mergedConfig = this.#buildBaseInstrumentationConfig();
179
+ for (const [name, config] of Object.entries(configOverrides)) {
180
+ mergedConfig[name] = {
181
+ ...mergedConfig[name],
182
+ ...config,
183
+ };
184
+ }
185
+ for (const name of disabledSet) {
186
+ mergedConfig[name] = { enabled: false };
187
+ }
188
+ this.#applyHttpInstrumentationConfig(mergedConfig, httpConfig);
189
+ this.#applyPinoInstrumentationConfig(mergedConfig, pinoConfig);
190
+ const autoInstrumentations = getNodeAutoInstrumentations(mergedConfig);
191
+ return [...autoInstrumentations, ...customInstances];
192
+ }
193
+ /**
194
+ * Apply HTTP instrumentation configuration with smart merging of ignoreIncomingRequestHook
195
+ */
196
+ #applyHttpInstrumentationConfig(mergedConfig, userHttpConfig) {
197
+ const httpKey = '@opentelemetry/instrumentation-http';
198
+ const currentConfig = mergedConfig[httpKey];
199
+ if (currentConfig && 'enabled' in currentConfig && currentConfig.enabled === false) {
200
+ return;
201
+ }
202
+ const ignoredUrls = this.#getIgnoredUrls(userHttpConfig);
203
+ const userIgnoreHook = userHttpConfig?.ignoreIncomingRequestHook;
204
+ mergedConfig[httpKey] = {
205
+ ...currentConfig,
206
+ ...userHttpConfig,
207
+ ignoreIncomingRequestHook: (req) => {
208
+ if (this.#shouldIgnoreUrl(req.url, ignoredUrls))
209
+ return true;
210
+ if (userIgnoreHook)
211
+ return userIgnoreHook(req);
212
+ return false;
213
+ },
214
+ };
215
+ }
216
+ /**
217
+ * Apply Pino instrumentation configuration with smart merging of logHook
218
+ */
219
+ #applyPinoInstrumentationConfig(mergedConfig, userPinoConfig) {
220
+ const pinoKey = '@opentelemetry/instrumentation-pino';
221
+ const currentConfig = mergedConfig[pinoKey];
222
+ if (currentConfig && 'enabled' in currentConfig && currentConfig.enabled === false) {
223
+ return;
224
+ }
225
+ const userLogHook = userPinoConfig?.logHook;
226
+ const internalLogHook = (span) => {
227
+ const httpContext = HttpContext.get();
228
+ span.setAttribute('http.route', httpContext?.route?.pattern || '');
229
+ };
230
+ mergedConfig[pinoKey] = {
231
+ ...currentConfig,
232
+ ...userPinoConfig,
233
+ logHook: (span, record) => {
234
+ internalLogHook(span);
235
+ if (userLogHook)
236
+ userLogHook(span, record);
237
+ },
238
+ };
239
+ }
240
+ /**
241
+ * Build sampler from samplingRatio if no explicit sampler is provided
242
+ */
243
+ #buildSampler() {
244
+ if (this.#config.sampler)
245
+ return this.#config.sampler;
246
+ if (this.#config.samplingRatio !== undefined) {
247
+ const ratio = Math.max(0, Math.min(1, this.#config.samplingRatio));
248
+ return new ParentBasedSampler({ root: new TraceIdRatioBasedSampler(ratio) });
249
+ }
250
+ return undefined;
251
+ }
252
+ /**
253
+ * Build span processors, including debug console exporter if enabled
254
+ */
255
+ #buildSpanProcessors() {
256
+ const processors = this.#config.spanProcessors ? [...this.#config.spanProcessors] : [];
257
+ if (this.#config.debug)
258
+ processors.push(new SimpleSpanProcessor(new ConsoleSpanExporter()));
259
+ return processors.length > 0 ? processors : undefined;
260
+ }
261
+ /**
262
+ * Create the NodeSDK instance with all configuration
263
+ */
264
+ #createSdk() {
265
+ const resource = this.#buildResource();
266
+ const instrumentations = this.#buildInstrumentations();
267
+ const sampler = this.#buildSampler();
268
+ const spanProcessors = this.#buildSpanProcessors();
269
+ return new NodeSDK({
270
+ ...this.#config,
271
+ resource,
272
+ serviceName: this.serviceName,
273
+ instrumentations,
274
+ ...(sampler && { sampler }),
275
+ ...(spanProcessors && { spanProcessors }),
276
+ });
277
+ }
278
+ /**
279
+ * Start the OpenTelemetry SDK
280
+ */
281
+ start() {
282
+ this.sdk.start();
283
+ }
284
+ /**
285
+ * Gracefully shutdown the OpenTelemetry SDK
286
+ */
287
+ async shutdown() {
288
+ await this.sdk.shutdown();
289
+ }
290
+ /**
291
+ * Check if OpenTelemetry should be enabled based on config.
292
+ * Defaults to false when NODE_ENV === 'test'.
293
+ */
294
+ static isEnabled(config) {
295
+ if (config.enabled !== undefined)
296
+ return config.enabled;
297
+ return process.env.NODE_ENV !== 'test';
298
+ }
299
+ /**
300
+ * Create and configure the OpenTelemetry SDK manager.
301
+ *
302
+ * Returns null if OpenTelemetry is disabled.
303
+ *
304
+ * @example
305
+ * ```ts
306
+ * import { OtelManager } from '@adonisjs/otel'
307
+ * import config from '#config/otel'
308
+ *
309
+ * const manager = OtelManager.create(config)
310
+ * manager?.start()
311
+ *
312
+ * // Later, on shutdown
313
+ * await manager?.shutdown()
314
+ * ```
315
+ */
316
+ static create(config) {
317
+ if (!OtelManager.isEnabled(config))
318
+ return null;
319
+ OtelManager.#instance = new OtelManager(config);
320
+ return OtelManager.#instance;
321
+ }
322
+ /**
323
+ * Get the global OtelManager instance.
324
+ * Returns null if OpenTelemetry is disabled or not yet initialized.
325
+ */
326
+ static getInstance() {
327
+ return OtelManager.#instance;
328
+ }
329
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * OpenTelemetry initialization file.
3
+ *
4
+ * This file should be loaded BEFORE your application starts
5
+ * to enable auto-instrumentation:
6
+ *
7
+ * ```ts
8
+ * // bin/otel.ts
9
+ * import { init } from '@adonisjs/otel/init'
10
+ * await init(import.meta.dirname)
11
+ * ```
12
+ *
13
+ * Then import it first in bin/server.ts:
14
+ * ```ts
15
+ * import './otel.js'
16
+ * ```
17
+ */
18
+ export declare function init(dirname: string): Promise<void>;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * OpenTelemetry initialization file.
3
+ *
4
+ * This file should be loaded BEFORE your application starts
5
+ * to enable auto-instrumentation:
6
+ *
7
+ * ```ts
8
+ * // bin/otel.ts
9
+ * import { init } from '@adonisjs/otel/init'
10
+ * await init(import.meta.dirname)
11
+ * ```
12
+ *
13
+ * Then import it first in bin/server.ts:
14
+ * ```ts
15
+ * import './otel.js'
16
+ * ```
17
+ */
18
+ import { createAddHookMessageChannel } from 'import-in-the-middle';
19
+ import { register } from 'node:module';
20
+ import { join } from 'node:path';
21
+ export async function init(dirname) {
22
+ // Setup import-in-the-middle hooks for auto-instrumentation
23
+ const { registerOptions, waitForAllMessagesAcknowledged } = createAddHookMessageChannel();
24
+ register('import-in-the-middle/hook.mjs', import.meta.url, registerOptions);
25
+ // Import SDK functions after hooks are registered
26
+ const { OtelManager } = await import('./otel.js');
27
+ const configPath = join(dirname, '../config/otel.ts');
28
+ const config = await import(configPath).then((mod) => mod.default || mod);
29
+ if (!config)
30
+ throw new Error(`Otel configuration not found at ${configPath}`);
31
+ // Check if OTEL is enabled
32
+ if (!OtelManager.isEnabled(config))
33
+ return;
34
+ const manager = OtelManager.create(config);
35
+ manager?.start();
36
+ await waitForAllMessagesAcknowledged();
37
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Options for span decorators
3
+ */
4
+ export interface SpanOptions {
5
+ /**
6
+ * Custom span name. Defaults to `ClassName.methodName`
7
+ */
8
+ name?: string;
9
+ /**
10
+ * Additional attributes to add to the span
11
+ */
12
+ attributes?: Record<string, string | number | boolean>;
13
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,155 @@
1
+ import type { NodeSDKConfiguration } from '@opentelemetry/sdk-node';
2
+ import type { HttpContext } from '@adonisjs/core/http';
3
+ export type { InstrumentationValue, CustomInstrumentationValue, HttpInstrumentationConfig, PinoInstrumentationConfig, InstrumentationsConfig, } from './instrumentations.js';
4
+ export type { SpanOptions } from './decorators.js';
5
+ export { hiddenFields, type HiddenField, type OtelLoggingPresetOptions } from './logging.js';
6
+ import type { InstrumentationsConfig } from './instrumentations.js';
7
+ /**
8
+ * Configuration for @adonisjs/otel
9
+ *
10
+ * Extends NodeSDKConfiguration with simplified options and good defaults.
11
+ * All options are optional - the package works out of the box.
12
+ */
13
+ export interface OtelConfig extends Partial<Omit<NodeSDKConfiguration, 'resource' | 'instrumentations'>> {
14
+ /**
15
+ * Enable or disable OpenTelemetry entirely.
16
+ *
17
+ * When disabled, no SDK is initialized and no traces are collected.
18
+ * Useful for tests or local development without a collector.
19
+ *
20
+ * @default true (false in 'test' environment)
21
+ */
22
+ enabled?: boolean;
23
+ /**
24
+ * Sampling ratio for traces (0.0 to 1.0).
25
+ *
26
+ * - `1.0` = 100% of traces are sampled (default)
27
+ * - `0.1` = 10% of traces are sampled
28
+ * - `0.0` = No traces are sampled
29
+ *
30
+ * This option is ignored if `sampler` is explicitly provided.
31
+ *
32
+ * @default 1.0
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * defineConfig({
37
+ * samplingRatio: 0.1, // Sample 10% of traces in production
38
+ * })
39
+ * ```
40
+ */
41
+ samplingRatio?: number;
42
+ /**
43
+ * Enable debug mode to print spans to the console.
44
+ *
45
+ * When enabled, a `ConsoleSpanExporter` is automatically added
46
+ * to help with local development and debugging.
47
+ *
48
+ * @default false
49
+ *
50
+ * @example
51
+ * ```ts
52
+ * defineConfig({
53
+ * debug: true, // Print spans to console
54
+ * })
55
+ * ```
56
+ */
57
+ debug?: boolean;
58
+ /**
59
+ * Service name for telemetry identification
60
+ * @default process.env.OTEL_SERVICE_NAME || process.env.APP_NAME || 'unknown_service'
61
+ */
62
+ serviceName?: string;
63
+ /**
64
+ * Service version
65
+ * @default process.env.APP_VERSION || '0.0.0'
66
+ */
67
+ serviceVersion?: string;
68
+ /**
69
+ * Deployment environment (production, staging, development, etc.)
70
+ * @default process.env.APP_ENV || 'development'
71
+ */
72
+ environment?: string;
73
+ /**
74
+ * Additional resource attributes to include in telemetry
75
+ */
76
+ resourceAttributes?: Record<string, string>;
77
+ /**
78
+ * Instrumentations configuration.
79
+ *
80
+ * - Pass a config object to merge with defaults
81
+ * - Pass an Instrumentation instance for custom instrumentations
82
+ * - Pass `{ enabled: false }` to disable
83
+ *
84
+ * @example
85
+ * ```ts
86
+ * instrumentations: {
87
+ * '@opentelemetry/instrumentation-http': {
88
+ * ignoredUrls: ['/internal/*', '/custom-health'],
89
+ * },
90
+ * '@opentelemetry/instrumentation-pino': {
91
+ * logHook: (span, record) => {
92
+ * record.tenant_id = getTenantId()
93
+ * },
94
+ * },
95
+ * '@opentelemetry/instrumentation-pg': { enabled: false },
96
+ * }
97
+ * ```
98
+ */
99
+ instrumentations?: InstrumentationsConfig;
100
+ /**
101
+ * Configure automatic user context extraction in the middleware.
102
+ *
103
+ * By default, extracts `id`, `email`, `role` from `ctx.auth.user`.
104
+ * Set to `false` to disable entirely.
105
+ *
106
+ * @example
107
+ * ```ts
108
+ * userContext: {
109
+ * resolver: async (ctx) => ({
110
+ * id: ctx.auth.user.id,
111
+ * tenantId: ctx.auth.user.tenantId,
112
+ * }),
113
+ * }
114
+ * ```
115
+ */
116
+ userContext?: false | UserContextConfig;
117
+ }
118
+ /**
119
+ * Result returned by the user context resolver
120
+ */
121
+ export interface UserContextResult {
122
+ id: string | number;
123
+ email?: string;
124
+ role?: string;
125
+ [key: string]: unknown;
126
+ }
127
+ /**
128
+ * Configuration for automatic user context extraction
129
+ */
130
+ export interface UserContextConfig {
131
+ /**
132
+ * Enable/disable automatic user extraction from @adonisjs/auth
133
+ * @default true
134
+ */
135
+ enabled?: boolean;
136
+ /**
137
+ * Custom function to extract user context from the HttpContext.
138
+ * When provided, replaces the default extraction logic.
139
+ * Return `null` to skip setting user context for this request.
140
+ */
141
+ resolver?: (ctx: HttpContext) => UserContextResult | null | Promise<UserContextResult | null>;
142
+ }
143
+ /**
144
+ * User information for tracing
145
+ */
146
+ export interface UserContext {
147
+ id: string | number;
148
+ email?: string;
149
+ role?: string;
150
+ [key: string]: unknown;
151
+ }
152
+ /**
153
+ * Headers carrier type for context propagation
154
+ */
155
+ export type HeadersCarrier = Record<string, string | string[] | undefined>;
@@ -0,0 +1 @@
1
+ export { hiddenFields } from './logging.js';
@@ -0,0 +1,79 @@
1
+ import type { Span } from '@opentelemetry/api';
2
+ import type { InstrumentationConfigMap } from '@opentelemetry/auto-instrumentations-node';
3
+ import type { Instrumentation } from '@opentelemetry/instrumentation';
4
+ /**
5
+ * Value for a known instrumentation: config object, instance, or disabled
6
+ */
7
+ export type InstrumentationValue<K extends keyof InstrumentationConfigMap> = InstrumentationConfigMap[K] | Instrumentation | {
8
+ enabled: false;
9
+ };
10
+ /**
11
+ * Value for a custom instrumentation: instance or disabled
12
+ */
13
+ export type CustomInstrumentationValue = Instrumentation | {
14
+ enabled: false;
15
+ };
16
+ /**
17
+ * Extended config for @opentelemetry/instrumentation-http.
18
+ * Adds AdonisJS-specific helpers for URL filtering.
19
+ */
20
+ export interface HttpInstrumentationConfig extends Omit<NonNullable<InstrumentationConfigMap['@opentelemetry/instrumentation-http']>, 'ignoreIncomingRequestHook'> {
21
+ /**
22
+ * URLs to ignore in HTTP instrumentation.
23
+ * Merged with defaults unless `mergeIgnoredUrls` is false.
24
+ * Supports wildcards: '/internal/*'
25
+ *
26
+ * @default ['/health', '/healthz', '/ready', '/metrics', '/favicon.ico', ...]
27
+ */
28
+ ignoredUrls?: string[];
29
+ /**
30
+ * Whether to merge ignoredUrls with default ignored URLs or replace them entirely.
31
+ * @default true
32
+ */
33
+ mergeIgnoredUrls?: boolean;
34
+ /**
35
+ * Custom hook to ignore specific incoming requests.
36
+ * Called AFTER the ignoredUrls check.
37
+ */
38
+ ignoreIncomingRequestHook?: (request: {
39
+ url?: string;
40
+ }) => boolean;
41
+ }
42
+ /**
43
+ * Extended config for @opentelemetry/instrumentation-pino.
44
+ * Allows custom logHook while preserving the internal one.
45
+ */
46
+ export interface PinoInstrumentationConfig extends Omit<NonNullable<InstrumentationConfigMap['@opentelemetry/instrumentation-pino']>, 'logHook'> {
47
+ /**
48
+ * Custom log hook executed AFTER the internal hook that adds route info.
49
+ * Use this to add your own properties to log records.
50
+ *
51
+ * @example
52
+ * ```ts
53
+ * logHook: (span, record) => {
54
+ * record.tenant_id = getCurrentTenantId()
55
+ * }
56
+ * ```
57
+ */
58
+ logHook?: (span: Span, record: Record<string, unknown>) => void;
59
+ }
60
+ /**
61
+ * Keys of instrumentations with custom extended configs
62
+ */
63
+ type ExtendedInstrumentationKeys = '@opentelemetry/instrumentation-http' | '@opentelemetry/instrumentation-pino';
64
+ /**
65
+ * Instrumentations configuration map.
66
+ *
67
+ * - HTTP and Pino instrumentations have extended configs
68
+ */
69
+ export type InstrumentationsConfig = {
70
+ '@opentelemetry/instrumentation-http'?: HttpInstrumentationConfig | Instrumentation | {
71
+ enabled: false;
72
+ };
73
+ '@opentelemetry/instrumentation-pino'?: PinoInstrumentationConfig | Instrumentation | {
74
+ enabled: false;
75
+ };
76
+ } & {
77
+ [K in Exclude<keyof InstrumentationConfigMap, ExtendedInstrumentationKeys>]?: InstrumentationValue<K>;
78
+ };
79
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Fields hidden by default in pino-pretty output
3
+ */
4
+ export declare const hiddenFields: readonly ["pid", "hostname", "trace_id", "span_id", "trace_flags", "route", "request_id", "x-request-id"];
5
+ export type HiddenField = (typeof hiddenFields)[number];
6
+ export interface OtelLoggingPresetOptions {
7
+ /**
8
+ * Fields to keep visible in logs (not hidden).
9
+ * Useful if you want to see trace context in development.
10
+ */
11
+ keep?: HiddenField[];
12
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Fields hidden by default in pino-pretty output
3
+ */
4
+ export const hiddenFields = [
5
+ 'pid',
6
+ 'hostname',
7
+ 'trace_id',
8
+ 'span_id',
9
+ 'trace_flags',
10
+ 'route',
11
+ 'request_id',
12
+ 'x-request-id',
13
+ ];
@@ -0,0 +1,12 @@
1
+ {{{
2
+ exports({ to: app.configPath('otel.ts') })
3
+ }}}
4
+ import { defineConfig } from '@adonisjs/otel'
5
+ import env from '#start/env'
6
+
7
+ export default defineConfig({
8
+ serviceName: env.get('APP_NAME'),
9
+ serviceVersion: env.get('APP_VERSION'),
10
+ environment: env.get('APP_ENV'),
11
+ })
12
+
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Path to the root directory where the stubs are stored. We use
3
+ * this path within commands and the configure hook
4
+ */
5
+ export declare const stubsRoot: string;