@pingops/core 0.1.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.
Files changed (45) hide show
  1. package/dist/context-keys.d.ts +30 -0
  2. package/dist/context-keys.d.ts.map +1 -0
  3. package/dist/context-keys.js +31 -0
  4. package/dist/context-keys.js.map +1 -0
  5. package/dist/filtering/domain-filter.d.ts +9 -0
  6. package/dist/filtering/domain-filter.d.ts.map +1 -0
  7. package/dist/filtering/domain-filter.js +136 -0
  8. package/dist/filtering/domain-filter.js.map +1 -0
  9. package/dist/filtering/header-filter.d.ts +31 -0
  10. package/dist/filtering/header-filter.d.ts.map +1 -0
  11. package/dist/filtering/header-filter.js +187 -0
  12. package/dist/filtering/header-filter.js.map +1 -0
  13. package/dist/filtering/span-filter.d.ts +13 -0
  14. package/dist/filtering/span-filter.d.ts.map +1 -0
  15. package/dist/filtering/span-filter.js +46 -0
  16. package/dist/filtering/span-filter.js.map +1 -0
  17. package/dist/index.d.ts +13 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +13 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/logger.d.ts +21 -0
  22. package/dist/logger.d.ts.map +1 -0
  23. package/dist/logger.js +36 -0
  24. package/dist/logger.js.map +1 -0
  25. package/dist/transport/client.d.ts +46 -0
  26. package/dist/transport/client.d.ts.map +1 -0
  27. package/dist/transport/client.js +110 -0
  28. package/dist/transport/client.js.map +1 -0
  29. package/dist/types.d.ts +34 -0
  30. package/dist/types.d.ts.map +1 -0
  31. package/dist/types.js +5 -0
  32. package/dist/types.js.map +1 -0
  33. package/dist/utils/context-extractor.d.ts +13 -0
  34. package/dist/utils/context-extractor.d.ts.map +1 -0
  35. package/dist/utils/context-extractor.js +44 -0
  36. package/dist/utils/context-extractor.js.map +1 -0
  37. package/dist/utils/span-extractor.d.ts +10 -0
  38. package/dist/utils/span-extractor.d.ts.map +1 -0
  39. package/dist/utils/span-extractor.js +125 -0
  40. package/dist/utils/span-extractor.js.map +1 -0
  41. package/dist/wrap-http.d.ts +55 -0
  42. package/dist/wrap-http.d.ts.map +1 -0
  43. package/dist/wrap-http.js +129 -0
  44. package/dist/wrap-http.js.map +1 -0
  45. package/package.json +34 -0
