@pingops/otel 0.2.5 → 0.3.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.
- package/dist/index.cjs +148 -132
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -22
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +23 -22
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +149 -133
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/config.ts","../src/span-processor.ts","../src/tracer-provider.ts","../src/instrumentations/index.ts","../src/instrumentations/http/pingops-http.ts","../src/instrumentations/http/http.ts","../src/instrumentations/undici/types.ts","../src/instrumentations/undici/pingops-undici.ts","../src/instrumentations/undici/undici.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAgBA;AAKA;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/config.ts","../src/span-processor.ts","../src/tracer-provider.ts","../src/instrumentations/index.ts","../src/instrumentations/http/pingops-http.ts","../src/instrumentations/http/http.ts","../src/instrumentations/undici/types.ts","../src/instrumentations/undici/pingops-undici.ts","../src/instrumentations/undici/undici.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.d.mts
CHANGED
|
@@ -22,6 +22,11 @@ type PingopsExportMode = "immediate" | "batched";
|
|
|
22
22
|
* Configuration parameters for the PingopsSpanProcessor.
|
|
23
23
|
*/
|
|
24
24
|
interface PingopsProcessorConfig {
|
|
25
|
+
/**
|
|
26
|
+
* PingOps SDK version to attach on exported spans.
|
|
27
|
+
* Intended to be set by @pingops/sdk.
|
|
28
|
+
*/
|
|
29
|
+
sdkVersion?: string;
|
|
25
30
|
/**
|
|
26
31
|
* API key for authentication. Can also be set via PINGOPS_API_KEY environment variable.
|
|
27
32
|
*/
|
|
@@ -62,7 +67,7 @@ interface PingopsProcessorConfig {
|
|
|
62
67
|
* Note: this is the number of raw bytes observed at the instrumentation layer.
|
|
63
68
|
* For compressed bodies, this is the compressed size.
|
|
64
69
|
*
|
|
65
|
-
* @defaultValue
|
|
70
|
+
* @defaultValue 10240 (10 KB)
|
|
66
71
|
*/
|
|
67
72
|
maxRequestBodySize?: number;
|
|
68
73
|
/**
|
|
@@ -72,7 +77,7 @@ interface PingopsProcessorConfig {
|
|
|
72
77
|
* Note: this is the number of raw bytes observed at the instrumentation layer.
|
|
73
78
|
* For compressed bodies, this is the compressed size.
|
|
74
79
|
*
|
|
75
|
-
* @defaultValue
|
|
80
|
+
* @defaultValue 10240 (10 KB)
|
|
76
81
|
*/
|
|
77
82
|
maxResponseBodySize?: number;
|
|
78
83
|
/**
|
|
@@ -198,22 +203,26 @@ declare function getInstrumentations(): Instrumentation[];
|
|
|
198
203
|
declare const PingopsSemanticAttributes: {
|
|
199
204
|
HTTP_REQUEST_BODY: string;
|
|
200
205
|
HTTP_RESPONSE_BODY: string;
|
|
206
|
+
HTTP_REQUEST_BODY_SIZE: string;
|
|
207
|
+
HTTP_RESPONSE_BODY_SIZE: string;
|
|
201
208
|
};
|
|
202
209
|
interface PingopsInstrumentationConfig {
|
|
203
210
|
/**
|
|
204
211
|
* Maximum size of request body to capture in bytes
|
|
205
|
-
* @defaultValue
|
|
212
|
+
* @defaultValue 10240 (10 KB)
|
|
206
213
|
*/
|
|
207
214
|
maxRequestBodySize?: number;
|
|
208
215
|
/**
|
|
209
216
|
* Maximum size of response body to capture in bytes
|
|
210
|
-
* @defaultValue
|
|
217
|
+
* @defaultValue 10240 (10 KB)
|
|
211
218
|
*/
|
|
212
219
|
maxResponseBodySize?: number;
|
|
213
220
|
}
|
|
214
221
|
declare const PingopsHttpSemanticAttributes: {
|
|
215
222
|
HTTP_REQUEST_BODY: string;
|
|
216
223
|
HTTP_RESPONSE_BODY: string;
|
|
224
|
+
HTTP_REQUEST_BODY_SIZE: string;
|
|
225
|
+
HTTP_RESPONSE_BODY_SIZE: string;
|
|
217
226
|
};
|
|
218
227
|
interface PingopsHttpInstrumentationConfig extends HttpInstrumentationConfig, PingopsInstrumentationConfig {}
|
|
219
228
|
declare class PingopsHttpInstrumentation extends HttpInstrumentation {
|
|
@@ -259,28 +268,20 @@ interface UndiciRequest {
|
|
|
259
268
|
idempotent: boolean;
|
|
260
269
|
contentLength: number | null;
|
|
261
270
|
contentType: string | null;
|
|
262
|
-
body:
|
|
271
|
+
body: unknown;
|
|
263
272
|
}
|
|
264
273
|
interface UndiciResponse {
|
|
265
274
|
headers: Buffer[];
|
|
266
275
|
statusCode: number;
|
|
267
276
|
statusText: string;
|
|
268
277
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
(span: Span$1, info: {
|
|
277
|
-
request: RequestType;
|
|
278
|
-
response: ResponseType;
|
|
279
|
-
}): void;
|
|
280
|
-
}
|
|
281
|
-
interface StartSpanHookFunction<T = UndiciRequest> {
|
|
282
|
-
(request: T): Attributes;
|
|
283
|
-
}
|
|
278
|
+
type IgnoreRequestFunction<T = UndiciRequest> = (request: T) => boolean;
|
|
279
|
+
type RequestHookFunction<T = UndiciRequest> = (span: Span$1, request: T) => void;
|
|
280
|
+
type ResponseHookFunction<RequestType = UndiciRequest, ResponseType = UndiciResponse> = (span: Span$1, info: {
|
|
281
|
+
request: RequestType;
|
|
282
|
+
response: ResponseType;
|
|
283
|
+
}) => void;
|
|
284
|
+
type StartSpanHookFunction<T = UndiciRequest> = (request: T) => Attributes;
|
|
284
285
|
interface UndiciInstrumentationConfig<RequestType = UndiciRequest, ResponseType = UndiciResponse> extends InstrumentationConfig {
|
|
285
286
|
/** Not trace all outgoing requests that matched with custom function */
|
|
286
287
|
ignoreRequestHook?: IgnoreRequestFunction<RequestType>;
|
|
@@ -299,12 +300,12 @@ interface UndiciInstrumentationConfig<RequestType = UndiciRequest, ResponseType
|
|
|
299
300
|
};
|
|
300
301
|
/**
|
|
301
302
|
* Maximum size of request body to capture in bytes
|
|
302
|
-
* @defaultValue
|
|
303
|
+
* @defaultValue 10240 (10 KB)
|
|
303
304
|
*/
|
|
304
305
|
maxRequestBodySize?: number;
|
|
305
306
|
/**
|
|
306
307
|
* Maximum size of response body to capture in bytes
|
|
307
|
-
* @defaultValue
|
|
308
|
+
* @defaultValue 10240 (10 KB)
|
|
308
309
|
*/
|
|
309
310
|
maxResponseBodySize?: number;
|
|
310
311
|
}
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/config.ts","../src/span-processor.ts","../src/tracer-provider.ts","../src/instrumentations/index.ts","../src/instrumentations/http/pingops-http.ts","../src/instrumentations/http/http.ts","../src/instrumentations/undici/types.ts","../src/instrumentations/undici/pingops-undici.ts","../src/instrumentations/undici/undici.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;;;AAgBA;AAKA;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/config.ts","../src/span-processor.ts","../src/tracer-provider.ts","../src/instrumentations/index.ts","../src/instrumentations/http/pingops-http.ts","../src/instrumentations/http/http.ts","../src/instrumentations/undici/types.ts","../src/instrumentations/undici/pingops-undici.ts","../src/instrumentations/undici/undici.ts"],"sourcesContent":[],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BatchSpanProcessor, SimpleSpanProcessor } from "@opentelemetry/sdk-trace-base";
|
|
2
2
|
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
|
|
3
|
-
import { HTTP_RESPONSE_CONTENT_ENCODING, PINGOPS_CAPTURE_REQUEST_BODY, PINGOPS_CAPTURE_RESPONSE_BODY, bufferToBodyString, createLogger, extractSpanPayload, getHttpUrlFromAttributes, getPropagatedAttributesFromContext, isCompressedContentEncoding, isSpanEligible, shouldCaptureSpan } from "@pingops/core";
|
|
3
|
+
import { HTTP_RESPONSE_CONTENT_ENCODING, PINGOPS_CAPTURE_REQUEST_BODY, PINGOPS_CAPTURE_RESPONSE_BODY, PINGOPS_INTENTIONAL_SUPPRESSION, bufferToBodyString, createLogger, extractDomainFromUrl, extractSpanPayload, getHttpUrlFromAttributes, getPropagatedAttributesFromContext, isCompressedContentEncoding, isSpanEligible, shouldCaptureSpan } from "@pingops/core";
|
|
4
4
|
import { INVALID_SPAN_CONTEXT, ROOT_CONTEXT, SpanKind, SpanStatusCode, ValueType, context, propagation, trace } from "@opentelemetry/api";
|
|
5
5
|
import "@opentelemetry/sdk-trace-node";
|
|
6
6
|
import "@opentelemetry/resources";
|
|
@@ -106,6 +106,7 @@ var PingopsSpanProcessor = class {
|
|
|
106
106
|
});
|
|
107
107
|
this.config = {
|
|
108
108
|
debug: config.debug ?? false,
|
|
109
|
+
sdkVersion: config.sdkVersion,
|
|
109
110
|
headersAllowList: config.headersAllowList,
|
|
110
111
|
headersDenyList: config.headersDenyList,
|
|
111
112
|
domainAllowList: config.domainAllowList,
|
|
@@ -143,6 +144,7 @@ var PingopsSpanProcessor = class {
|
|
|
143
144
|
spanId: spanContext.spanId,
|
|
144
145
|
traceId: spanContext.traceId
|
|
145
146
|
});
|
|
147
|
+
if (this.config.sdkVersion) span.setAttribute("pingops.sdk.version", this.config.sdkVersion);
|
|
146
148
|
const propagatedAttributes = getPropagatedAttributesFromContext(parentContext);
|
|
147
149
|
if (Object.keys(propagatedAttributes).length > 0) {
|
|
148
150
|
for (const [key, value] of Object.entries(propagatedAttributes)) if (typeof value === "string" || Array.isArray(value)) span.setAttribute(key, value);
|
|
@@ -395,6 +397,7 @@ function shouldIgnoreOutboundInstrumentation(requestUrl) {
|
|
|
395
397
|
*/
|
|
396
398
|
function resolveOutboundSpanParentContext(activeContext, requestUrl) {
|
|
397
399
|
if (!isTracingSuppressed(activeContext)) return activeContext;
|
|
400
|
+
if (activeContext.getValue(PINGOPS_INTENTIONAL_SUPPRESSION) === true) return activeContext;
|
|
398
401
|
if (isExporterRequestUrl(requestUrl)) return activeContext;
|
|
399
402
|
if (!hasLoggedSuppressionLeakWarning) {
|
|
400
403
|
logger.warn("Detected suppressed context for outbound user request; running instrumentation on ROOT_CONTEXT to prevent Noop spans from suppression leakage");
|
|
@@ -403,18 +406,74 @@ function resolveOutboundSpanParentContext(activeContext, requestUrl) {
|
|
|
403
406
|
return ROOT_CONTEXT;
|
|
404
407
|
}
|
|
405
408
|
|
|
409
|
+
//#endregion
|
|
410
|
+
//#region src/instrumentations/body-utils.ts
|
|
411
|
+
const HTTP_REQUEST_BODY = "http.request.body";
|
|
412
|
+
const HTTP_RESPONSE_BODY = "http.response.body";
|
|
413
|
+
const HTTP_REQUEST_BODY_SIZE = "http.request.body.size";
|
|
414
|
+
const HTTP_RESPONSE_BODY_SIZE = "http.response.body.size";
|
|
415
|
+
const DEFAULT_MAX_REQUEST_BODY_SIZE = 10 * 1024;
|
|
416
|
+
const DEFAULT_MAX_RESPONSE_BODY_SIZE = 10 * 1024;
|
|
417
|
+
/**
|
|
418
|
+
* Gets domain rule configuration for a given URL.
|
|
419
|
+
*/
|
|
420
|
+
function getDomainRule(url, domainAllowList) {
|
|
421
|
+
if (!domainAllowList) return;
|
|
422
|
+
const domain = extractDomainFromUrl(url);
|
|
423
|
+
for (const rule of domainAllowList) if (domain === rule.domain || domain.endsWith(`.${rule.domain}`) || domain === rule.domain.slice(1)) return rule;
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Determines if request body should be captured based on priority:
|
|
427
|
+
* context > domain rule > global config > default (false).
|
|
428
|
+
*/
|
|
429
|
+
function shouldCaptureRequestBody(url) {
|
|
430
|
+
const contextValue = context.active().getValue(PINGOPS_CAPTURE_REQUEST_BODY);
|
|
431
|
+
if (contextValue !== void 0) return contextValue;
|
|
432
|
+
if (url) {
|
|
433
|
+
const domainRule = getDomainRule(url, getGlobalConfig()?.domainAllowList);
|
|
434
|
+
if (domainRule?.captureRequestBody !== void 0) return domainRule.captureRequestBody;
|
|
435
|
+
}
|
|
436
|
+
const globalConfig$1 = getGlobalConfig();
|
|
437
|
+
if (globalConfig$1?.captureRequestBody !== void 0) return globalConfig$1.captureRequestBody;
|
|
438
|
+
return false;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Determines if response body should be captured based on priority:
|
|
442
|
+
* context > domain rule > global config > default (false).
|
|
443
|
+
*/
|
|
444
|
+
function shouldCaptureResponseBody(url) {
|
|
445
|
+
const contextValue = context.active().getValue(PINGOPS_CAPTURE_RESPONSE_BODY);
|
|
446
|
+
if (contextValue !== void 0) return contextValue;
|
|
447
|
+
if (url) {
|
|
448
|
+
const domainRule = getDomainRule(url, getGlobalConfig()?.domainAllowList);
|
|
449
|
+
if (domainRule?.captureResponseBody !== void 0) return domainRule.captureResponseBody;
|
|
450
|
+
}
|
|
451
|
+
const globalConfig$1 = getGlobalConfig();
|
|
452
|
+
if (globalConfig$1?.captureResponseBody !== void 0) return globalConfig$1.captureResponseBody;
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Normalizes supported HTTP chunk types into a Buffer.
|
|
457
|
+
*/
|
|
458
|
+
function toBufferChunk(data) {
|
|
459
|
+
if (typeof data === "string") return Buffer.from(data);
|
|
460
|
+
if (Buffer.isBuffer(data)) return data;
|
|
461
|
+
if (data instanceof Uint8Array) return Buffer.from(data);
|
|
462
|
+
return null;
|
|
463
|
+
}
|
|
464
|
+
|
|
406
465
|
//#endregion
|
|
407
466
|
//#region src/instrumentations/http/pingops-http.ts
|
|
408
467
|
/**
|
|
409
468
|
* Pingops HTTP instrumentation that extends HttpInstrumentation
|
|
410
469
|
* with request/response body capture
|
|
411
470
|
*/
|
|
412
|
-
const DEFAULT_MAX_REQUEST_BODY_SIZE$1 = 4 * 1024;
|
|
413
|
-
const DEFAULT_MAX_RESPONSE_BODY_SIZE$1 = 4 * 1024;
|
|
414
471
|
const LEGACY_ATTR_HTTP_URL = "http.url";
|
|
415
472
|
const PingopsSemanticAttributes = {
|
|
416
|
-
HTTP_REQUEST_BODY
|
|
417
|
-
HTTP_RESPONSE_BODY
|
|
473
|
+
HTTP_REQUEST_BODY,
|
|
474
|
+
HTTP_RESPONSE_BODY,
|
|
475
|
+
HTTP_REQUEST_BODY_SIZE,
|
|
476
|
+
HTTP_RESPONSE_BODY_SIZE
|
|
418
477
|
};
|
|
419
478
|
/**
|
|
420
479
|
* Manually flattens a nested object into dot-notation keys
|
|
@@ -427,7 +486,7 @@ function isPrimitiveArray(value) {
|
|
|
427
486
|
}
|
|
428
487
|
function flatten(obj, prefix = "") {
|
|
429
488
|
const result = {};
|
|
430
|
-
for (const key in obj) if (Object.
|
|
489
|
+
for (const key in obj) if (Object.hasOwn(obj, key)) {
|
|
431
490
|
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
432
491
|
const value = obj[key];
|
|
433
492
|
if (isPlainObject(value)) Object.assign(result, flatten(value, newKey));
|
|
@@ -446,61 +505,12 @@ function setAttributeValue(span, attrName, attrValue) {
|
|
|
446
505
|
} else if (isPlainObject(attrValue)) span.setAttributes(flatten({ [attrName]: attrValue }));
|
|
447
506
|
}
|
|
448
507
|
/**
|
|
449
|
-
*
|
|
450
|
-
*/
|
|
451
|
-
function extractDomainFromUrl$1(url) {
|
|
452
|
-
try {
|
|
453
|
-
return new URL(url).hostname;
|
|
454
|
-
} catch {
|
|
455
|
-
const match = url.match(/^(?:https?:\/\/)?([^/]+)/);
|
|
456
|
-
return match ? match[1] : "";
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
/**
|
|
460
|
-
* Gets domain rule configuration for a given URL
|
|
461
|
-
*/
|
|
462
|
-
function getDomainRule$1(url, domainAllowList) {
|
|
463
|
-
if (!domainAllowList) return;
|
|
464
|
-
const domain = extractDomainFromUrl$1(url);
|
|
465
|
-
for (const rule of domainAllowList) if (domain === rule.domain || domain.endsWith(`.${rule.domain}`) || domain === rule.domain.slice(1)) return rule;
|
|
466
|
-
}
|
|
467
|
-
/**
|
|
468
|
-
* Determines if request body should be captured based on priority:
|
|
469
|
-
* context > domain rule > global config > default (false)
|
|
470
|
-
*/
|
|
471
|
-
function shouldCaptureRequestBody$1(url) {
|
|
472
|
-
const contextValue = context.active().getValue(PINGOPS_CAPTURE_REQUEST_BODY);
|
|
473
|
-
if (contextValue !== void 0) return contextValue;
|
|
474
|
-
if (url) {
|
|
475
|
-
const domainRule = getDomainRule$1(url, getGlobalConfig()?.domainAllowList);
|
|
476
|
-
if (domainRule?.captureRequestBody !== void 0) return domainRule.captureRequestBody;
|
|
477
|
-
}
|
|
478
|
-
const globalConfig$1 = getGlobalConfig();
|
|
479
|
-
if (globalConfig$1?.captureRequestBody !== void 0) return globalConfig$1.captureRequestBody;
|
|
480
|
-
return false;
|
|
481
|
-
}
|
|
482
|
-
/**
|
|
483
|
-
* Determines if response body should be captured based on priority:
|
|
484
|
-
* context > domain rule > global config > default (false)
|
|
485
|
-
*/
|
|
486
|
-
function shouldCaptureResponseBody$1(url) {
|
|
487
|
-
const contextValue = context.active().getValue(PINGOPS_CAPTURE_RESPONSE_BODY);
|
|
488
|
-
if (contextValue !== void 0) return contextValue;
|
|
489
|
-
if (url) {
|
|
490
|
-
const domainRule = getDomainRule$1(url, getGlobalConfig()?.domainAllowList);
|
|
491
|
-
if (domainRule?.captureResponseBody !== void 0) return domainRule.captureResponseBody;
|
|
492
|
-
}
|
|
493
|
-
const globalConfig$1 = getGlobalConfig();
|
|
494
|
-
if (globalConfig$1?.captureResponseBody !== void 0) return globalConfig$1.captureResponseBody;
|
|
495
|
-
return false;
|
|
496
|
-
}
|
|
497
|
-
/**
|
|
498
|
-
* Captures request body from string or Buffer data
|
|
508
|
+
* Captures request body from a chunk buffer.
|
|
499
509
|
*/
|
|
500
510
|
function captureRequestBody(span, data, maxSize, semanticAttr, url) {
|
|
501
|
-
if (!shouldCaptureRequestBody
|
|
511
|
+
if (!shouldCaptureRequestBody(url)) return;
|
|
502
512
|
if (data.length && data.length <= maxSize) try {
|
|
503
|
-
const requestBody =
|
|
513
|
+
const requestBody = data.toString("utf-8");
|
|
504
514
|
if (requestBody) setAttributeValue(span, semanticAttr, requestBody);
|
|
505
515
|
} catch (e) {
|
|
506
516
|
console.error("Error occurred while capturing request body:", e);
|
|
@@ -510,12 +520,12 @@ function captureRequestBody(span, data, maxSize, semanticAttr, url) {
|
|
|
510
520
|
* Captures response body from chunks
|
|
511
521
|
*/
|
|
512
522
|
function captureResponseBody(span, chunks, semanticAttr, responseHeaders, url, maxSize) {
|
|
513
|
-
if (!shouldCaptureResponseBody
|
|
523
|
+
if (!shouldCaptureResponseBody(url)) return;
|
|
514
524
|
if (chunks === null) {
|
|
515
525
|
const contentEncoding = responseHeaders?.["content-encoding"];
|
|
516
526
|
const contentType = responseHeaders?.["content-type"];
|
|
517
527
|
const toHeaderString = (value) => typeof value === "string" ? value : Array.isArray(value) ? value.join(", ") : "unknown";
|
|
518
|
-
setAttributeValue(span, semanticAttr, `[truncated response body; exceeded maxResponseBodySize=${maxSize ?? DEFAULT_MAX_RESPONSE_BODY_SIZE
|
|
528
|
+
setAttributeValue(span, semanticAttr, `[truncated response body; exceeded maxResponseBodySize=${maxSize ?? DEFAULT_MAX_RESPONSE_BODY_SIZE}; content-type=${toHeaderString(contentType)}; content-encoding=${toHeaderString(contentEncoding)}]`);
|
|
519
529
|
return;
|
|
520
530
|
}
|
|
521
531
|
if (chunks.length) try {
|
|
@@ -587,6 +597,21 @@ function extractRequestUrlFromSpanOptions(options) {
|
|
|
587
597
|
if (!host) return;
|
|
588
598
|
return `${scheme}://${host}${typeof attrs[ATTR_SERVER_PORT] === "number" ? `:${attrs[ATTR_SERVER_PORT]}` : ""}${typeof attrs[ATTR_URL_PATH] === "string" ? attrs[ATTR_URL_PATH] : "/"}${typeof attrs[ATTR_URL_QUERY] === "string" && attrs[ATTR_URL_QUERY].length > 0 ? `?${attrs[ATTR_URL_QUERY]}` : ""}`;
|
|
589
599
|
}
|
|
600
|
+
function parseRequestPathAndQuery(pathWithQuery) {
|
|
601
|
+
const queryIndex = pathWithQuery.indexOf("?");
|
|
602
|
+
if (queryIndex < 0) return { path: pathWithQuery || "/" };
|
|
603
|
+
const path = pathWithQuery.slice(0, queryIndex) || "/";
|
|
604
|
+
const queryPart = pathWithQuery.slice(queryIndex);
|
|
605
|
+
return {
|
|
606
|
+
path,
|
|
607
|
+
query: queryPart.length > 0 ? queryPart : void 0
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
function extractClientRequestPath(request) {
|
|
611
|
+
if (!request || typeof request !== "object" || !("path" in request)) return;
|
|
612
|
+
const path = request.path;
|
|
613
|
+
return typeof path === "string" && path.length > 0 ? path : void 0;
|
|
614
|
+
}
|
|
590
615
|
const PingopsHttpSemanticAttributes = PingopsSemanticAttributes;
|
|
591
616
|
var PingopsHttpInstrumentation = class extends HttpInstrumentation {
|
|
592
617
|
constructor(config) {
|
|
@@ -619,18 +644,36 @@ var PingopsHttpInstrumentation = class extends HttpInstrumentation {
|
|
|
619
644
|
const headers = extractRequestHeaders(request);
|
|
620
645
|
if (headers) captureRequestHeaders(span, headers);
|
|
621
646
|
if (request instanceof ClientRequest) {
|
|
622
|
-
const maxRequestBodySize = config?.maxRequestBodySize || DEFAULT_MAX_REQUEST_BODY_SIZE
|
|
647
|
+
const maxRequestBodySize = config?.maxRequestBodySize || DEFAULT_MAX_REQUEST_BODY_SIZE;
|
|
648
|
+
let requestBodySize = 0;
|
|
649
|
+
span.setAttribute(PingopsSemanticAttributes.HTTP_REQUEST_BODY_SIZE, requestBodySize);
|
|
623
650
|
const hostHeader = request.getHeader("host");
|
|
624
651
|
const host = typeof hostHeader === "string" ? hostHeader : Array.isArray(hostHeader) ? hostHeader.join(",") : typeof hostHeader === "number" ? String(hostHeader) : void 0;
|
|
625
652
|
const url = request.path && host ? `${request.protocol || "http:"}//${host}${request.path}` : void 0;
|
|
653
|
+
if (typeof request.path === "string" && request.path.length > 0) {
|
|
654
|
+
const { path, query } = parseRequestPathAndQuery(request.path);
|
|
655
|
+
span.setAttribute(ATTR_URL_PATH, path);
|
|
656
|
+
if (query) span.setAttribute(ATTR_URL_QUERY, query);
|
|
657
|
+
}
|
|
658
|
+
if (url) span.setAttribute(ATTR_URL_FULL, url);
|
|
626
659
|
const originalWrite = request.write.bind(request);
|
|
627
660
|
const originalEnd = request.end.bind(request);
|
|
628
661
|
request.write = ((data, ...rest) => {
|
|
629
|
-
|
|
662
|
+
const chunkBuffer = toBufferChunk(data);
|
|
663
|
+
if (chunkBuffer) {
|
|
664
|
+
requestBodySize += chunkBuffer.length;
|
|
665
|
+
span.setAttribute(PingopsSemanticAttributes.HTTP_REQUEST_BODY_SIZE, requestBodySize);
|
|
666
|
+
captureRequestBody(span, chunkBuffer, maxRequestBodySize, PingopsSemanticAttributes.HTTP_REQUEST_BODY, url);
|
|
667
|
+
}
|
|
630
668
|
return originalWrite(data, ...rest);
|
|
631
669
|
});
|
|
632
670
|
request.end = ((data, ...rest) => {
|
|
633
|
-
|
|
671
|
+
const chunkBuffer = toBufferChunk(data);
|
|
672
|
+
if (chunkBuffer) {
|
|
673
|
+
requestBodySize += chunkBuffer.length;
|
|
674
|
+
span.setAttribute(PingopsSemanticAttributes.HTTP_REQUEST_BODY_SIZE, requestBodySize);
|
|
675
|
+
captureRequestBody(span, chunkBuffer, maxRequestBodySize, PingopsSemanticAttributes.HTTP_REQUEST_BODY, url);
|
|
676
|
+
}
|
|
634
677
|
return originalEnd(data, ...rest);
|
|
635
678
|
});
|
|
636
679
|
}
|
|
@@ -642,19 +685,25 @@ var PingopsHttpInstrumentation = class extends HttpInstrumentation {
|
|
|
642
685
|
const headers = extractResponseHeaders(response);
|
|
643
686
|
if (headers) captureResponseHeaders(span, headers);
|
|
644
687
|
if (response instanceof IncomingMessage) {
|
|
645
|
-
const
|
|
688
|
+
const requestPath = response.req instanceof ClientRequest ? extractClientRequestPath(response.req) : void 0;
|
|
689
|
+
if (requestPath) {
|
|
690
|
+
const { path, query } = parseRequestPathAndQuery(requestPath);
|
|
691
|
+
span.setAttribute(ATTR_URL_PATH, path);
|
|
692
|
+
if (query) span.setAttribute(ATTR_URL_QUERY, query);
|
|
693
|
+
}
|
|
694
|
+
const maxResponseBodySize = config?.maxResponseBodySize || DEFAULT_MAX_RESPONSE_BODY_SIZE;
|
|
646
695
|
const url = response.url || void 0;
|
|
647
696
|
let chunks = [];
|
|
648
697
|
let totalSize = 0;
|
|
649
|
-
|
|
698
|
+
span.setAttribute(PingopsSemanticAttributes.HTTP_RESPONSE_BODY_SIZE, 0);
|
|
699
|
+
const shouldCapture = shouldCaptureResponseBody(url);
|
|
650
700
|
response.prependListener("data", (chunk) => {
|
|
651
|
-
if (!chunk
|
|
652
|
-
|
|
653
|
-
if (typeof chunk === "string") chunkBuffer = Buffer.from(chunk);
|
|
654
|
-
else if (Buffer.isBuffer(chunk)) chunkBuffer = chunk;
|
|
655
|
-
else if (chunk instanceof Uint8Array) chunkBuffer = Buffer.from(chunk);
|
|
701
|
+
if (!chunk) return;
|
|
702
|
+
const chunkBuffer = toBufferChunk(chunk);
|
|
656
703
|
if (!chunkBuffer) return;
|
|
657
704
|
totalSize += chunkBuffer.length;
|
|
705
|
+
span.setAttribute(PingopsSemanticAttributes.HTTP_RESPONSE_BODY_SIZE, totalSize);
|
|
706
|
+
if (!shouldCapture) return;
|
|
658
707
|
if (chunks && totalSize <= maxResponseBodySize) chunks.push(chunkBuffer);
|
|
659
708
|
else chunks = null;
|
|
660
709
|
});
|
|
@@ -662,6 +711,7 @@ var PingopsHttpInstrumentation = class extends HttpInstrumentation {
|
|
|
662
711
|
const finalizeCapture = () => {
|
|
663
712
|
if (finalized) return;
|
|
664
713
|
finalized = true;
|
|
714
|
+
span.setAttribute(PingopsSemanticAttributes.HTTP_RESPONSE_BODY_SIZE, totalSize);
|
|
665
715
|
captureResponseBody(span, chunks, PingopsSemanticAttributes.HTTP_RESPONSE_BODY, headers, url, maxResponseBodySize);
|
|
666
716
|
};
|
|
667
717
|
response.prependOnceListener("end", finalizeCapture);
|
|
@@ -710,59 +760,6 @@ function createHttpInstrumentation(config) {
|
|
|
710
760
|
|
|
711
761
|
//#endregion
|
|
712
762
|
//#region src/instrumentations/undici/pingops-undici.ts
|
|
713
|
-
const DEFAULT_MAX_REQUEST_BODY_SIZE = 4 * 1024;
|
|
714
|
-
const DEFAULT_MAX_RESPONSE_BODY_SIZE = 4 * 1024;
|
|
715
|
-
const HTTP_REQUEST_BODY = "http.request.body";
|
|
716
|
-
const HTTP_RESPONSE_BODY = "http.response.body";
|
|
717
|
-
/**
|
|
718
|
-
* Extracts domain from URL
|
|
719
|
-
*/
|
|
720
|
-
function extractDomainFromUrl(url) {
|
|
721
|
-
try {
|
|
722
|
-
return new URL$1(url).hostname;
|
|
723
|
-
} catch {
|
|
724
|
-
const match = url.match(/^(?:https?:\/\/)?([^/]+)/);
|
|
725
|
-
return match ? match[1] : "";
|
|
726
|
-
}
|
|
727
|
-
}
|
|
728
|
-
/**
|
|
729
|
-
* Gets domain rule configuration for a given URL
|
|
730
|
-
*/
|
|
731
|
-
function getDomainRule(url, domainAllowList) {
|
|
732
|
-
if (!domainAllowList) return;
|
|
733
|
-
const domain = extractDomainFromUrl(url);
|
|
734
|
-
for (const rule of domainAllowList) if (domain === rule.domain || domain.endsWith(`.${rule.domain}`) || domain === rule.domain.slice(1)) return rule;
|
|
735
|
-
}
|
|
736
|
-
/**
|
|
737
|
-
* Determines if request body should be captured based on priority:
|
|
738
|
-
* context > domain rule > global config > default (false)
|
|
739
|
-
*/
|
|
740
|
-
function shouldCaptureRequestBody(url) {
|
|
741
|
-
const contextValue = context.active().getValue(PINGOPS_CAPTURE_REQUEST_BODY);
|
|
742
|
-
if (contextValue !== void 0) return contextValue;
|
|
743
|
-
if (url) {
|
|
744
|
-
const domainRule = getDomainRule(url, getGlobalConfig()?.domainAllowList);
|
|
745
|
-
if (domainRule?.captureRequestBody !== void 0) return domainRule.captureRequestBody;
|
|
746
|
-
}
|
|
747
|
-
const globalConfig$1 = getGlobalConfig();
|
|
748
|
-
if (globalConfig$1?.captureRequestBody !== void 0) return globalConfig$1.captureRequestBody;
|
|
749
|
-
return false;
|
|
750
|
-
}
|
|
751
|
-
/**
|
|
752
|
-
* Determines if response body should be captured based on priority:
|
|
753
|
-
* context > domain rule > global config > default (false)
|
|
754
|
-
*/
|
|
755
|
-
function shouldCaptureResponseBody(url) {
|
|
756
|
-
const contextValue = context.active().getValue(PINGOPS_CAPTURE_RESPONSE_BODY);
|
|
757
|
-
if (contextValue !== void 0) return contextValue;
|
|
758
|
-
if (url) {
|
|
759
|
-
const domainRule = getDomainRule(url, getGlobalConfig()?.domainAllowList);
|
|
760
|
-
if (domainRule?.captureResponseBody !== void 0) return domainRule.captureResponseBody;
|
|
761
|
-
}
|
|
762
|
-
const globalConfig$1 = getGlobalConfig();
|
|
763
|
-
if (globalConfig$1?.captureResponseBody !== void 0) return globalConfig$1.captureResponseBody;
|
|
764
|
-
return false;
|
|
765
|
-
}
|
|
766
763
|
var UndiciInstrumentation = class extends InstrumentationBase {
|
|
767
764
|
_recordFromReq = /* @__PURE__ */ new WeakMap();
|
|
768
765
|
constructor(config = {}) {
|
|
@@ -870,7 +867,9 @@ var UndiciInstrumentation = class extends InstrumentationBase {
|
|
|
870
867
|
[ATTR_URL_FULL]: requestUrl.toString(),
|
|
871
868
|
[ATTR_URL_PATH]: requestUrl.pathname,
|
|
872
869
|
[ATTR_URL_QUERY]: requestUrl.search,
|
|
873
|
-
[ATTR_URL_SCHEME]: urlScheme
|
|
870
|
+
[ATTR_URL_SCHEME]: urlScheme,
|
|
871
|
+
[HTTP_REQUEST_BODY_SIZE]: 0,
|
|
872
|
+
[HTTP_RESPONSE_BODY_SIZE]: 0
|
|
874
873
|
};
|
|
875
874
|
const schemePorts = {
|
|
876
875
|
https: "443",
|
|
@@ -913,6 +912,10 @@ var UndiciInstrumentation = class extends InstrumentationBase {
|
|
|
913
912
|
responseBodyChunks: [],
|
|
914
913
|
requestBodySize: 0,
|
|
915
914
|
responseBodySize: 0,
|
|
915
|
+
requestBodyCaptureSize: 0,
|
|
916
|
+
responseBodyCaptureSize: 0,
|
|
917
|
+
requestBodyCaptureExceeded: false,
|
|
918
|
+
responseBodyCaptureExceeded: false,
|
|
916
919
|
url: requestUrl.toString()
|
|
917
920
|
});
|
|
918
921
|
}
|
|
@@ -959,11 +962,13 @@ var UndiciInstrumentation = class extends InstrumentationBase {
|
|
|
959
962
|
const record = this._recordFromReq.get(request);
|
|
960
963
|
if (!record) return;
|
|
961
964
|
const { span, attributes, startTime } = record;
|
|
965
|
+
span.setAttribute(HTTP_REQUEST_BODY_SIZE, record.requestBodySize);
|
|
966
|
+
span.setAttribute(HTTP_RESPONSE_BODY_SIZE, record.responseBodySize);
|
|
962
967
|
if (shouldCaptureResponseBody(record.url)) {
|
|
963
968
|
const maxResponseBodySize = this.getConfig().maxResponseBodySize ?? DEFAULT_MAX_RESPONSE_BODY_SIZE;
|
|
964
969
|
const contentEncoding = record.attributes?.["http.response.header.content-encoding"] ?? void 0;
|
|
965
970
|
const contentType = record.attributes?.["http.response.header.content-type"] ?? void 0;
|
|
966
|
-
if (record.
|
|
971
|
+
if (record.responseBodyCaptureExceeded) span.setAttribute(HTTP_RESPONSE_BODY, `[truncated response body; exceeded maxResponseBodySize=${maxResponseBodySize}; content-type=${contentType ?? "unknown"}; content-encoding=${contentEncoding ?? "identity"}]`);
|
|
967
972
|
else if (record.responseBodyChunks.length > 0) try {
|
|
968
973
|
const responseBodyBuffer = Buffer.concat(record.responseBodyChunks);
|
|
969
974
|
if (isCompressedContentEncoding(contentEncoding)) {
|
|
@@ -985,8 +990,10 @@ var UndiciInstrumentation = class extends InstrumentationBase {
|
|
|
985
990
|
const record = this._recordFromReq.get(request);
|
|
986
991
|
if (!record) return;
|
|
987
992
|
const { span, attributes, startTime } = record;
|
|
993
|
+
span.setAttribute(HTTP_REQUEST_BODY_SIZE, record.requestBodySize);
|
|
994
|
+
span.setAttribute(HTTP_RESPONSE_BODY_SIZE, record.responseBodySize);
|
|
988
995
|
if (shouldCaptureRequestBody(record.url)) {
|
|
989
|
-
if (record.requestBodyChunks.length > 0 && record.
|
|
996
|
+
if (record.requestBodyChunks.length > 0 && !record.requestBodyCaptureExceeded) try {
|
|
990
997
|
const requestBody = Buffer.concat(record.requestBodyChunks).toString("utf-8");
|
|
991
998
|
if (requestBody) span.setAttribute(HTTP_REQUEST_BODY, requestBody);
|
|
992
999
|
} catch (e) {
|
|
@@ -1007,24 +1014,29 @@ var UndiciInstrumentation = class extends InstrumentationBase {
|
|
|
1007
1014
|
onBodyChunkSent({ request, chunk }) {
|
|
1008
1015
|
const record = this._recordFromReq.get(request);
|
|
1009
1016
|
if (!record) return;
|
|
1017
|
+
record.requestBodySize += chunk.length;
|
|
1010
1018
|
if (!shouldCaptureRequestBody(record.url)) return;
|
|
1011
1019
|
const maxRequestBodySize = this.getConfig().maxRequestBodySize ?? DEFAULT_MAX_REQUEST_BODY_SIZE;
|
|
1012
|
-
if (record.
|
|
1020
|
+
if (!record.requestBodyCaptureExceeded && record.requestBodyCaptureSize + chunk.length <= maxRequestBodySize) {
|
|
1013
1021
|
record.requestBodyChunks.push(chunk);
|
|
1014
|
-
record.
|
|
1022
|
+
record.requestBodyCaptureSize += chunk.length;
|
|
1015
1023
|
} else {
|
|
1016
|
-
record.
|
|
1024
|
+
record.requestBodyCaptureExceeded = true;
|
|
1017
1025
|
record.requestBodyChunks = [];
|
|
1026
|
+
record.requestBodyCaptureSize = 0;
|
|
1018
1027
|
}
|
|
1019
1028
|
}
|
|
1020
1029
|
onBodySent({ request }) {
|
|
1021
1030
|
const record = this._recordFromReq.get(request);
|
|
1022
1031
|
if (!record) return;
|
|
1032
|
+
record.span.setAttribute(HTTP_REQUEST_BODY_SIZE, record.requestBodySize);
|
|
1023
1033
|
if (!shouldCaptureRequestBody(record.url)) {
|
|
1024
1034
|
record.requestBodyChunks = [];
|
|
1035
|
+
record.requestBodyCaptureSize = 0;
|
|
1036
|
+
record.requestBodyCaptureExceeded = false;
|
|
1025
1037
|
return;
|
|
1026
1038
|
}
|
|
1027
|
-
if (record.
|
|
1039
|
+
if (record.requestBodyCaptureExceeded) {
|
|
1028
1040
|
const maxRequestBodySize = this.getConfig().maxRequestBodySize ?? DEFAULT_MAX_REQUEST_BODY_SIZE;
|
|
1029
1041
|
record.span.setAttribute(HTTP_REQUEST_BODY, `[truncated request body; exceeded maxRequestBodySize=${maxRequestBodySize}]`);
|
|
1030
1042
|
} else if (record.requestBodyChunks.length > 0) try {
|
|
@@ -1034,18 +1046,22 @@ var UndiciInstrumentation = class extends InstrumentationBase {
|
|
|
1034
1046
|
this._diag.error("Error occurred while capturing request body:", e);
|
|
1035
1047
|
}
|
|
1036
1048
|
record.requestBodyChunks = [];
|
|
1049
|
+
record.requestBodyCaptureSize = 0;
|
|
1050
|
+
record.requestBodyCaptureExceeded = false;
|
|
1037
1051
|
}
|
|
1038
1052
|
onBodyChunkReceived({ request, chunk }) {
|
|
1039
1053
|
const record = this._recordFromReq.get(request);
|
|
1040
1054
|
if (!record) return;
|
|
1055
|
+
record.responseBodySize += chunk.length;
|
|
1041
1056
|
if (!shouldCaptureResponseBody(record.url)) return;
|
|
1042
1057
|
const maxResponseBodySize = this.getConfig().maxResponseBodySize ?? DEFAULT_MAX_RESPONSE_BODY_SIZE;
|
|
1043
|
-
if (record.
|
|
1058
|
+
if (!record.responseBodyCaptureExceeded && record.responseBodyCaptureSize + chunk.length <= maxResponseBodySize) {
|
|
1044
1059
|
record.responseBodyChunks.push(chunk);
|
|
1045
|
-
record.
|
|
1060
|
+
record.responseBodyCaptureSize += chunk.length;
|
|
1046
1061
|
} else {
|
|
1047
|
-
record.
|
|
1062
|
+
record.responseBodyCaptureExceeded = true;
|
|
1048
1063
|
record.responseBodyChunks = [];
|
|
1064
|
+
record.responseBodyCaptureSize = 0;
|
|
1049
1065
|
}
|
|
1050
1066
|
}
|
|
1051
1067
|
recordRequestDuration(attributes, startTime) {
|