@pingops/otel 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 (42) hide show
  1. package/README.md +93 -0
  2. package/dist/config.d.ts +75 -0
  3. package/dist/config.d.ts.map +1 -0
  4. package/dist/config.js +5 -0
  5. package/dist/config.js.map +1 -0
  6. package/dist/index.d.ts +10 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +9 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/instrumentations/body-extractor.d.ts +48 -0
  11. package/dist/instrumentations/body-extractor.d.ts.map +1 -0
  12. package/dist/instrumentations/body-extractor.js +361 -0
  13. package/dist/instrumentations/body-extractor.js.map +1 -0
  14. package/dist/instrumentations/http.d.ts +12 -0
  15. package/dist/instrumentations/http.d.ts.map +1 -0
  16. package/dist/instrumentations/http.js +38 -0
  17. package/dist/instrumentations/http.js.map +1 -0
  18. package/dist/instrumentations/index.d.ts +17 -0
  19. package/dist/instrumentations/index.d.ts.map +1 -0
  20. package/dist/instrumentations/index.js +32 -0
  21. package/dist/instrumentations/index.js.map +1 -0
  22. package/dist/instrumentations/undici.d.ts +12 -0
  23. package/dist/instrumentations/undici.d.ts.map +1 -0
  24. package/dist/instrumentations/undici.js +38 -0
  25. package/dist/instrumentations/undici.js.map +1 -0
  26. package/dist/processor.d.ts +82 -0
  27. package/dist/processor.d.ts.map +1 -0
  28. package/dist/processor.js +264 -0
  29. package/dist/processor.js.map +1 -0
  30. package/dist/span-processor.d.ts +78 -0
  31. package/dist/span-processor.d.ts.map +1 -0
  32. package/dist/span-processor.js +272 -0
  33. package/dist/span-processor.js.map +1 -0
  34. package/dist/span-wrapper.d.ts +60 -0
  35. package/dist/span-wrapper.d.ts.map +1 -0
  36. package/dist/span-wrapper.js +118 -0
  37. package/dist/span-wrapper.js.map +1 -0
  38. package/dist/tracer-provider.d.ts +57 -0
  39. package/dist/tracer-provider.d.ts.map +1 -0
  40. package/dist/tracer-provider.js +182 -0
  41. package/dist/tracer-provider.js.map +1 -0
  42. package/package.json +43 -0