@@ -0,0 +1,46 @@
1
+ /**
2
+ * HTTP transport client for sending spans to PingOps backend
3
+ * Fire-and-forget, batched, with error handling
4
+ */
5
+ import type { SpanPayload } from '../types';
6
+ export interface TransportConfig {
7
+ apiKey?: string;
8
+ baseUrl: string;
9
+ batchSize?: number;
10
+ batchTimeout?: number;
11
+ debug?: boolean;
12
+ }
13
+ /**
14
+ * HTTP client for PingOps backend
15
+ */
16
+ export declare class PingopsTransportClient {
17
+ private config;
18
+ private batch;
19
+ private batchTimeoutId;
20
+ constructor(config: TransportConfig);
21
+ /**
22
+ * Adds a span to the batch and sends if batch is full
23
+ */
24
+ addSpan(payload: SpanPayload): void;
25
+ /**
26
+ * Sends a span immediately (for immediate export mode)
27
+ */
28
+ sendSpanImmediately(payload: SpanPayload): Promise<void>;
29
+ /**
30
+ * Schedules a flush after batchTimeout
31
+ */
32
+ private scheduleFlush;
33
+ /**
34
+ * Flushes the current batch to the backend
35
+ */
36
+ flush(): void;
37
+ /**
38
+ * Sends a batch of spans to the backend
39
+ */
40
+ private sendBatch;
41
+ /**
42
+ * Forces a flush and waits for completion (for shutdown)
43
+ */
44
+ shutdown(): Promise<void>;
45
+ }
46
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/transport/client.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,qBAAa,sBAAsB;IACjC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,cAAc,CAA+B;gBAEzC,MAAM,EAAE,eAAe;IAanC;;OAEG;IACI,OAAO,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAY1C;;OAEG;IACU,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrE;;OAEG;IACH,OAAO,CAAC,aAAa;IAWrB;;OAEG;IACI,KAAK,IAAI,IAAI;IAsBpB;;OAEG;YACW,SAAS;IA4BvB;;OAEG;IACU,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAKvC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * HTTP transport client for sending spans to PingOps backend
3
+ * Fire-and-forget, batched, with error handling
4
+ */
5
+ /**
6
+ * HTTP client for PingOps backend
7
+ */
8
+ export class PingopsTransportClient {
9
+ config;
10
+ batch = [];
11
+ batchTimeoutId = null;
12
+ constructor(config) {
13
+ // Get API key from config or environment
14
+ const apiKey = config.apiKey || process.env.PINGOPS_API_KEY || '';
15
+ this.config = {
16
+ apiKey,
17
+ baseUrl: config.baseUrl,
18
+ batchSize: config.batchSize ?? 50,
19
+ batchTimeout: config.batchTimeout ?? 5000, // 5 seconds
20
+ debug: config.debug ?? false,
21
+ };
22
+ }
23
+ /**
24
+ * Adds a span to the batch and sends if batch is full
25
+ */
26
+ addSpan(payload) {
27
+ this.batch.push(payload);
28
+ // Send immediately if batch is full
29
+ if (this.batch.length >= this.config.batchSize) {
30
+ this.flush();
31
+ }
32
+ else {
33
+ // Set timeout for sending batch
34
+ this.scheduleFlush();
35
+ }
36
+ }
37
+ /**
38
+ * Sends a span immediately (for immediate export mode)
39
+ */
40
+ async sendSpanImmediately(payload) {
41
+ await this.sendBatch([payload]);
42
+ }
43
+ /**
44
+ * Schedules a flush after batchTimeout
45
+ */
46
+ scheduleFlush() {
47
+ if (this.batchTimeoutId) {
48
+ return; // Already scheduled
49
+ }
50
+ this.batchTimeoutId = setTimeout(() => {
51
+ this.batchTimeoutId = null;
52
+ this.flush();
53
+ }, this.config.batchTimeout);
54
+ }
55
+ /**
56
+ * Flushes the current batch to the backend
57
+ */
58
+ flush() {
59
+ if (this.batch.length === 0) {
60
+ return;
61
+ }
62
+ const batchToSend = [...this.batch];
63
+ this.batch = [];
64
+ if (this.batchTimeoutId) {
65
+ clearTimeout(this.batchTimeoutId);
66
+ this.batchTimeoutId = null;
67
+ }
68
+ // Fire-and-forget: don't await
69
+ this.sendBatch(batchToSend).catch((error) => {
70
+ // Error handling: log but don't crash
71
+ if (this.config.debug) {
72
+ console.error('[PingOps] Failed to send batch:', error);
73
+ }
74
+ });
75
+ }
76
+ /**
77
+ * Sends a batch of spans to the backend
78
+ */
79
+ async sendBatch(spans) {
80
+ const url = `${this.config.baseUrl}/api/v1/spans`;
81
+ const headers = {
82
+ 'Content-Type': 'application/json',
83
+ };
84
+ if (this.config.apiKey) {
85
+ headers['Authorization'] = `Bearer ${this.config.apiKey}`;
86
+ }
87
+ // Use native fetch (Node 20+) or fallback to undici if available
88
+ const response = await fetch(url, {
89
+ method: 'POST',
90
+ headers,
91
+ body: JSON.stringify({ spans }),
92
+ });
93
+ if (!response.ok) {
94
+ const errorText = await response.text().catch(() => 'Unknown error');
95
+ throw new Error(`PingOps API error: ${response.status} ${response.statusText} - ${errorText}`);
96
+ }
97
+ if (this.config.debug) {
98
+ console.log(`[PingOps] Sent ${spans.length} spans successfully`);
99
+ }
100
+ }
101
+ /**
102
+ * Forces a flush and waits for completion (for shutdown)
103
+ */
104
+ async shutdown() {
105
+ this.flush();
106
+ // Give a small delay for the async send to complete
107
+ await new Promise((resolve) => setTimeout(resolve, 100));
108
+ }
109
+ }
110
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/transport/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Shared type definitions for PingOps SDK
3
+ */
4
+ export interface DomainRule {
5
+ domain: string;
6
+ paths?: string[];
7
+ headersAllowList?: string[];
8
+ headersDenyList?: string[];
9
+ }
10
+ export interface SpanPayload {
11
+ traceId: string;
12
+ spanId: string;
13
+ parentSpanId?: string;
14
+ name: string;
15
+ kind: string;
16
+ startTime: string;
17
+ endTime: string;
18
+ duration: number;
19
+ attributes: Record<string, unknown>;
20
+ status: {
21
+ code: string;
22
+ message?: string;
23
+ };
24
+ }
25
+ /**
26
+ * Attributes to propagate to HTTP spans
27
+ */
28
+ export interface WrapHttpAttributes {
29
+ userId?: string;
30
+ sessionId?: string;
31
+ tags?: string[];
32
+ metadata?: Record<string, string>;
33
+ }
34
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,MAAM,EAAE;QACN,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC"}
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shared type definitions for PingOps SDK
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Extracts propagated attributes from OpenTelemetry context
3
+ */
4
+ import type { Context } from "@opentelemetry/api";
5
+ /**
6
+ * Extracts propagated attributes from the given context and returns them
7
+ * as span attributes that can be set on a span.
8
+ *
9
+ * @param parentContext - The OpenTelemetry context to extract attributes from
10
+ * @returns Record of attribute key-value pairs to set on spans
11
+ */
12
+ export declare function getPropagatedAttributesFromContext(parentContext: Context): Record<string, string | string[]>;
13
+ //# sourceMappingURL=context-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-extractor.d.ts","sourceRoot":"","sources":["../../src/utils/context-extractor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAQlD;;;;;;GAMG;AACH,wBAAgB,kCAAkC,CAChD,aAAa,EAAE,OAAO,GACrB,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAsCnC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Extracts propagated attributes from OpenTelemetry context
3
+ */
4
+ import { PINGOPS_USER_ID, PINGOPS_SESSION_ID, PINGOPS_TAGS, PINGOPS_METADATA, } from "../context-keys";
5
+ /**
6
+ * Extracts propagated attributes from the given context and returns them
7
+ * as span attributes that can be set on a span.
8
+ *
9
+ * @param parentContext - The OpenTelemetry context to extract attributes from
10
+ * @returns Record of attribute key-value pairs to set on spans
11
+ */
12
+ export function getPropagatedAttributesFromContext(parentContext) {
13
+ const attributes = {};
14
+ // Extract userId
15
+ const userId = parentContext.getValue(PINGOPS_USER_ID);
16
+ if (userId !== undefined && typeof userId === "string") {
17
+ attributes["pingops.user_id"] = userId;
18
+ }
19
+ // Extract sessionId
20
+ const sessionId = parentContext.getValue(PINGOPS_SESSION_ID);
21
+ if (sessionId !== undefined && typeof sessionId === "string") {
22
+ attributes["pingops.session_id"] = sessionId;
23
+ }
24
+ // Extract tags
25
+ const tags = parentContext.getValue(PINGOPS_TAGS);
26
+ if (tags !== undefined && Array.isArray(tags)) {
27
+ attributes["pingops.tags"] = tags;
28
+ }
29
+ // Extract metadata
30
+ const metadata = parentContext.getValue(PINGOPS_METADATA);
31
+ if (metadata !== undefined &&
32
+ typeof metadata === "object" &&
33
+ metadata !== null &&
34
+ !Array.isArray(metadata)) {
35
+ // Flatten metadata object into span attributes with prefix
36
+ for (const [key, value] of Object.entries(metadata)) {
37
+ if (typeof value === "string") {
38
+ attributes[`pingops.metadata.${key}`] = value;
39
+ }
40
+ }
41
+ }
42
+ return attributes;
43
+ }
44
+ //# sourceMappingURL=context-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-extractor.js","sourceRoot":"","sources":["../../src/utils/context-extractor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,YAAY,EACZ,gBAAgB,GACjB,MAAM,iBAAiB,CAAC;AAEzB;;;;;;GAMG;AACH,MAAM,UAAU,kCAAkC,CAChD,aAAsB;IAEtB,MAAM,UAAU,GAAsC,EAAE,CAAC;IAEzD,iBAAiB;IACjB,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IACvD,IAAI,MAAM,KAAK,SAAS,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QACvD,UAAU,CAAC,iBAAiB,CAAC,GAAG,MAAM,CAAC;IACzC,CAAC;IAED,oBAAoB;IACpB,MAAM,SAAS,GAAG,aAAa,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAC7D,IAAI,SAAS,KAAK,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC7D,UAAU,CAAC,oBAAoB,CAAC,GAAG,SAAS,CAAC;IAC/C,CAAC;IAED,eAAe;IACf,MAAM,IAAI,GAAG,aAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9C,UAAU,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IACpC,CAAC;IAED,mBAAmB;IACnB,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC;IAC1D,IACE,QAAQ,KAAK,SAAS;QACtB,OAAO,QAAQ,KAAK,QAAQ;QAC5B,QAAQ,KAAK,IAAI;QACjB,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EACxB,CAAC;QACD,2DAA2D;QAC3D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC9B,UAAU,CAAC,oBAAoB,GAAG,EAAE,CAAC,GAAG,KAAK,CAAC;YAChD,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Extracts structured data from spans for PingOps backend
3
+ */
4
+ import type { ReadableSpan } from "@opentelemetry/sdk-trace-base";
5
+ import type { DomainRule, SpanPayload } from "../types";
6
+ /**
7
+ * Extracts structured payload from a span
8
+ */
9
+ export declare function extractSpanPayload(span: ReadableSpan, domainAllowList?: DomainRule[], globalHeadersAllowList?: string[], globalHeadersDenyList?: string[]): SpanPayload | null;
10
+ //# sourceMappingURL=span-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"span-extractor.d.ts","sourceRoot":"","sources":["../../src/utils/span-extractor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AA2CxD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,YAAY,EAClB,eAAe,CAAC,EAAE,UAAU,EAAE,EAC9B,sBAAsB,CAAC,EAAE,MAAM,EAAE,EACjC,qBAAqB,CAAC,EAAE,MAAM,EAAE,GAC/B,WAAW,GAAG,IAAI,CAwIpB"}
@@ -0,0 +1,125 @@
1
+ /**
2
+ * Extracts structured data from spans for PingOps backend
3
+ */
4
+ import { filterHeaders, extractHeadersFromAttributes, } from "../filtering/header-filter";
5
+ /**
6
+ * Extracts domain from URL
7
+ */
8
+ function extractDomainFromUrl(url) {
9
+ try {
10
+ const urlObj = new URL(url);
11
+ return urlObj.hostname;
12
+ }
13
+ catch {
14
+ const match = url.match(/^(?:https?:\/\/)?([^/]+)/);
15
+ return match ? match[1] : "";
16
+ }
17
+ }
18
+ /**
19
+ * Gets domain rule configuration for a given URL
20
+ */
21
+ function getDomainRule(url, domainAllowList) {
22
+ if (!domainAllowList) {
23
+ return undefined;
24
+ }
25
+ const domain = extractDomainFromUrl(url);
26
+ for (const rule of domainAllowList) {
27
+ if (domain === rule.domain ||
28
+ domain.endsWith(`.${rule.domain}`) ||
29
+ domain === rule.domain.slice(1)) {
30
+ return rule;
31
+ }
32
+ }
33
+ return undefined;
34
+ }
35
+ /**
36
+ * Extracts structured payload from a span
37
+ */
38
+ export function extractSpanPayload(span, domainAllowList, globalHeadersAllowList, globalHeadersDenyList) {
39
+ const attributes = span.attributes;
40
+ const url = attributes["http.url"] || attributes["url.full"];
41
+ // Get domain-specific rule if available
42
+ const domainRule = url ? getDomainRule(url, domainAllowList) : undefined;
43
+ // Merge global and domain-specific header rules
44
+ const headersAllowList = domainRule?.headersAllowList ?? globalHeadersAllowList;
45
+ const headersDenyList = domainRule?.headersDenyList ?? globalHeadersDenyList;
46
+ // Extract HTTP headers if available
47
+ let requestHeaders = {};
48
+ let responseHeaders = {};
49
+ // First, try to extract flat array format headers (e.g., 'http.request.header.0', 'http.request.header.1')
50
+ const flatRequestHeaders = extractHeadersFromAttributes(attributes, "http.request.header");
51
+ const flatResponseHeaders = extractHeadersFromAttributes(attributes, "http.response.header");
52
+ // Try to get headers from attributes (format may vary by instrumentation)
53
+ const httpRequestHeadersValue = attributes["http.request.header"];
54
+ const httpResponseHeadersValue = attributes["http.response.header"];
55
+ // Type guard: check if value is a record/object with string keys
56
+ const isHeadersRecord = (value) => {
57
+ return (typeof value === "object" &&
58
+ value !== null &&
59
+ !Array.isArray(value) &&
60
+ Object.values(value).every((v) => typeof v === "string" ||
61
+ (Array.isArray(v) && v.every((item) => typeof item === "string")) ||
62
+ v === undefined));
63
+ };
64
+ // Use flat array format if available, otherwise use direct attribute
65
+ if (flatRequestHeaders) {
66
+ requestHeaders = filterHeaders(flatRequestHeaders, headersAllowList, headersDenyList);
67
+ }
68
+ else if (isHeadersRecord(httpRequestHeadersValue)) {
69
+ requestHeaders = filterHeaders(httpRequestHeadersValue, headersAllowList, headersDenyList);
70
+ }
71
+ if (flatResponseHeaders) {
72
+ responseHeaders = filterHeaders(flatResponseHeaders, headersAllowList, headersDenyList);
73
+ }
74
+ else if (isHeadersRecord(httpResponseHeadersValue)) {
75
+ responseHeaders = filterHeaders(httpResponseHeadersValue, headersAllowList, headersDenyList);
76
+ }
77
+ // Build attributes object
78
+ const extractedAttributes = {
79
+ ...attributes,
80
+ };
81
+ // Remove flat array format headers (e.g., 'http.request.header.0', 'http.request.header.1', etc.)
82
+ // We'll replace them with the proper key-value format
83
+ for (const key in extractedAttributes) {
84
+ if ((key.startsWith("http.request.header.") &&
85
+ key !== "http.request.header") ||
86
+ (key.startsWith("http.response.header.") &&
87
+ key !== "http.response.header")) {
88
+ // Check if it's a numeric index (flat array format)
89
+ const match = key.match(/^(http\.(?:request|response)\.header)\.(\d+)$/);
90
+ if (match) {
91
+ delete extractedAttributes[key];
92
+ }
93
+ }
94
+ }
95
+ // Add filtered headers in proper key-value format
96
+ if (Object.keys(requestHeaders).length > 0) {
97
+ extractedAttributes["http.request.header"] = requestHeaders;
98
+ }
99
+ if (Object.keys(responseHeaders).length > 0) {
100
+ extractedAttributes["http.response.header"] = responseHeaders;
101
+ }
102
+ // Build span payload
103
+ const spanContext = span.spanContext();
104
+ // parentSpanId may not be available in all versions of ReadableSpan
105
+ const parentSpanId = "parentSpanId" in span
106
+ ? span.parentSpanId
107
+ : undefined;
108
+ return {
109
+ traceId: spanContext.traceId,
110
+ spanId: spanContext.spanId,
111
+ parentSpanId,
112
+ name: span.name,
113
+ kind: span.kind.toString(),
114
+ startTime: new Date(span.startTime[0] * 1000 + span.startTime[1] / 1000000).toISOString(),
115
+ endTime: new Date(span.endTime[0] * 1000 + span.endTime[1] / 1000000).toISOString(),
116
+ duration: (span.endTime[0] - span.startTime[0]) * 1000 +
117
+ (span.endTime[1] - span.startTime[1]) / 1000000,
118
+ attributes: extractedAttributes,
119
+ status: {
120
+ code: span.status.code.toString(),
121
+ message: span.status.message,
122
+ },
123
+ };
124
+ }
125
+ //# sourceMappingURL=span-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"span-extractor.js","sourceRoot":"","sources":["../../src/utils/span-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * wrapHttp - Wraps a function to set attributes on HTTP spans created within the wrapped block.
3
+ *
4
+ * This function sets attributes (userId, sessionId, tags, metadata) in the OpenTelemetry
5
+ * context, which are automatically propagated to all spans created within the wrapped function.
6
+ *
7
+ * Instrumentation behavior:
8
+ * - If `initializePingops` was called: All HTTP requests are instrumented by default.
9
+ * `wrapHttp` only adds attributes to spans created within the wrapped block.
10
+ * - If `initializePingops` was NOT called: Only HTTP requests within `wrapHttp` blocks
11
+ * are instrumented. Requests outside `wrapHttp` are not instrumented.
12
+ */
13
+ import type { WrapHttpAttributes } from "./types";
14
+ /**
15
+ * Options for wrapHttp function
16
+ */
17
+ export interface WrapHttpOptions {
18
+ attributes?: WrapHttpAttributes;
19
+ /**
20
+ * Callback to check if SDK is initialized.
21
+ * Required to determine if global instrumentation is enabled.
22
+ */
23
+ checkInitialized: () => boolean;
24
+ /**
25
+ * Callback to check if global instrumentation is enabled.
26
+ * Required to determine instrumentation behavior.
27
+ */
28
+ isGlobalInstrumentationEnabled: () => boolean;
29
+ /**
30
+ * Optional callback to ensure SDK is initialized (auto-initialization).
31
+ * If not provided, wrapHttp will try to auto-initialize from environment variables.
32
+ */
33
+ ensureInitialized?: () => Promise<void>;
34
+ }
35
+ /**
36
+ * Wraps a function to set attributes on HTTP spans created within the wrapped block.
37
+ *
38
+ * This function sets attributes (userId, sessionId, tags, metadata) in the OpenTelemetry
39
+ * context, which are automatically propagated to all spans created within the wrapped function.
40
+ *
41
+ * Instrumentation behavior:
42
+ * - If `initializePingops` was called: All HTTP requests are instrumented by default.
43
+ * `wrapHttp` only adds attributes to spans created within the wrapped block.
44
+ * - If `initializePingops` was NOT called: Only HTTP requests within `wrapHttp` blocks
45
+ * are instrumented. Requests outside `wrapHttp` are not instrumented.
46
+ *
47
+ * Note: This is the low-level API. For a simpler API with automatic setup,
48
+ * use `wrapHttp` from `@pingops/sdk` instead.
49
+ *
50
+ * @param options - Options including attributes and required callbacks
51
+ * @param fn - Function to execute within the attribute context
52
+ * @returns The result of the function
53
+ */
54
+ export declare function wrapHttp<T>(options: WrapHttpOptions, fn: () => T | Promise<T>): T | Promise<T>;
55
+ //# sourceMappingURL=wrap-http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap-http.d.ts","sourceRoot":"","sources":["../src/wrap-http.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAWH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAIlD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC;;;OAGG;IACH,gBAAgB,EAAE,MAAM,OAAO,CAAC;IAChC;;;OAGG;IACH,8BAA8B,EAAE,MAAM,OAAO,CAAC;IAC9C;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CACzC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,QAAQ,CAAC,CAAC,EACxB,OAAO,EAAE,eAAe,EACxB,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoDhB"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * wrapHttp - Wraps a function to set attributes on HTTP spans created within the wrapped block.
3
+ *
4
+ * This function sets attributes (userId, sessionId, tags, metadata) in the OpenTelemetry
5
+ * context, which are automatically propagated to all spans created within the wrapped function.
6
+ *
7
+ * Instrumentation behavior:
8
+ * - If `initializePingops` was called: All HTTP requests are instrumented by default.
9
+ * `wrapHttp` only adds attributes to spans created within the wrapped block.
10
+ * - If `initializePingops` was NOT called: Only HTTP requests within `wrapHttp` blocks
11
+ * are instrumented. Requests outside `wrapHttp` are not instrumented.
12
+ */
13
+ import { context } from "@opentelemetry/api";
14
+ import { createLogger } from "./logger";
15
+ import { PINGOPS_HTTP_ENABLED, PINGOPS_USER_ID, PINGOPS_SESSION_ID, PINGOPS_TAGS, PINGOPS_METADATA, } from "./context-keys";
16
+ const logger = createLogger("[PingOps wrapHttp]");
17
+ /**
18
+ * Wraps a function to set attributes on HTTP spans created within the wrapped block.
19
+ *
20
+ * This function sets attributes (userId, sessionId, tags, metadata) in the OpenTelemetry
21
+ * context, which are automatically propagated to all spans created within the wrapped function.
22
+ *
23
+ * Instrumentation behavior:
24
+ * - If `initializePingops` was called: All HTTP requests are instrumented by default.
25
+ * `wrapHttp` only adds attributes to spans created within the wrapped block.
26
+ * - If `initializePingops` was NOT called: Only HTTP requests within `wrapHttp` blocks
27
+ * are instrumented. Requests outside `wrapHttp` are not instrumented.
28
+ *
29
+ * Note: This is the low-level API. For a simpler API with automatic setup,
30
+ * use `wrapHttp` from `@pingops/sdk` instead.
31
+ *
32
+ * @param options - Options including attributes and required callbacks
33
+ * @param fn - Function to execute within the attribute context
34
+ * @returns The result of the function
35
+ */
36
+ export function wrapHttp(options, fn) {
37
+ logger.debug("wrapHttp called", {
38
+ hasAttributes: !!options.attributes,
39
+ hasUserId: !!options.attributes?.userId,
40
+ hasSessionId: !!options.attributes?.sessionId,
41
+ hasTags: !!options.attributes?.tags,
42
+ hasMetadata: !!options.attributes?.metadata,
43
+ });
44
+ // Normalize options - if just attributes provided, it means callbacks are required
45
+ // This is a type error at compile time, but we handle it gracefully
46
+ const normalizedOptions = "checkInitialized" in options && "isGlobalInstrumentationEnabled" in options
47
+ ? options
48
+ : (() => {
49
+ throw new Error("wrapHttp requires checkInitialized and isGlobalInstrumentationEnabled callbacks. Use wrapHttp from @pingops/sdk for automatic setup.");
50
+ })();
51
+ const { checkInitialized, ensureInitialized } = normalizedOptions;
52
+ // Ensure SDK is initialized so that span processor can extract attributes
53
+ // If already initialized, execute synchronously
54
+ if (checkInitialized()) {
55
+ logger.debug("SDK already initialized, executing wrapHttp synchronously");
56
+ return executeWrapHttpWithContext(normalizedOptions, fn);
57
+ }
58
+ // If not initialized, we need to initialize first (async)
59
+ if (ensureInitialized) {
60
+ logger.debug("SDK not initialized, using provided ensureInitialized callback");
61
+ return ensureInitialized()
62
+ .then(() => {
63
+ logger.debug("SDK initialized, executing wrapHttp");
64
+ return executeWrapHttpWithContext(normalizedOptions, fn);
65
+ })
66
+ .catch((error) => {
67
+ logger.error("Failed to initialize SDK for wrapHttp", {
68
+ error: error instanceof Error ? error.message : String(error),
69
+ });
70
+ throw error;
71
+ });
72
+ }
73
+ // No ensureInitialized callback provided, execute without initialization
74
+ logger.debug("SDK not initialized and no ensureInitialized callback provided, executing wrapHttp");
75
+ return executeWrapHttpWithContext(normalizedOptions, fn);
76
+ }
77
+ function executeWrapHttpWithContext(options, fn) {
78
+ const { attributes, isGlobalInstrumentationEnabled } = options;
79
+ const globalInstrumentationEnabled = isGlobalInstrumentationEnabled();
80
+ logger.debug("Executing wrapHttp context", {
81
+ hasAttributes: !!attributes,
82
+ globalInstrumentationEnabled,
83
+ });
84
+ const activeContext = context.active();
85
+ // If global instrumentation is not enabled, enable HTTP instrumentation
86
+ // for this block only. If it's enabled, all requests are already instrumented.
87
+ let contextWithAttributes = activeContext;
88
+ if (!globalInstrumentationEnabled) {
89
+ contextWithAttributes = contextWithAttributes.setValue(PINGOPS_HTTP_ENABLED, true);
90
+ }
91
+ // Set attributes in context if provided
92
+ // These will be propagated to all spans created within the wrapped function
93
+ if (attributes) {
94
+ if (attributes.userId !== undefined) {
95
+ contextWithAttributes = contextWithAttributes.setValue(PINGOPS_USER_ID, attributes.userId);
96
+ }
97
+ if (attributes.sessionId !== undefined) {
98
+ contextWithAttributes = contextWithAttributes.setValue(PINGOPS_SESSION_ID, attributes.sessionId);
99
+ }
100
+ if (attributes.tags !== undefined) {
101
+ contextWithAttributes = contextWithAttributes.setValue(PINGOPS_TAGS, attributes.tags);
102
+ }
103
+ if (attributes.metadata !== undefined) {
104
+ contextWithAttributes = contextWithAttributes.setValue(PINGOPS_METADATA, attributes.metadata);
105
+ }
106
+ }
107
+ // Run user code inside the context with attributes
108
+ return context.with(contextWithAttributes, () => {
109
+ try {
110
+ const result = fn();
111
+ if (result instanceof Promise) {
112
+ return result.catch((err) => {
113
+ logger.error("Error in wrapHttp async execution", {
114
+ error: err instanceof Error ? err.message : String(err),
115
+ });
116
+ throw err;
117
+ });
118
+ }
119
+ return result;
120
+ }
121
+ catch (err) {
122
+ logger.error("Error in wrapHttp sync execution", {
123
+ error: err instanceof Error ? err.message : String(err),
124
+ });
125
+ throw err;
126
+ }
127
+ });
128
+ }
129
+ //# sourceMappingURL=wrap-http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap-http.js","sourceRoot":"","sources":["../src/wrap-http.ts"],"names":[],"mappings":"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"}