@pingops/otel 0.1.0 → 0.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/dist/config-store.d.ts +26 -0
- package/dist/config-store.d.ts.map +1 -0
- package/dist/config-store.js +26 -0
- package/dist/config-store.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/instrumentations/http/http.d.ts +13 -0
- package/dist/instrumentations/http/http.d.ts.map +1 -0
- package/dist/instrumentations/{http.js → http/http.js} +6 -16
- package/dist/instrumentations/http/http.js.map +1 -0
- package/dist/instrumentations/http/pingops-http.d.ts +52 -0
- package/dist/instrumentations/http/pingops-http.d.ts.map +1 -0
- package/dist/instrumentations/http/pingops-http.js +381 -0
- package/dist/instrumentations/http/pingops-http.js.map +1 -0
- package/dist/instrumentations/index.d.ts.map +1 -1
- package/dist/instrumentations/index.js +6 -10
- package/dist/instrumentations/index.js.map +1 -1
- package/dist/instrumentations/undici/pingops-undici.d.ts +25 -0
- package/dist/instrumentations/undici/pingops-undici.d.ts.map +1 -0
- package/dist/instrumentations/undici/pingops-undici.js +568 -0
- package/dist/instrumentations/undici/pingops-undici.js.map +1 -0
- package/dist/instrumentations/undici/types.d.ts +106 -0
- package/dist/instrumentations/undici/types.d.ts.map +1 -0
- package/dist/instrumentations/undici/types.js +2 -0
- package/dist/instrumentations/undici/types.js.map +1 -0
- package/dist/instrumentations/{undici.d.ts → undici/undici.d.ts} +1 -1
- package/dist/instrumentations/undici/undici.d.ts.map +1 -0
- package/dist/instrumentations/{undici.js → undici/undici.js} +1 -13
- package/dist/instrumentations/undici/undici.js.map +1 -0
- package/dist/span-processor.d.ts.map +1 -1
- package/dist/span-processor.js +31 -21
- package/dist/span-processor.js.map +1 -1
- package/dist/tracer-provider.d.ts.map +1 -1
- package/dist/tracer-provider.js +22 -20
- package/dist/tracer-provider.js.map +1 -1
- package/package.json +7 -7
- package/dist/instrumentations/body-extractor.d.ts +0 -48
- package/dist/instrumentations/body-extractor.d.ts.map +0 -1
- package/dist/instrumentations/body-extractor.js +0 -361
- package/dist/instrumentations/body-extractor.js.map +0 -1
- package/dist/instrumentations/http.d.ts +0 -12
- package/dist/instrumentations/http.d.ts.map +0 -1
- package/dist/instrumentations/http.js.map +0 -1
- package/dist/instrumentations/undici.d.ts.map +0 -1
- package/dist/instrumentations/undici.js.map +0 -1
- package/dist/processor.d.ts +0 -82
- package/dist/processor.d.ts.map +0 -1
- package/dist/processor.js +0 -264
- package/dist/processor.js.map +0 -1
- package/dist/span-wrapper.d.ts +0 -60
- package/dist/span-wrapper.d.ts.map +0 -1
- package/dist/span-wrapper.js +0 -118
- package/dist/span-wrapper.js.map +0 -1
package/dist/processor.js
DELETED
|
@@ -1,264 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PingopsSpanProcessor - OpenTelemetry SpanProcessor implementation
|
|
3
|
-
* Observes finished spans and sends eligible ones to PingOps backend
|
|
4
|
-
*
|
|
5
|
-
* This processor provides:
|
|
6
|
-
* - Automatic filtering of spans (CLIENT spans with HTTP/GenAI attributes only)
|
|
7
|
-
* - Domain and header filtering based on configuration
|
|
8
|
-
* - Batched or immediate export modes using OTLP exporters
|
|
9
|
-
* - Fire-and-forget transport (never blocks application)
|
|
10
|
-
*
|
|
11
|
-
* @example
|
|
12
|
-
* ```typescript
|
|
13
|
-
* import { NodeSDK } from '@opentelemetry/sdk-node';
|
|
14
|
-
* import { PingopsSpanProcessor } from '@pingops/otel';
|
|
15
|
-
*
|
|
16
|
-
* const sdk = new NodeSDK({
|
|
17
|
-
* spanProcessors: [
|
|
18
|
-
* new PingopsSpanProcessor({
|
|
19
|
-
* apiKey: 'your-api-key',
|
|
20
|
-
* baseUrl: 'https://api.pingops.com',
|
|
21
|
-
* serviceName: 'my-service',
|
|
22
|
-
* exportMode: 'batched', // or 'immediate'
|
|
23
|
-
* domainAllowList: [
|
|
24
|
-
* { domain: 'api.example.com' }
|
|
25
|
-
* ]
|
|
26
|
-
* })
|
|
27
|
-
* ]
|
|
28
|
-
* });
|
|
29
|
-
*
|
|
30
|
-
* sdk.start();
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
import { BatchSpanProcessor, SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
|
|
34
|
-
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
|
|
35
|
-
import { isSpanEligible, shouldCaptureSpan, createLogger, } from '@pingops/core';
|
|
36
|
-
import { PINGOPS_PARENT_SPAN_ATTRIBUTES_KEY } from '@pingops/core';
|
|
37
|
-
const log = createLogger('[PingOps Processor]');
|
|
38
|
-
/**
|
|
39
|
-
* OpenTelemetry span processor for sending spans to PingOps backend.
|
|
40
|
-
*
|
|
41
|
-
* This processor wraps OpenTelemetry's built-in processors (BatchSpanProcessor or SimpleSpanProcessor)
|
|
42
|
-
* and applies filtering before passing spans to the OTLP exporter.
|
|
43
|
-
*/
|
|
44
|
-
export class PingopsSpanProcessor {
|
|
45
|
-
processor;
|
|
46
|
-
config;
|
|
47
|
-
/**
|
|
48
|
-
* Creates a new PingopsSpanProcessor instance.
|
|
49
|
-
*
|
|
50
|
-
* @param config - Configuration parameters for the processor
|
|
51
|
-
*/
|
|
52
|
-
constructor(config) {
|
|
53
|
-
const exportMode = config.exportMode ?? 'batched';
|
|
54
|
-
// Get API key from config or environment
|
|
55
|
-
const apiKey = config.apiKey || process.env.PINGOPS_API_KEY || '';
|
|
56
|
-
// Create OTLP exporter pointing to PingOps backend
|
|
57
|
-
const exporter = new OTLPTraceExporter({
|
|
58
|
-
url: `${config.baseUrl}/v1/traces`,
|
|
59
|
-
headers: {
|
|
60
|
-
'Authorization': apiKey ? `Bearer ${apiKey}` : '',
|
|
61
|
-
'Content-Type': 'application/json',
|
|
62
|
-
},
|
|
63
|
-
timeoutMillis: 5000,
|
|
64
|
-
});
|
|
65
|
-
// Create underlying processor based on export mode
|
|
66
|
-
if (exportMode === 'immediate') {
|
|
67
|
-
this.processor = new SimpleSpanProcessor(exporter);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
this.processor = new BatchSpanProcessor(exporter, {
|
|
71
|
-
maxExportBatchSize: config.batchSize ?? 50,
|
|
72
|
-
scheduledDelayMillis: config.batchTimeout ?? 5000,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
this.config = {
|
|
76
|
-
debug: config.debug ?? false,
|
|
77
|
-
headersAllowList: config.headersAllowList,
|
|
78
|
-
headersDenyList: config.headersDenyList,
|
|
79
|
-
domainAllowList: config.domainAllowList,
|
|
80
|
-
domainDenyList: config.domainDenyList,
|
|
81
|
-
};
|
|
82
|
-
log.info('Initialized PingopsSpanProcessor', {
|
|
83
|
-
baseUrl: config.baseUrl,
|
|
84
|
-
exportMode,
|
|
85
|
-
batchSize: config.batchSize,
|
|
86
|
-
batchTimeout: config.batchTimeout,
|
|
87
|
-
hasDomainAllowList: !!config.domainAllowList && config.domainAllowList.length > 0,
|
|
88
|
-
hasDomainDenyList: !!config.domainDenyList && config.domainDenyList.length > 0,
|
|
89
|
-
hasHeadersAllowList: !!config.headersAllowList && config.headersAllowList.length > 0,
|
|
90
|
-
hasHeadersDenyList: !!config.headersDenyList && config.headersDenyList.length > 0,
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* Called when a span starts - extracts parent attributes from context and adds them to the span
|
|
95
|
-
*/
|
|
96
|
-
onStart(span, parentContext) {
|
|
97
|
-
const spanContext = span.spanContext();
|
|
98
|
-
log.debug('Span started', {
|
|
99
|
-
spanName: span.name,
|
|
100
|
-
spanId: spanContext.spanId,
|
|
101
|
-
traceId: spanContext.traceId,
|
|
102
|
-
});
|
|
103
|
-
// Extract parent span attributes from context and add them to this span
|
|
104
|
-
// This allows child spans (like HTTP spans) to inherit custom attributes from parent spans
|
|
105
|
-
const parentAttributes = parentContext.getValue(PINGOPS_PARENT_SPAN_ATTRIBUTES_KEY);
|
|
106
|
-
if (parentAttributes && Object.keys(parentAttributes).length > 0) {
|
|
107
|
-
// Filter out HTTP/GenAI attributes - we only want custom attributes
|
|
108
|
-
const customAttributes = this.extractCustomAttributes(parentAttributes);
|
|
109
|
-
if (Object.keys(customAttributes).length > 0) {
|
|
110
|
-
// Convert to Attributes type (string | number | boolean | string[] | undefined)
|
|
111
|
-
const attributesToSet = {};
|
|
112
|
-
for (const [key, value] of Object.entries(customAttributes)) {
|
|
113
|
-
// Only set valid attribute types
|
|
114
|
-
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || Array.isArray(value)) {
|
|
115
|
-
attributesToSet[key] = value;
|
|
116
|
-
}
|
|
117
|
-
else if (value !== null && value !== undefined) {
|
|
118
|
-
// Convert other types to string
|
|
119
|
-
attributesToSet[key] = String(value);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
span.setAttributes(attributesToSet);
|
|
123
|
-
log.debug('Added parent span attributes to child span', {
|
|
124
|
-
spanName: span.name,
|
|
125
|
-
spanId: spanContext.spanId,
|
|
126
|
-
attributeCount: Object.keys(attributesToSet).length,
|
|
127
|
-
attributes: Object.keys(attributesToSet),
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
this.processor.onStart(span, parentContext);
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Extracts custom attributes (non-HTTP, non-GenAI) from attributes.
|
|
135
|
-
* These are attributes that were added manually via updateActiveSpan.
|
|
136
|
-
*/
|
|
137
|
-
extractCustomAttributes(attributes) {
|
|
138
|
-
const customAttributes = {};
|
|
139
|
-
// List of HTTP attribute prefixes to exclude
|
|
140
|
-
const httpPrefixes = ['http.', 'url.', 'server.', 'network.', 'user_agent.'];
|
|
141
|
-
// List of GenAI attribute prefixes to exclude
|
|
142
|
-
const genAiPrefixes = ['gen_ai.', 'genai.'];
|
|
143
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
144
|
-
// Skip HTTP and GenAI attributes
|
|
145
|
-
const isHttpAttribute = httpPrefixes.some(prefix => key.startsWith(prefix));
|
|
146
|
-
const isGenAiAttribute = genAiPrefixes.some(prefix => key.startsWith(prefix));
|
|
147
|
-
if (!isHttpAttribute && !isGenAiAttribute) {
|
|
148
|
-
customAttributes[key] = value;
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return customAttributes;
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* Called when a span ends. Filters the span and passes it to the underlying processor if eligible.
|
|
155
|
-
*
|
|
156
|
-
* This method:
|
|
157
|
-
* 1. Checks if the span is eligible (CLIENT + HTTP/GenAI attributes)
|
|
158
|
-
* 2. Applies domain filtering
|
|
159
|
-
* 3. If eligible, passes span to underlying OTLP processor for export
|
|
160
|
-
*/
|
|
161
|
-
onEnd(span) {
|
|
162
|
-
const spanContext = span.spanContext();
|
|
163
|
-
log.debug('Span ended, processing', {
|
|
164
|
-
spanName: span.name,
|
|
165
|
-
spanId: spanContext.spanId,
|
|
166
|
-
traceId: spanContext.traceId,
|
|
167
|
-
spanKind: span.kind,
|
|
168
|
-
});
|
|
169
|
-
try {
|
|
170
|
-
// Step 1: Check if span is eligible (CLIENT + HTTP/GenAI attributes)
|
|
171
|
-
if (!isSpanEligible(span)) {
|
|
172
|
-
log.debug('Span not eligible, skipping', {
|
|
173
|
-
spanName: span.name,
|
|
174
|
-
spanId: spanContext.spanId,
|
|
175
|
-
reason: 'not CLIENT or missing HTTP/GenAI attributes',
|
|
176
|
-
});
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
// Step 2: Extract URL for domain filtering
|
|
180
|
-
const attributes = span.attributes;
|
|
181
|
-
const url = attributes['http.url'] ||
|
|
182
|
-
attributes['url.full'] ||
|
|
183
|
-
(attributes['server.address'] ? `https://${attributes['server.address']}` : '');
|
|
184
|
-
log.debug('Extracted URL for domain filtering', {
|
|
185
|
-
spanName: span.name,
|
|
186
|
-
url,
|
|
187
|
-
hasHttpUrl: !!attributes['http.url'],
|
|
188
|
-
hasUrlFull: !!attributes['url.full'],
|
|
189
|
-
hasServerAddress: !!attributes['server.address'],
|
|
190
|
-
});
|
|
191
|
-
// Step 3: Apply domain filtering
|
|
192
|
-
if (url) {
|
|
193
|
-
const shouldCapture = shouldCaptureSpan(url, this.config.domainAllowList, this.config.domainDenyList);
|
|
194
|
-
if (!shouldCapture) {
|
|
195
|
-
log.info('Span filtered out by domain rules', {
|
|
196
|
-
spanName: span.name,
|
|
197
|
-
spanId: spanContext.spanId,
|
|
198
|
-
url,
|
|
199
|
-
});
|
|
200
|
-
return;
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
else {
|
|
204
|
-
log.debug('No URL found for domain filtering, proceeding', {
|
|
205
|
-
spanName: span.name,
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
// Step 4: Span passed all filters, pass to underlying processor for export
|
|
209
|
-
this.processor.onEnd(span);
|
|
210
|
-
log.info('Span passed all filters and queued for export', {
|
|
211
|
-
spanName: span.name,
|
|
212
|
-
spanId: spanContext.spanId,
|
|
213
|
-
traceId: spanContext.traceId,
|
|
214
|
-
attributes: span.attributes,
|
|
215
|
-
url,
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
catch (error) {
|
|
219
|
-
// Defensive error handling - never crash the app
|
|
220
|
-
log.error('Error processing span', {
|
|
221
|
-
spanName: span.name,
|
|
222
|
-
spanId: spanContext.spanId,
|
|
223
|
-
error: error instanceof Error ? error.message : String(error),
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
/**
|
|
228
|
-
* Forces an immediate flush of all pending spans.
|
|
229
|
-
*
|
|
230
|
-
* @returns Promise that resolves when all pending operations are complete
|
|
231
|
-
*/
|
|
232
|
-
async forceFlush() {
|
|
233
|
-
log.info('Force flushing spans');
|
|
234
|
-
try {
|
|
235
|
-
await this.processor.forceFlush();
|
|
236
|
-
log.info('Force flush complete');
|
|
237
|
-
}
|
|
238
|
-
catch (error) {
|
|
239
|
-
log.error('Error during force flush', {
|
|
240
|
-
error: error instanceof Error ? error.message : String(error),
|
|
241
|
-
});
|
|
242
|
-
throw error;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
/**
|
|
246
|
-
* Gracefully shuts down the processor, ensuring all pending operations are completed.
|
|
247
|
-
*
|
|
248
|
-
* @returns Promise that resolves when shutdown is complete
|
|
249
|
-
*/
|
|
250
|
-
async shutdown() {
|
|
251
|
-
log.info('Shutting down processor');
|
|
252
|
-
try {
|
|
253
|
-
await this.processor.shutdown();
|
|
254
|
-
log.info('Processor shutdown complete');
|
|
255
|
-
}
|
|
256
|
-
catch (error) {
|
|
257
|
-
log.error('Error during processor shutdown', {
|
|
258
|
-
error: error instanceof Error ? error.message : String(error),
|
|
259
|
-
});
|
|
260
|
-
throw error;
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
//# sourceMappingURL=processor.js.map
|
package/dist/processor.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"processor.js","sourceRoot":"","sources":["../src/processor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAGH,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAE5E,OAAO,EACL,cAAc,EACd,iBAAiB,EAEjB,YAAY,GACb,MAAM,eAAe,CAAC;AAEvB,OAAO,EAAE,kCAAkC,EAAE,MAAM,eAAe,CAAC;AAEnE,MAAM,GAAG,GAAG,YAAY,CAAC,qBAAqB,CAAC,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,OAAO,oBAAoB;IACvB,SAAS,CAAgB;IACzB,MAAM,CAMZ;IAEF;;;;OAIG;IACH,YAAY,MAA8B;QACxC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,SAAS,CAAC;QAElD,yCAAyC;QACzC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC;QAElE,mDAAmD;QACnD,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC;YACrC,GAAG,EAAE,GAAG,MAAM,CAAC,OAAO,YAAY;YAClC,OAAO,EAAE;gBACP,eAAe,EAAE,MAAM,CAAC,CAAC,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE;gBACjD,cAAc,EAAE,kBAAkB;aACnC;YACD,aAAa,EAAE,IAAI;SACpB,CAAC,CAAC;QAEH,mDAAmD;QACnD,IAAI,UAAU,KAAK,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,SAAS,GAAG,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,GAAG,IAAI,kBAAkB,CAAC,QAAQ,EAAE;gBAChD,kBAAkB,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;gBAC1C,oBAAoB,EAAE,MAAM,CAAC,YAAY,IAAI,IAAI;aAClD,CAAC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,MAAM,GAAG;YACZ,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,KAAK;YAC5B,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,eAAe,EAAE,MAAM,CAAC,eAAe;YACvC,cAAc,EAAE,MAAM,CAAC,cAAc;SACtC,CAAC;QAEF,GAAG,CAAC,IAAI,CAAC,kCAAkC,EAAE;YAC3C,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,UAAU;YACV,SAAS,EAAE,MAAM,CAAC,SAAS;YAC3B,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,kBAAkB,EAAE,CAAC,CAAC,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC;YACjF,iBAAiB,EAAE,CAAC,CAAC,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC;YAC9E,mBAAmB,EAAE,CAAC,CAAC,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC;YACpF,kBAAkB,EAAE,CAAC,CAAC,MAAM,CAAC,eAAe,IAAI,MAAM,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC;SAClF,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,OAAO,CAAC,IAAU,EAAE,aAAsB;QACxC,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACvC,GAAG,CAAC,KAAK,CAAC,cAAc,EAAE;YACxB,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,OAAO,EAAE,WAAW,CAAC,OAAO;SAC7B,CAAC,CAAC;QAEH,wEAAwE;QACxE,2FAA2F;QAC3F,MAAM,gBAAgB,GAAG,aAAa,CAAC,QAAQ,CAAC,kCAAkC,CAAwC,CAAC;QAE3H,IAAI,gBAAgB,IAAI,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjE,oEAAoE;YACpE,MAAM,gBAAgB,GAAG,IAAI,CAAC,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;YAExE,IAAI,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7C,gFAAgF;gBAChF,MAAM,eAAe,GAAqE,EAAE,CAAC;gBAC7F,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,EAAE,CAAC;oBAC5D,iCAAiC;oBACjC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;wBACjH,eAAe,CAAC,GAAG,CAAC,GAAG,KAAyD,CAAC;oBACnF,CAAC;yBAAM,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;wBACjD,gCAAgC;wBAChC,eAAe,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;oBACvC,CAAC;gBACH,CAAC;gBAED,IAAI,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC;gBACpC,GAAG,CAAC,KAAK,CAAC,4CAA4C,EAAE;oBACtD,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,MAAM,EAAE,WAAW,CAAC,MAAM;oBAC1B,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,MAAM;oBACnD,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC;iBACzC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,CAAC,CAAC;IAC9C,CAAC;IAED;;;OAGG;IACK,uBAAuB,CAAC,UAAmC;QACjE,MAAM,gBAAgB,GAA4B,EAAE,CAAC;QAErD,6CAA6C;QAC7C,MAAM,YAAY,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;QAC7E,8CAA8C;QAC9C,MAAM,aAAa,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;QAE5C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;YACtD,iCAAiC;YACjC,MAAM,eAAe,GAAG,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;YAC5E,MAAM,gBAAgB,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;YAE9E,IAAI,CAAC,eAAe,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBAC1C,gBAAgB,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAChC,CAAC;QACH,CAAC;QAED,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED;;;;;;;OAOG;IACH,KAAK,CAAC,IAAkB;QACtB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACvC,GAAG,CAAC,KAAK,CAAC,wBAAwB,EAAE;YAClC,QAAQ,EAAE,IAAI,CAAC,IAAI;YACnB,MAAM,EAAE,WAAW,CAAC,MAAM;YAC1B,OAAO,EAAE,WAAW,CAAC,OAAO;YAC5B,QAAQ,EAAE,IAAI,CAAC,IAAI;SACpB,CAAC,CAAC;QAEH,IAAI,CAAC;YACH,qEAAqE;YACrE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC1B,GAAG,CAAC,KAAK,CAAC,6BAA6B,EAAE;oBACvC,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,MAAM,EAAE,WAAW,CAAC,MAAM;oBAC1B,MAAM,EAAE,6CAA6C;iBACtD,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,2CAA2C;YAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC;YACnC,MAAM,GAAG,GAAI,UAAU,CAAC,UAAU,CAAY;gBACjC,UAAU,CAAC,UAAU,CAAY;gBAClC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,WAAW,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAE5F,GAAG,CAAC,KAAK,CAAC,oCAAoC,EAAE;gBAC9C,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,GAAG;gBACH,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;gBACpC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;gBACpC,gBAAgB,EAAE,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC;aACjD,CAAC,CAAC;YAEH,iCAAiC;YACjC,IAAI,GAAG,EAAE,CAAC;gBACR,MAAM,aAAa,GAAG,iBAAiB,CACrC,GAAG,EACH,IAAI,CAAC,MAAM,CAAC,eAAe,EAC3B,IAAI,CAAC,MAAM,CAAC,cAAc,CAC3B,CAAC;gBAEF,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,GAAG,CAAC,IAAI,CAAC,mCAAmC,EAAE;wBAC5C,QAAQ,EAAE,IAAI,CAAC,IAAI;wBACnB,MAAM,EAAE,WAAW,CAAC,MAAM;wBAC1B,GAAG;qBACJ,CAAC,CAAC;oBACH,OAAO;gBACT,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,GAAG,CAAC,KAAK,CAAC,+CAA+C,EAAE;oBACzD,QAAQ,EAAE,IAAI,CAAC,IAAI;iBACpB,CAAC,CAAC;YACL,CAAC;YAED,2EAA2E;YAC3E,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAE3B,GAAG,CAAC,IAAI,CAAC,+CAA+C,EAAE;gBACxD,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,OAAO,EAAE,WAAW,CAAC,OAAO;gBAC5B,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,GAAG;aACJ,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,iDAAiD;YACjD,GAAG,CAAC,KAAK,CAAC,uBAAuB,EAAE;gBACjC,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,UAAU;QACrB,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACjC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC;YAClC,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,0BAA0B,EAAE;gBACpC,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,KAAK,CAAC,QAAQ;QACnB,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YAChC,GAAG,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,GAAG,CAAC,KAAK,CAAC,iCAAiC,EAAE;gBAC3C,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;aAC9D,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;CACF"}
|
package/dist/span-wrapper.d.ts
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Span wrapper for PingOps SDK
|
|
3
|
-
*
|
|
4
|
-
* Provides PingopsSpan class similar to LangfuseSpan for wrapping OpenTelemetry spans
|
|
5
|
-
* with PingOps-specific functionality.
|
|
6
|
-
*/
|
|
7
|
-
import { TimeInput, Span, SpanContext } from '@opentelemetry/api';
|
|
8
|
-
import type { Attributes } from '@opentelemetry/api';
|
|
9
|
-
import type { SpanAttributes } from './tracer-provider';
|
|
10
|
-
/**
|
|
11
|
-
* Base class for PingOps span wrappers
|
|
12
|
-
*
|
|
13
|
-
* Provides common functionality for wrapping OpenTelemetry spans with PingOps-specific features.
|
|
14
|
-
*/
|
|
15
|
-
declare abstract class PingopsBaseSpan {
|
|
16
|
-
/** The underlying OpenTelemetry span */
|
|
17
|
-
readonly otelSpan: Span;
|
|
18
|
-
/** The span ID from the OpenTelemetry span context */
|
|
19
|
-
id: string;
|
|
20
|
-
/** The trace ID from the OpenTelemetry span context */
|
|
21
|
-
traceId: string;
|
|
22
|
-
constructor(otelSpan: Span);
|
|
23
|
-
/**
|
|
24
|
-
* Ends the span, marking it as complete.
|
|
25
|
-
*
|
|
26
|
-
* @param endTime - Optional end time, defaults to current time
|
|
27
|
-
*/
|
|
28
|
-
end(endTime?: TimeInput): void;
|
|
29
|
-
/**
|
|
30
|
-
* Updates the span with new attributes.
|
|
31
|
-
*
|
|
32
|
-
* @param attributes - Span attributes to set
|
|
33
|
-
* @returns This span for method chaining
|
|
34
|
-
*/
|
|
35
|
-
update(attributes: SpanAttributes): PingopsSpan;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* PingOps span wrapper for tracking operations
|
|
39
|
-
*
|
|
40
|
-
* Provides a convenient wrapper around OpenTelemetry spans with PingOps-specific
|
|
41
|
-
* attribute handling and lifecycle management.
|
|
42
|
-
*/
|
|
43
|
-
export declare class PingopsSpan extends PingopsBaseSpan {
|
|
44
|
-
constructor(otelSpan: Span);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Creates an OpenTelemetry span with the PingOps tracer.
|
|
48
|
-
*
|
|
49
|
-
* @param params - Parameters for span creation
|
|
50
|
-
* @returns The created OpenTelemetry span
|
|
51
|
-
* @internal
|
|
52
|
-
*/
|
|
53
|
-
export declare function createOtelSpan(params: {
|
|
54
|
-
name: string;
|
|
55
|
-
startTime?: TimeInput;
|
|
56
|
-
parentSpanContext?: SpanContext;
|
|
57
|
-
attributes?: Attributes;
|
|
58
|
-
}): Span;
|
|
59
|
-
export {};
|
|
60
|
-
//# sourceMappingURL=span-wrapper.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"span-wrapper.d.ts","sourceRoot":"","sources":["../src/span-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAkB,SAAS,EAAE,IAAI,EAAE,WAAW,EAAW,MAAM,oBAAoB,CAAC;AAC3F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;;GAIG;AACH,uBAAe,eAAe;IAC5B,wCAAwC;IACxC,SAAgB,QAAQ,EAAE,IAAI,CAAC;IAC/B,sDAAsD;IAC/C,EAAE,EAAE,MAAM,CAAC;IAClB,uDAAuD;IAChD,OAAO,EAAE,MAAM,CAAC;gBAEX,QAAQ,EAAE,IAAI;IAO1B;;;;OAIG;IACI,GAAG,CAAC,OAAO,CAAC,EAAE,SAAS,GAAG,IAAI;IAIrC;;;;;OAKG;IACI,MAAM,CAAC,UAAU,EAAE,cAAc,GAAG,WAAW;CA8CvD;AAED;;;;;GAKG;AACH,qBAAa,WAAY,SAAQ,eAAe;gBAClC,QAAQ,EAAE,IAAI;CAG3B;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,iBAAiB,CAAC,EAAE,WAAW,CAAC;IAChC,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,GAAG,IAAI,CAYP"}
|
package/dist/span-wrapper.js
DELETED
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Span wrapper for PingOps SDK
|
|
3
|
-
*
|
|
4
|
-
* Provides PingopsSpan class similar to LangfuseSpan for wrapping OpenTelemetry spans
|
|
5
|
-
* with PingOps-specific functionality.
|
|
6
|
-
*/
|
|
7
|
-
import { trace, context } from '@opentelemetry/api';
|
|
8
|
-
import { getPingopsTracerProvider } from './tracer-provider';
|
|
9
|
-
/**
|
|
10
|
-
* Base class for PingOps span wrappers
|
|
11
|
-
*
|
|
12
|
-
* Provides common functionality for wrapping OpenTelemetry spans with PingOps-specific features.
|
|
13
|
-
*/
|
|
14
|
-
class PingopsBaseSpan {
|
|
15
|
-
/** The underlying OpenTelemetry span */
|
|
16
|
-
otelSpan;
|
|
17
|
-
/** The span ID from the OpenTelemetry span context */
|
|
18
|
-
id;
|
|
19
|
-
/** The trace ID from the OpenTelemetry span context */
|
|
20
|
-
traceId;
|
|
21
|
-
constructor(otelSpan) {
|
|
22
|
-
this.otelSpan = otelSpan;
|
|
23
|
-
const spanContext = otelSpan.spanContext();
|
|
24
|
-
this.id = spanContext.spanId;
|
|
25
|
-
this.traceId = spanContext.traceId;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Ends the span, marking it as complete.
|
|
29
|
-
*
|
|
30
|
-
* @param endTime - Optional end time, defaults to current time
|
|
31
|
-
*/
|
|
32
|
-
end(endTime) {
|
|
33
|
-
this.otelSpan.end(endTime);
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Updates the span with new attributes.
|
|
37
|
-
*
|
|
38
|
-
* @param attributes - Span attributes to set
|
|
39
|
-
* @returns This span for method chaining
|
|
40
|
-
*/
|
|
41
|
-
update(attributes) {
|
|
42
|
-
const otelAttributes = {};
|
|
43
|
-
// Handle nested attributes object
|
|
44
|
-
if (attributes.attributes) {
|
|
45
|
-
Object.assign(otelAttributes, attributes.attributes);
|
|
46
|
-
}
|
|
47
|
-
// Handle input/output
|
|
48
|
-
if (attributes.input !== undefined) {
|
|
49
|
-
otelAttributes['span.input'] =
|
|
50
|
-
typeof attributes.input === 'string'
|
|
51
|
-
? attributes.input
|
|
52
|
-
: JSON.stringify(attributes.input);
|
|
53
|
-
}
|
|
54
|
-
if (attributes.output !== undefined) {
|
|
55
|
-
otelAttributes['span.output'] =
|
|
56
|
-
typeof attributes.output === 'string'
|
|
57
|
-
? attributes.output
|
|
58
|
-
: JSON.stringify(attributes.output);
|
|
59
|
-
}
|
|
60
|
-
// Handle metadata
|
|
61
|
-
if (attributes.metadata !== undefined) {
|
|
62
|
-
for (const [key, value] of Object.entries(attributes.metadata)) {
|
|
63
|
-
otelAttributes[`span.metadata.${key}`] =
|
|
64
|
-
typeof value === 'string' ? value : JSON.stringify(value);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
// Add any other custom attributes (excluding the special keys)
|
|
68
|
-
for (const [key, value] of Object.entries(attributes)) {
|
|
69
|
-
if (key !== 'attributes' &&
|
|
70
|
-
key !== 'input' &&
|
|
71
|
-
key !== 'output' &&
|
|
72
|
-
key !== 'metadata') {
|
|
73
|
-
otelAttributes[key] = value;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
this.otelSpan.setAttributes(otelAttributes);
|
|
77
|
-
return this;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
/**
|
|
81
|
-
* PingOps span wrapper for tracking operations
|
|
82
|
-
*
|
|
83
|
-
* Provides a convenient wrapper around OpenTelemetry spans with PingOps-specific
|
|
84
|
-
* attribute handling and lifecycle management.
|
|
85
|
-
*/
|
|
86
|
-
export class PingopsSpan extends PingopsBaseSpan {
|
|
87
|
-
constructor(otelSpan) {
|
|
88
|
-
super(otelSpan);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Creates an OpenTelemetry span with the PingOps tracer.
|
|
93
|
-
*
|
|
94
|
-
* @param params - Parameters for span creation
|
|
95
|
-
* @returns The created OpenTelemetry span
|
|
96
|
-
* @internal
|
|
97
|
-
*/
|
|
98
|
-
export function createOtelSpan(params) {
|
|
99
|
-
const provider = getPingopsTracerProvider();
|
|
100
|
-
const tracer = provider.getTracer('@pingops/sdk', '0.1.0');
|
|
101
|
-
return tracer.startSpan(params.name, {
|
|
102
|
-
startTime: params.startTime,
|
|
103
|
-
attributes: params.attributes,
|
|
104
|
-
}, createParentContext(params.parentSpanContext));
|
|
105
|
-
}
|
|
106
|
-
/**
|
|
107
|
-
* Creates a parent context from a span context.
|
|
108
|
-
*
|
|
109
|
-
* @param parentSpanContext - The span context to use as parent
|
|
110
|
-
* @returns The created context or undefined if no parent provided
|
|
111
|
-
* @internal
|
|
112
|
-
*/
|
|
113
|
-
function createParentContext(parentSpanContext) {
|
|
114
|
-
if (!parentSpanContext)
|
|
115
|
-
return undefined;
|
|
116
|
-
return trace.setSpanContext(context.active(), parentSpanContext);
|
|
117
|
-
}
|
|
118
|
-
//# sourceMappingURL=span-wrapper.js.map
|
package/dist/span-wrapper.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"span-wrapper.js","sourceRoot":"","sources":["../src/span-wrapper.ts"],"names":[],"mappings":"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"}
|