@adonisjs/otel 1.0.0 → 1.1.1
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.
- package/README.md +1 -1
- package/build/src/debug.d.ts +2 -0
- package/build/src/debug.js +2 -0
- package/build/src/helpers.d.ts +9 -1
- package/build/src/helpers.js +17 -1
- package/build/src/http_url_filter.d.ts +6 -4
- package/build/src/http_url_filter.js +33 -8
- package/build/src/middleware/otel_middleware.d.ts +6 -7
- package/build/src/middleware/otel_middleware.js +29 -22
- package/build/src/otel.js +12 -6
- package/build/src/types/index.d.ts +3 -1
- package/build/src/types/instrumentations.d.ts +22 -4
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ OpenTelemetry integration for AdonisJS with sensible defaults and zero-config se
|
|
|
10
10
|
|
|
11
11
|
## Official Documentation
|
|
12
12
|
|
|
13
|
-
The documentation is available on the [AdonisJS website](https://docs.adonisjs.com/guides/digging-deeper/
|
|
13
|
+
The documentation is available on the [AdonisJS website](https://docs.adonisjs.com/guides/digging-deeper/open-telemetry)
|
|
14
14
|
|
|
15
15
|
## Contributing
|
|
16
16
|
|
package/build/src/helpers.d.ts
CHANGED
|
@@ -70,17 +70,25 @@ export declare function handleError(span: Span, error: Error): void;
|
|
|
70
70
|
* Set user information on the currently active span.
|
|
71
71
|
*
|
|
72
72
|
* Uses OpenTelemetry semantic conventions for user attributes.
|
|
73
|
+
* Custom attributes are prefixed with `user.` automatically.
|
|
73
74
|
*
|
|
74
75
|
* @example
|
|
75
76
|
* ```ts
|
|
76
77
|
* import { setUser } from '@adonisjs/otel'
|
|
77
78
|
*
|
|
78
|
-
* //
|
|
79
|
+
* // Basic usage
|
|
79
80
|
* setUser({
|
|
80
81
|
* id: auth.user.id,
|
|
81
82
|
* email: auth.user.email,
|
|
82
83
|
* role: auth.user.role,
|
|
83
84
|
* })
|
|
85
|
+
*
|
|
86
|
+
* // With custom attributes
|
|
87
|
+
* setUser({
|
|
88
|
+
* id: auth.user.id,
|
|
89
|
+
* tenantId: auth.user.tenantId,
|
|
90
|
+
* plan: 'enterprise',
|
|
91
|
+
* })
|
|
84
92
|
* ```
|
|
85
93
|
*/
|
|
86
94
|
export declare function setUser(user: UserContextResult): void;
|
package/build/src/helpers.js
CHANGED
|
@@ -107,17 +107,25 @@ const ATTR_USER_ROLES = 'user.roles';
|
|
|
107
107
|
* Set user information on the currently active span.
|
|
108
108
|
*
|
|
109
109
|
* Uses OpenTelemetry semantic conventions for user attributes.
|
|
110
|
+
* Custom attributes are prefixed with `user.` automatically.
|
|
110
111
|
*
|
|
111
112
|
* @example
|
|
112
113
|
* ```ts
|
|
113
114
|
* import { setUser } from '@adonisjs/otel'
|
|
114
115
|
*
|
|
115
|
-
* //
|
|
116
|
+
* // Basic usage
|
|
116
117
|
* setUser({
|
|
117
118
|
* id: auth.user.id,
|
|
118
119
|
* email: auth.user.email,
|
|
119
120
|
* role: auth.user.role,
|
|
120
121
|
* })
|
|
122
|
+
*
|
|
123
|
+
* // With custom attributes
|
|
124
|
+
* setUser({
|
|
125
|
+
* id: auth.user.id,
|
|
126
|
+
* tenantId: auth.user.tenantId,
|
|
127
|
+
* plan: 'enterprise',
|
|
128
|
+
* })
|
|
121
129
|
* ```
|
|
122
130
|
*/
|
|
123
131
|
export function setUser(user) {
|
|
@@ -131,6 +139,14 @@ export function setUser(user) {
|
|
|
131
139
|
attributes[ATTR_USER_EMAIL] = user.email;
|
|
132
140
|
if (user.role)
|
|
133
141
|
attributes[ATTR_USER_ROLES] = [user.role];
|
|
142
|
+
// Add custom attributes with user. prefix
|
|
143
|
+
for (const [key, value] of Object.entries(user)) {
|
|
144
|
+
if (key === 'id' || key === 'email' || key === 'role')
|
|
145
|
+
continue;
|
|
146
|
+
if (value === undefined)
|
|
147
|
+
continue;
|
|
148
|
+
attributes[`user.${key}`] = value;
|
|
149
|
+
}
|
|
134
150
|
span.setAttributes(attributes);
|
|
135
151
|
}
|
|
136
152
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { InstrumentationConfigMap } from '@opentelemetry/auto-instrumentations-node';
|
|
2
|
-
import type { HttpInstrumentationConfig } from './types/instrumentations.js';
|
|
2
|
+
import type { HttpInstrumentationConfig, IgnoreRequestInfo } from './types/instrumentations.js';
|
|
3
3
|
/**
|
|
4
4
|
* Handles URL filtering for OpenTelemetry HTTP instrumentation.
|
|
5
5
|
* Determines which requests should be ignored (not traced).
|
|
@@ -8,15 +8,17 @@ export declare class HttpUrlFilter {
|
|
|
8
8
|
#private;
|
|
9
9
|
static readonly DEFAULT_IGNORED_URLS: string[];
|
|
10
10
|
static readonly STATIC_FILE_EXTENSIONS: Set<string>;
|
|
11
|
+
static readonly VITE_DEV_PATTERNS: string[];
|
|
11
12
|
constructor(config?: HttpInstrumentationConfig);
|
|
12
13
|
/**
|
|
13
|
-
* Check if a
|
|
14
|
-
* A
|
|
14
|
+
* Check if a request should be ignored (not traced).
|
|
15
|
+
* A request is ignored if:
|
|
16
|
+
* - It's an OPTIONS request and ignoreOptionsRequests is true (default)
|
|
15
17
|
* - It's a static file and ignoreStaticFiles is true (default)
|
|
16
18
|
* - It matches the ignored URLs list (exact or prefix pattern)
|
|
17
19
|
* - The user's custom hook returns true
|
|
18
20
|
*/
|
|
19
|
-
shouldIgnore(
|
|
21
|
+
shouldIgnore(request: IgnoreRequestInfo): boolean;
|
|
20
22
|
/**
|
|
21
23
|
* Apply HTTP instrumentation config to the merged config map
|
|
22
24
|
*/
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import debug from './debug.js';
|
|
1
2
|
/**
|
|
2
3
|
* Handles URL filtering for OpenTelemetry HTTP instrumentation.
|
|
3
4
|
* Determines which requests should be ignored (not traced).
|
|
@@ -40,13 +41,18 @@ export class HttpUrlFilter {
|
|
|
40
41
|
'ogg',
|
|
41
42
|
'wav',
|
|
42
43
|
'pdf',
|
|
44
|
+
'vue',
|
|
45
|
+
'svelte',
|
|
43
46
|
]);
|
|
47
|
+
static VITE_DEV_PATTERNS = ['/@vite/', '/@id/', '/@fs/', '/__vite'];
|
|
44
48
|
#ignoredUrls;
|
|
45
49
|
#ignoreStaticFiles;
|
|
50
|
+
#ignoreOptionsRequests;
|
|
46
51
|
#userIgnoreHook;
|
|
47
52
|
constructor(config) {
|
|
48
53
|
this.#ignoredUrls = this.#buildIgnoredUrls(config);
|
|
49
54
|
this.#ignoreStaticFiles = config?.ignoreStaticFiles !== false;
|
|
55
|
+
this.#ignoreOptionsRequests = config?.ignoreOptionsRequests !== false;
|
|
50
56
|
this.#userIgnoreHook = config?.ignoreIncomingRequestHook;
|
|
51
57
|
}
|
|
52
58
|
#buildIgnoredUrls(config) {
|
|
@@ -64,6 +70,9 @@ export class HttpUrlFilter {
|
|
|
64
70
|
const extension = lastSegment.slice(dotIndex + 1).toLowerCase();
|
|
65
71
|
return HttpUrlFilter.STATIC_FILE_EXTENSIONS.has(extension);
|
|
66
72
|
}
|
|
73
|
+
#isViteDevRequest(url) {
|
|
74
|
+
return HttpUrlFilter.VITE_DEV_PATTERNS.some((pattern) => url.startsWith(pattern));
|
|
75
|
+
}
|
|
67
76
|
#matchesPattern(urlPath, pattern) {
|
|
68
77
|
if (pattern.endsWith('/*')) {
|
|
69
78
|
const prefix = pattern.slice(0, -2);
|
|
@@ -72,22 +81,38 @@ export class HttpUrlFilter {
|
|
|
72
81
|
return urlPath === pattern || urlPath.startsWith(pattern + '/');
|
|
73
82
|
}
|
|
74
83
|
/**
|
|
75
|
-
* Check if a
|
|
76
|
-
* A
|
|
84
|
+
* Check if a request should be ignored (not traced).
|
|
85
|
+
* A request is ignored if:
|
|
86
|
+
* - It's an OPTIONS request and ignoreOptionsRequests is true (default)
|
|
77
87
|
* - It's a static file and ignoreStaticFiles is true (default)
|
|
78
88
|
* - It matches the ignored URLs list (exact or prefix pattern)
|
|
79
89
|
* - The user's custom hook returns true
|
|
80
90
|
*/
|
|
81
|
-
shouldIgnore(
|
|
91
|
+
shouldIgnore(request) {
|
|
92
|
+
const { url, method } = request;
|
|
93
|
+
if (this.#ignoreOptionsRequests && method === 'OPTIONS') {
|
|
94
|
+
debug('ignoring request "%s %s" (reason: OPTIONS method)', method, url);
|
|
95
|
+
return true;
|
|
96
|
+
}
|
|
82
97
|
if (!url)
|
|
83
98
|
return false;
|
|
84
99
|
const urlPath = url.split('?')[0];
|
|
85
|
-
if (this.#ignoreStaticFiles && this.#isStaticFile(urlPath))
|
|
100
|
+
if (this.#ignoreStaticFiles && this.#isStaticFile(urlPath)) {
|
|
101
|
+
debug('ignoring request "%s %s" (reason: static file)', method, urlPath);
|
|
86
102
|
return true;
|
|
87
|
-
|
|
103
|
+
}
|
|
104
|
+
if (this.#ignoreStaticFiles && this.#isViteDevRequest(urlPath)) {
|
|
105
|
+
debug('ignoring request "%s %s" (reason: vite dev pattern)', method, urlPath);
|
|
88
106
|
return true;
|
|
89
|
-
|
|
90
|
-
|
|
107
|
+
}
|
|
108
|
+
if (this.#ignoredUrls.some((pattern) => this.#matchesPattern(urlPath, pattern))) {
|
|
109
|
+
debug('ignoring request "%s %s" (reason: ignored url pattern)', method, urlPath);
|
|
110
|
+
return true;
|
|
111
|
+
}
|
|
112
|
+
if (this.#userIgnoreHook && this.#userIgnoreHook(request)) {
|
|
113
|
+
debug('ignoring request "%s %s" (reason: user hook)', method, urlPath);
|
|
114
|
+
return true;
|
|
115
|
+
}
|
|
91
116
|
return false;
|
|
92
117
|
}
|
|
93
118
|
/**
|
|
@@ -102,7 +127,7 @@ export class HttpUrlFilter {
|
|
|
102
127
|
mergedConfig[httpKey] = {
|
|
103
128
|
...currentConfig,
|
|
104
129
|
...userHttpConfig,
|
|
105
|
-
ignoreIncomingRequestHook: (req) => this.shouldIgnore(req.url),
|
|
130
|
+
ignoreIncomingRequestHook: (req) => this.shouldIgnore({ url: req.url, method: req.method }),
|
|
106
131
|
};
|
|
107
132
|
}
|
|
108
133
|
}
|
|
@@ -2,19 +2,18 @@ import type { HttpContext } from '@adonisjs/core/http';
|
|
|
2
2
|
import type { NextFn } from '@adonisjs/core/types/http';
|
|
3
3
|
import type { UserContextConfig } from '../types/index.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
* specific attributes like the route pattern, user info, etc.
|
|
5
|
+
* Enriches the active OpenTelemetry span with AdonisJS-specific attributes.
|
|
7
6
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* When Auth module is installed, it will automatically set user
|
|
12
|
-
* attributes on the span if a user is authenticated.
|
|
7
|
+
* Should be registered as a router middleware so it runs after route resolution.
|
|
8
|
+
* Automatically extracts user context from Auth module when available.
|
|
13
9
|
*/
|
|
14
10
|
export default class OtelMiddleware {
|
|
15
11
|
#private;
|
|
16
12
|
constructor(options: {
|
|
17
13
|
userContext?: UserContextConfig | false;
|
|
18
14
|
});
|
|
15
|
+
/**
|
|
16
|
+
* Enriches active span with route info, user context, and response status.
|
|
17
|
+
*/
|
|
19
18
|
handle(ctx: HttpContext, next: NextFn): Promise<any>;
|
|
20
19
|
}
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
import { trace } from '@opentelemetry/api';
|
|
1
|
+
import { context, trace } from '@opentelemetry/api';
|
|
2
|
+
import { getRPCMetadata, RPCType } from '@opentelemetry/core';
|
|
2
3
|
import { ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_HTTP_ROUTE, } from '@opentelemetry/semantic-conventions';
|
|
3
4
|
import { setUser } from '../helpers.js';
|
|
4
5
|
/**
|
|
5
|
-
*
|
|
6
|
-
* specific attributes like the route pattern, user info, etc.
|
|
6
|
+
* Enriches the active OpenTelemetry span with AdonisJS-specific attributes.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* When Auth module is installed, it will automatically set user
|
|
12
|
-
* attributes on the span if a user is authenticated.
|
|
8
|
+
* Should be registered as a router middleware so it runs after route resolution.
|
|
9
|
+
* Automatically extracts user context from Auth module when available.
|
|
13
10
|
*/
|
|
14
11
|
export default class OtelMiddleware {
|
|
15
12
|
#userContextConfig;
|
|
@@ -17,45 +14,55 @@ export default class OtelMiddleware {
|
|
|
17
14
|
this.#userContextConfig = options.userContext ?? {};
|
|
18
15
|
}
|
|
19
16
|
/**
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* @see https://opentelemetry.io/docs/specs/semconv/registry/attributes/user/
|
|
17
|
+
* Extracts user from auth context and sets OTEL user attributes.
|
|
18
|
+
* Supports custom resolvers or defaults to ctx.auth.user fields.
|
|
23
19
|
*/
|
|
24
20
|
async #setUserFromAuth(ctx) {
|
|
25
21
|
if (this.#userContextConfig === false)
|
|
26
22
|
return;
|
|
27
23
|
if (this.#userContextConfig.enabled === false)
|
|
28
24
|
return;
|
|
29
|
-
// Custom resolver takes precedence
|
|
30
25
|
if (this.#userContextConfig.resolver) {
|
|
31
26
|
const resolved = await this.#userContextConfig.resolver(ctx);
|
|
32
27
|
if (resolved)
|
|
33
28
|
setUser(resolved);
|
|
34
29
|
return;
|
|
35
30
|
}
|
|
36
|
-
// Default: extract from ctx.auth.user
|
|
37
31
|
const user = ctx.auth?.user;
|
|
38
32
|
if (!user)
|
|
39
33
|
return;
|
|
40
34
|
setUser({ id: user.id, email: user.email, role: user.role });
|
|
41
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Sets route metadata via RPCMetadata for OTEL HTTP instrumentation.
|
|
38
|
+
* This is the standard mechanism OTEL uses to populate http.route attribute.
|
|
39
|
+
*/
|
|
40
|
+
#setRouteViaRpcMetadata(routePattern) {
|
|
41
|
+
const rpcMetadata = getRPCMetadata(context.active());
|
|
42
|
+
if (rpcMetadata?.type === RPCType.HTTP)
|
|
43
|
+
rpcMetadata.route = routePattern;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Updates span name and sets http.route attribute directly.
|
|
47
|
+
* Produces better trace names like "GET /users/:id" instead of just "GET".
|
|
48
|
+
*/
|
|
49
|
+
#updateSpanWithRoute(options) {
|
|
50
|
+
options.span?.updateName(`${options.method} ${options.routePattern}`);
|
|
51
|
+
options.span?.setAttribute(ATTR_HTTP_ROUTE, options.routePattern);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Enriches active span with route info, user context, and response status.
|
|
55
|
+
*/
|
|
42
56
|
async handle(ctx, next) {
|
|
43
57
|
const span = trace.getActiveSpan();
|
|
44
58
|
if (!span)
|
|
45
59
|
return next();
|
|
46
60
|
const { request, route } = ctx;
|
|
47
|
-
/**
|
|
48
|
-
* Update span name with HTTP method and route pattern
|
|
49
|
-
* This gives much better trace names like "GET /users/:id" instead of "GET"
|
|
50
|
-
*/
|
|
51
61
|
if (route?.pattern) {
|
|
52
|
-
|
|
53
|
-
span.
|
|
62
|
+
this.#setRouteViaRpcMetadata(route.pattern);
|
|
63
|
+
this.#updateSpanWithRoute({ span, method: request.method(), routePattern: route.pattern });
|
|
54
64
|
}
|
|
55
65
|
span.setAttributes({ 'adonis.route.name': route?.name ?? 'unknown' });
|
|
56
|
-
/**
|
|
57
|
-
* Automatically set user context from Auth module
|
|
58
|
-
*/
|
|
59
66
|
await this.#setUserFromAuth(ctx);
|
|
60
67
|
const output = await next();
|
|
61
68
|
span.setAttribute(ATTR_HTTP_RESPONSE_STATUS_CODE, ctx.response.getStatus());
|
package/build/src/otel.js
CHANGED
|
@@ -2,10 +2,11 @@ import { getNodeAutoInstrumentations, } from '@opentelemetry/auto-instrumentatio
|
|
|
2
2
|
import { resourceFromAttributes } from '@opentelemetry/resources';
|
|
3
3
|
import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
4
4
|
import { ConsoleSpanExporter, ParentBasedSampler, SimpleSpanProcessor, TraceIdRatioBasedSampler, } from '@opentelemetry/sdk-trace-base';
|
|
5
|
-
import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION } from '@opentelemetry/semantic-conventions';
|
|
5
|
+
import { ATTR_HTTP_ROUTE, ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from '@opentelemetry/semantic-conventions';
|
|
6
6
|
import { ATTR_DEPLOYMENT_ENVIRONMENT_NAME, ATTR_SERVICE_INSTANCE_ID, } from '@opentelemetry/semantic-conventions/incubating';
|
|
7
7
|
import { HttpContext } from '@adonisjs/core/http';
|
|
8
8
|
import { HttpUrlFilter } from './http_url_filter.js';
|
|
9
|
+
import debug from './debug.js';
|
|
9
10
|
/**
|
|
10
11
|
* OpenTelemetry SDK manager for AdonisJS.
|
|
11
12
|
*
|
|
@@ -140,6 +141,10 @@ export class OtelManager {
|
|
|
140
141
|
*/
|
|
141
142
|
#buildInstrumentations() {
|
|
142
143
|
const { customInstances, disabledSet, configOverrides, httpConfig, pinoConfig } = this.#processUserInstrumentations(this.#config.instrumentations);
|
|
144
|
+
if (disabledSet.size > 0)
|
|
145
|
+
debug('disabled instrumentations: %O', [...disabledSet]);
|
|
146
|
+
if (customInstances.length > 0)
|
|
147
|
+
debug('custom instrumentations: %O', customInstances.map((i) => i.instrumentationName));
|
|
143
148
|
const mergedConfig = this.#buildBaseInstrumentationConfig();
|
|
144
149
|
for (const [name, config] of Object.entries(configOverrides)) {
|
|
145
150
|
mergedConfig[name] = {
|
|
@@ -166,15 +171,14 @@ export class OtelManager {
|
|
|
166
171
|
return;
|
|
167
172
|
}
|
|
168
173
|
const userLogHook = userPinoConfig?.logHook;
|
|
169
|
-
const internalLogHook = (span) => {
|
|
170
|
-
const httpContext = HttpContext.get();
|
|
171
|
-
span.setAttribute('http.route', httpContext?.route?.pattern || '');
|
|
172
|
-
};
|
|
173
174
|
mergedConfig[pinoKey] = {
|
|
174
175
|
...currentConfig,
|
|
175
176
|
...userPinoConfig,
|
|
176
177
|
logHook: (span, record) => {
|
|
177
|
-
|
|
178
|
+
const httpContext = HttpContext.get();
|
|
179
|
+
const routePattern = httpContext?.route?.pattern;
|
|
180
|
+
if (routePattern)
|
|
181
|
+
span.setAttribute(ATTR_HTTP_ROUTE, routePattern);
|
|
178
182
|
if (userLogHook)
|
|
179
183
|
userLogHook(span, record);
|
|
180
184
|
},
|
|
@@ -222,12 +226,14 @@ export class OtelManager {
|
|
|
222
226
|
* Start the OpenTelemetry SDK
|
|
223
227
|
*/
|
|
224
228
|
start() {
|
|
229
|
+
debug('starting otel sdk for service "%s" v%s (%s)', this.serviceName, this.serviceVersion, this.environment);
|
|
225
230
|
this.sdk.start();
|
|
226
231
|
}
|
|
227
232
|
/**
|
|
228
233
|
* Gracefully shutdown the OpenTelemetry SDK
|
|
229
234
|
*/
|
|
230
235
|
async shutdown() {
|
|
236
|
+
debug('shutting down otel sdk');
|
|
231
237
|
await this.sdk.shutdown();
|
|
232
238
|
}
|
|
233
239
|
/**
|
|
@@ -102,12 +102,14 @@ export interface OtelConfig extends Partial<Omit<NodeSDKConfiguration, 'resource
|
|
|
102
102
|
userContext?: false | UserContextConfig;
|
|
103
103
|
}
|
|
104
104
|
/**
|
|
105
|
-
* Result returned by the user context resolver
|
|
105
|
+
* Result returned by the user context resolver.
|
|
106
|
+
* Supports custom attributes via index signature.
|
|
106
107
|
*/
|
|
107
108
|
export interface UserContextResult {
|
|
108
109
|
id: string | number;
|
|
109
110
|
email?: string;
|
|
110
111
|
role?: string;
|
|
112
|
+
[key: string]: string | number | boolean | string[] | undefined;
|
|
111
113
|
}
|
|
112
114
|
/**
|
|
113
115
|
* Configuration for automatic user context extraction
|
|
@@ -13,6 +13,13 @@ export type InstrumentationValue<K extends keyof InstrumentationConfigMap> = Ins
|
|
|
13
13
|
export type CustomInstrumentationValue = Instrumentation | {
|
|
14
14
|
enabled: false;
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Request info passed to the ignoreIncomingRequestHook
|
|
18
|
+
*/
|
|
19
|
+
export interface IgnoreRequestInfo {
|
|
20
|
+
url?: string;
|
|
21
|
+
method?: string;
|
|
22
|
+
}
|
|
16
23
|
/**
|
|
17
24
|
* Extended config for @opentelemetry/instrumentation-http.
|
|
18
25
|
* Adds AdonisJS-specific helpers for URL filtering.
|
|
@@ -36,13 +43,16 @@ export interface HttpInstrumentationConfig extends Omit<NonNullable<Instrumentat
|
|
|
36
43
|
* @default true
|
|
37
44
|
*/
|
|
38
45
|
ignoreStaticFiles?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Whether to automatically ignore OPTIONS requests (CORS preflight).
|
|
48
|
+
* @default true
|
|
49
|
+
*/
|
|
50
|
+
ignoreOptionsRequests?: boolean;
|
|
39
51
|
/**
|
|
40
52
|
* Custom hook to ignore specific incoming requests.
|
|
41
|
-
* Called AFTER the ignoredUrls
|
|
53
|
+
* Called AFTER the ignoredUrls, static files, and OPTIONS checks.
|
|
42
54
|
*/
|
|
43
|
-
ignoreIncomingRequestHook?: (request:
|
|
44
|
-
url?: string;
|
|
45
|
-
}) => boolean;
|
|
55
|
+
ignoreIncomingRequestHook?: (request: IgnoreRequestInfo) => boolean;
|
|
46
56
|
}
|
|
47
57
|
/**
|
|
48
58
|
* Extended config for @opentelemetry/instrumentation-pino.
|
|
@@ -66,10 +76,16 @@ export interface PinoInstrumentationConfig extends Omit<NonNullable<Instrumentat
|
|
|
66
76
|
* Keys of instrumentations with custom extended configs
|
|
67
77
|
*/
|
|
68
78
|
type ExtendedInstrumentationKeys = '@opentelemetry/instrumentation-http' | '@opentelemetry/instrumentation-pino';
|
|
79
|
+
/**
|
|
80
|
+
* All possible values for any instrumentation key
|
|
81
|
+
*/
|
|
82
|
+
type AnyInstrumentationValue = HttpInstrumentationConfig | PinoInstrumentationConfig | InstrumentationConfigMap[keyof InstrumentationConfigMap] | CustomInstrumentationValue;
|
|
69
83
|
/**
|
|
70
84
|
* Instrumentations configuration map.
|
|
71
85
|
*
|
|
72
86
|
* - HTTP and Pino instrumentations have extended configs
|
|
87
|
+
* - Known OpenTelemetry instrumentations have typed configs with autocomplete
|
|
88
|
+
* - Custom instrumentations can be added with any string key
|
|
73
89
|
*/
|
|
74
90
|
export type InstrumentationsConfig = {
|
|
75
91
|
'@opentelemetry/instrumentation-http'?: HttpInstrumentationConfig | Instrumentation | {
|
|
@@ -80,5 +96,7 @@ export type InstrumentationsConfig = {
|
|
|
80
96
|
};
|
|
81
97
|
} & {
|
|
82
98
|
[K in Exclude<keyof InstrumentationConfigMap, ExtendedInstrumentationKeys>]?: InstrumentationValue<K>;
|
|
99
|
+
} & {
|
|
100
|
+
[key: string & {}]: AnyInstrumentationValue | undefined;
|
|
83
101
|
};
|
|
84
102
|
export {};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonisjs/otel",
|
|
3
3
|
"description": "OpenTelemetry integration for AdonisJS with sensible defaults and zero-config setup",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.1",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=20.6.0"
|
|
7
7
|
},
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
"dependencies": {
|
|
69
69
|
"@opentelemetry/api": "^1.9.0",
|
|
70
70
|
"@opentelemetry/auto-instrumentations-node": "^0.67.2",
|
|
71
|
+
"@opentelemetry/core": "^2.2.0",
|
|
71
72
|
"@opentelemetry/exporter-metrics-otlp-grpc": "^0.208.0",
|
|
72
73
|
"@opentelemetry/exporter-trace-otlp-grpc": "^0.208.0",
|
|
73
74
|
"@opentelemetry/instrumentation": "^0.208.0",
|
|
@@ -88,8 +89,8 @@
|
|
|
88
89
|
"@adonisjs/tsconfig": "^1.4.1",
|
|
89
90
|
"@japa/assert": "^4.1.1",
|
|
90
91
|
"@japa/runner": "^4.4.0",
|
|
92
|
+
"@julr/otel-instrumentation-clickhouse": "^1.0.2",
|
|
91
93
|
"@opentelemetry/context-async-hooks": "^2.2.0",
|
|
92
|
-
"@opentelemetry/core": "^2.2.0",
|
|
93
94
|
"@release-it/conventional-changelog": "^10.0.0",
|
|
94
95
|
"@sentry/node": "^10.30.0",
|
|
95
96
|
"@swc/core": "^1.15.3",
|