@@ -0,0 +1,182 @@
1
+ /**
2
+ * Tracer Provider with global state and isolated TracerProvider architecture
3
+ *
4
+ * This module provides an isolated TracerProvider that shares the same
5
+ * span processors (like PingopsSpanProcessor) with the main OpenTelemetry SDK.
6
+ * This ensures manual spans created via startSpan are properly processed.
7
+ *
8
+ * Architecture follows Langfuse's pattern with global state management.
9
+ */
10
+ import { trace } from "@opentelemetry/api";
11
+ import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
12
+ import { resourceFromAttributes } from "@opentelemetry/resources";
13
+ import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
14
+ import { createLogger } from "@pingops/core";
15
+ /**
16
+ * Global symbol for PingOps state
17
+ */
18
+ const PINGOPS_GLOBAL_SYMBOL = Symbol.for("pingops");
19
+ /**
20
+ * Logger instance for tracer provider
21
+ */
22
+ const log = createLogger("[PingOps TracerProvider]");
23
+ /**
24
+ * Creates initial global state
25
+ */
26
+ function createState() {
27
+ return {
28
+ isolatedTracerProvider: null,
29
+ };
30
+ }
31
+ /**
32
+ * Gets the global state, creating it if it doesn't exist
33
+ */
34
+ function getGlobalState() {
35
+ const initialState = createState();
36
+ try {
37
+ const g = globalThis;
38
+ if (typeof g !== "object" || g === null) {
39
+ // Fallback if globalThis is not available
40
+ log.warn("globalThis is not available, using fallback state");
41
+ return initialState;
42
+ }
43
+ if (!g[PINGOPS_GLOBAL_SYMBOL]) {
44
+ log.debug("Creating new global state");
45
+ Object.defineProperty(g, PINGOPS_GLOBAL_SYMBOL, {
46
+ value: initialState,
47
+ writable: false, // lock the slot (not the contents)
48
+ configurable: false,
49
+ enumerable: false,
50
+ });
51
+ }
52
+ else {
53
+ log.debug("Retrieved existing global state");
54
+ }
55
+ return g[PINGOPS_GLOBAL_SYMBOL];
56
+ }
57
+ catch (err) {
58
+ log.error("Failed to access global state:", err instanceof Error ? err.message : String(err));
59
+ // Fallback on error
60
+ return initialState;
61
+ }
62
+ }
63
+ /**
64
+ * Sets an isolated TracerProvider for PingOps tracing operations.
65
+ *
66
+ * This allows PingOps to use its own TracerProvider instance, separate from
67
+ * the global OpenTelemetry TracerProvider. This is useful for avoiding conflicts
68
+ * with other OpenTelemetry instrumentation in the application.
69
+ *
70
+ * @param provider - The TracerProvider instance to use, or null to clear the isolated provider
71
+ * @public
72
+ */
73
+ export function setPingopsTracerProvider(provider) {
74
+ const state = getGlobalState();
75
+ const hadProvider = state.isolatedTracerProvider !== null;
76
+ state.isolatedTracerProvider = provider;
77
+ if (provider) {
78
+ log.info("Set isolated TracerProvider", {
79
+ hadPrevious: hadProvider,
80
+ providerType: provider.constructor.name,
81
+ });
82
+ }
83
+ else {
84
+ log.info("Cleared isolated TracerProvider", { hadPrevious: hadProvider });
85
+ }
86
+ }
87
+ /**
88
+ * Gets the TracerProvider for PingOps tracing operations.
89
+ *
90
+ * Returns the isolated TracerProvider if one has been set via setPingopsTracerProvider(),
91
+ * otherwise falls back to the global OpenTelemetry TracerProvider.
92
+ *
93
+ * @returns The TracerProvider instance to use for PingOps tracing
94
+ * @public
95
+ */
96
+ export function getPingopsTracerProvider() {
97
+ const { isolatedTracerProvider } = getGlobalState();
98
+ if (isolatedTracerProvider) {
99
+ log.debug("Using isolated TracerProvider", {
100
+ providerType: isolatedTracerProvider.constructor.name,
101
+ });
102
+ return isolatedTracerProvider;
103
+ }
104
+ const globalProvider = trace.getTracerProvider();
105
+ log.debug("Using global TracerProvider", {
106
+ providerType: globalProvider.constructor.name,
107
+ });
108
+ return globalProvider;
109
+ }
110
+ /**
111
+ * Initializes the isolated TracerProvider with the given span processors
112
+ *
113
+ * This creates a separate TracerProvider that shares the same span processors
114
+ * (like PingopsSpanProcessor) with the main SDK. This ensures manual spans
115
+ * are processed correctly.
116
+ *
117
+ * @param spanProcessors - Array of span processors to use (e.g., PingopsSpanProcessor)
118
+ * @param serviceName - Service name for resource attributes
119
+ * @deprecated Use setPingopsTracerProvider instead
120
+ */
121
+ export function initializeTracerProvider(spanProcessors, serviceName) {
122
+ log.info("Initializing TracerProvider", {
123
+ serviceName,
124
+ spanProcessorCount: spanProcessors.length,
125
+ });
126
+ // Create resource with service name
127
+ const resource = resourceFromAttributes({
128
+ [ATTR_SERVICE_NAME]: serviceName,
129
+ });
130
+ log.debug("Created resource", { serviceName });
131
+ // In version 2.2.0, span processors are passed in the constructor
132
+ const tracerProvider = new NodeTracerProvider({
133
+ resource,
134
+ spanProcessors,
135
+ });
136
+ log.debug("Created NodeTracerProvider", {
137
+ spanProcessorCount: spanProcessors.length,
138
+ });
139
+ // Register the provider globally
140
+ tracerProvider.register();
141
+ log.info("Registered TracerProvider globally");
142
+ // Set it in global state
143
+ setPingopsTracerProvider(tracerProvider);
144
+ log.info("TracerProvider initialization complete");
145
+ }
146
+ /**
147
+ * Gets the isolated TracerProvider instance
148
+ *
149
+ * @returns The TracerProvider instance, or null if not initialized
150
+ * @deprecated Use getPingopsTracerProvider instead
151
+ */
152
+ export function getTracerProvider() {
153
+ const provider = getPingopsTracerProvider();
154
+ return provider instanceof NodeTracerProvider ? provider : null;
155
+ }
156
+ /**
157
+ * Shuts down the TracerProvider and flushes remaining spans
158
+ */
159
+ export async function shutdownTracerProvider() {
160
+ log.info("Shutting down TracerProvider");
161
+ const provider = getPingopsTracerProvider();
162
+ // Check if provider has shutdown method (NodeTracerProvider and compatible providers)
163
+ const providerWithShutdown = provider;
164
+ if (providerWithShutdown &&
165
+ typeof providerWithShutdown.shutdown === "function") {
166
+ log.debug("Calling provider.shutdown()");
167
+ try {
168
+ await providerWithShutdown.shutdown();
169
+ log.info("TracerProvider shutdown complete");
170
+ }
171
+ catch (error) {
172
+ log.error("Error during TracerProvider shutdown:", error instanceof Error ? error.message : String(error));
173
+ throw error;
174
+ }
175
+ }
176
+ else {
177
+ log.warn("TracerProvider does not have shutdown method, skipping");
178
+ }
179
+ setPingopsTracerProvider(null);
180
+ log.info("TracerProvider shutdown finished");
181
+ }
182
+ //# sourceMappingURL=tracer-provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tracer-provider.js","sourceRoot":"","sources":["../src/tracer-provider.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@pingops/otel",
3
+ "version": "0.1.0",
4
+ "description": "OpenTelemetry SpanProcessor for PingOps",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "files": [
8
+ "dist",
9
+ "README.md"
10
+ ],
11
+ "keywords": [
12
+ "pingops",
13
+ "monitoring",
14
+ "observability",
15
+ "opentelemetry",
16
+ "span-processor"
17
+ ],
18
+ "license": "MIT",
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "dependencies": {
23
+ "@opentelemetry/api": "^1.9.0",
24
+ "@opentelemetry/sdk-trace-base": "^2.2.0",
25
+ "@opentelemetry/sdk-trace-node": "^2.2.0",
26
+ "@opentelemetry/resources": "^2.2.0",
27
+ "@opentelemetry/semantic-conventions": "^1.38.0",
28
+ "@opentelemetry/exporter-trace-otlp-http": "^0.208.0",
29
+ "@opentelemetry/instrumentation": "^0.208.0",
30
+ "@opentelemetry/instrumentation-http": "^0.208.0",
31
+ "@opentelemetry/instrumentation-undici": "^0.19.0",
32
+ "@pingops/core": "^0.1.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^20.11.0",
36
+ "typescript": "^5.6.0"
37
+ },
38
+ "scripts": {
39
+ "build": "tsc",
40
+ "dev": "tsc --watch",
41
+ "clean": "rm -rf dist"
42
+ }
43
+ }