@blaxel/telemetry 0.2.23-dev.173 → 0.2.23-dev.174

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.
@@ -0,0 +1,44 @@
1
+ import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
2
+ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
3
+ import { ResourceMetrics } from "@opentelemetry/sdk-metrics";
4
+ import { ReadableSpan, SpanExporter } from "@opentelemetry/sdk-trace-node";
5
+ /**
6
+ * SpanExporter that refreshes authentication before each export.
7
+ * This is necessary for long-running containers where tokens may expire.
8
+ */
9
+ export declare class AuthRefreshingSpanExporter implements SpanExporter {
10
+ private createExporter;
11
+ constructor(createExporter: () => SpanExporter);
12
+ private currentExporter;
13
+ export(spans: ReadableSpan[], resultCallback: (result: {
14
+ code: number;
15
+ error?: Error;
16
+ }) => void): void;
17
+ private doExport;
18
+ shutdown(): Promise<void>;
19
+ forceFlush(): Promise<void>;
20
+ }
21
+ /**
22
+ * MetricExporter that refreshes authentication before each export.
23
+ * This is necessary for long-running containers where tokens may expire.
24
+ */
25
+ export declare class AuthRefreshingMetricExporter {
26
+ private createExporter;
27
+ constructor(createExporter: () => OTLPMetricExporter);
28
+ private currentExporter;
29
+ export(metrics: ResourceMetrics, resultCallback: (result: {
30
+ code: number;
31
+ error?: Error;
32
+ }) => void): void;
33
+ private doExport;
34
+ shutdown(): Promise<void>;
35
+ forceFlush(): Promise<void>;
36
+ }
37
+ /**
38
+ * Creates an OTLP Trace Exporter with the current auth headers
39
+ */
40
+ export declare function createTraceExporter(): OTLPTraceExporter;
41
+ /**
42
+ * Creates an OTLP Metric Exporter with the current auth headers
43
+ */
44
+ export declare function createMetricExporter(): OTLPMetricExporter;
@@ -0,0 +1,200 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuthRefreshingMetricExporter = exports.AuthRefreshingSpanExporter = void 0;
4
+ exports.createTraceExporter = createTraceExporter;
5
+ exports.createMetricExporter = createMetricExporter;
6
+ const core_1 = require("@blaxel/core");
7
+ const exporter_metrics_otlp_http_1 = require("@opentelemetry/exporter-metrics-otlp-http");
8
+ const exporter_trace_otlp_http_1 = require("@opentelemetry/exporter-trace-otlp-http");
9
+ /**
10
+ * SpanExporter that refreshes authentication before each export.
11
+ * This is necessary for long-running containers where tokens may expire.
12
+ */
13
+ class AuthRefreshingSpanExporter {
14
+ createExporter;
15
+ constructor(createExporter) {
16
+ this.createExporter = createExporter;
17
+ core_1.logger.debug("[AuthRefreshingSpanExporter] Initialized");
18
+ }
19
+ currentExporter = null;
20
+ export(spans, resultCallback) {
21
+ core_1.logger.debug(`[AuthRefreshingSpanExporter] Exporting ${spans.length} spans`);
22
+ // Execute async operations but return void as required by interface
23
+ this.doExport(spans, resultCallback).catch(error => {
24
+ core_1.logger.error("[AuthRefreshingSpanExporter] Fatal error in export:", error);
25
+ resultCallback({ code: 1, error: error });
26
+ });
27
+ }
28
+ async doExport(spans, resultCallback) {
29
+ try {
30
+ core_1.logger.debug("[AuthRefreshingSpanExporter] Starting authentication refresh");
31
+ const startTime = Date.now();
32
+ // Always refresh auth before export
33
+ await (0, core_1.authenticate)();
34
+ const authTime = Date.now() - startTime;
35
+ core_1.logger.debug(`[AuthRefreshingSpanExporter] Authentication completed in ${authTime}ms`);
36
+ // Log current auth status
37
+ if (core_1.settings.authorization) {
38
+ core_1.logger.debug("[AuthRefreshingSpanExporter] Authorization token is present");
39
+ }
40
+ else {
41
+ core_1.logger.warn("[AuthRefreshingSpanExporter] No authorization token after authentication!");
42
+ }
43
+ core_1.logger.debug("[AuthRefreshingSpanExporter] Creating new exporter");
44
+ // Create new exporter with fresh headers
45
+ this.currentExporter = this.createExporter();
46
+ core_1.logger.debug("[AuthRefreshingSpanExporter] New exporter created with fresh auth headers");
47
+ // Export using the fresh exporter
48
+ if (this.currentExporter && this.currentExporter.export) {
49
+ core_1.logger.debug("[AuthRefreshingSpanExporter] Calling export on fresh exporter");
50
+ this.currentExporter.export(spans, resultCallback);
51
+ }
52
+ else {
53
+ const error = new Error('Exporter not initialized');
54
+ core_1.logger.error("[AuthRefreshingSpanExporter] Exporter not properly initialized", error);
55
+ resultCallback({ code: 1, error });
56
+ }
57
+ }
58
+ catch (error) {
59
+ core_1.logger.error("[AuthRefreshingSpanExporter] Error during authentication or export:", error);
60
+ core_1.logger.error("[AuthRefreshingSpanExporter] Error details:", {
61
+ message: error.message,
62
+ stack: error.stack
63
+ });
64
+ resultCallback({ code: 1, error: error });
65
+ }
66
+ }
67
+ async shutdown() {
68
+ core_1.logger.debug("[AuthRefreshingSpanExporter] Shutting down");
69
+ if (this.currentExporter) {
70
+ return this.currentExporter.shutdown();
71
+ }
72
+ }
73
+ async forceFlush() {
74
+ core_1.logger.debug("[AuthRefreshingSpanExporter] Force flushing");
75
+ if (this.currentExporter && this.currentExporter.forceFlush) {
76
+ return this.currentExporter.forceFlush();
77
+ }
78
+ }
79
+ }
80
+ exports.AuthRefreshingSpanExporter = AuthRefreshingSpanExporter;
81
+ /**
82
+ * MetricExporter that refreshes authentication before each export.
83
+ * This is necessary for long-running containers where tokens may expire.
84
+ */
85
+ class AuthRefreshingMetricExporter {
86
+ createExporter;
87
+ constructor(createExporter) {
88
+ this.createExporter = createExporter;
89
+ core_1.logger.debug("[AuthRefreshingMetricExporter] Initialized");
90
+ }
91
+ currentExporter = null;
92
+ export(metrics, resultCallback) {
93
+ core_1.logger.debug("[AuthRefreshingMetricExporter] Exporting metrics");
94
+ // Execute async operations but return void
95
+ this.doExport(metrics, resultCallback).catch(error => {
96
+ core_1.logger.error("[AuthRefreshingMetricExporter] Fatal error in export:", error);
97
+ resultCallback({ code: 1, error: error });
98
+ });
99
+ }
100
+ async doExport(metrics, resultCallback) {
101
+ try {
102
+ core_1.logger.debug("[AuthRefreshingMetricExporter] Starting authentication refresh");
103
+ const startTime = Date.now();
104
+ // Always refresh auth before export
105
+ await (0, core_1.authenticate)();
106
+ const authTime = Date.now() - startTime;
107
+ core_1.logger.debug(`[AuthRefreshingMetricExporter] Authentication completed in ${authTime}ms`);
108
+ // Log current auth status
109
+ if (core_1.settings.authorization) {
110
+ core_1.logger.debug("[AuthRefreshingMetricExporter] Authorization token is present");
111
+ }
112
+ else {
113
+ core_1.logger.warn("[AuthRefreshingMetricExporter] No authorization token after authentication!");
114
+ }
115
+ core_1.logger.debug("[AuthRefreshingMetricExporter] Creating new exporter");
116
+ // Create new exporter with fresh headers
117
+ this.currentExporter = this.createExporter();
118
+ core_1.logger.debug("[AuthRefreshingMetricExporter] New exporter created with fresh auth headers");
119
+ // Export using the fresh exporter
120
+ if (this.currentExporter && this.currentExporter.export) {
121
+ core_1.logger.debug("[AuthRefreshingMetricExporter] Calling export on fresh exporter");
122
+ this.currentExporter.export(metrics, resultCallback);
123
+ }
124
+ else {
125
+ const error = new Error('Exporter not initialized');
126
+ core_1.logger.error("[AuthRefreshingMetricExporter] Exporter not properly initialized", error);
127
+ resultCallback({ code: 1, error });
128
+ }
129
+ }
130
+ catch (error) {
131
+ core_1.logger.error("[AuthRefreshingMetricExporter] Error during authentication or export:", error);
132
+ core_1.logger.error("[AuthRefreshingMetricExporter] Error details:", {
133
+ message: error.message,
134
+ stack: error.stack
135
+ });
136
+ resultCallback({ code: 1, error: error });
137
+ }
138
+ }
139
+ async shutdown() {
140
+ core_1.logger.debug("[AuthRefreshingMetricExporter] Shutting down");
141
+ if (this.currentExporter) {
142
+ return this.currentExporter.shutdown();
143
+ }
144
+ }
145
+ async forceFlush() {
146
+ core_1.logger.debug("[AuthRefreshingMetricExporter] Force flushing");
147
+ if (this.currentExporter && this.currentExporter.forceFlush) {
148
+ return this.currentExporter.forceFlush();
149
+ }
150
+ }
151
+ }
152
+ exports.AuthRefreshingMetricExporter = AuthRefreshingMetricExporter;
153
+ /**
154
+ * Creates an OTLP Trace Exporter with the current auth headers
155
+ */
156
+ function createTraceExporter() {
157
+ const headers = {};
158
+ if (core_1.settings.authorization) {
159
+ headers["x-blaxel-authorization"] = core_1.settings.authorization;
160
+ core_1.logger.debug("[createTraceExporter] Added authorization header");
161
+ }
162
+ else {
163
+ core_1.logger.warn("[createTraceExporter] No authorization available");
164
+ }
165
+ if (core_1.settings.workspace) {
166
+ headers["x-blaxel-workspace"] = core_1.settings.workspace;
167
+ core_1.logger.debug(`[createTraceExporter] Added workspace header: ${core_1.settings.workspace}`);
168
+ }
169
+ else {
170
+ core_1.logger.warn("[createTraceExporter] No workspace available");
171
+ }
172
+ core_1.logger.debug("[createTraceExporter] Creating OTLPTraceExporter with headers:", Object.keys(headers));
173
+ return new exporter_trace_otlp_http_1.OTLPTraceExporter({
174
+ headers,
175
+ });
176
+ }
177
+ /**
178
+ * Creates an OTLP Metric Exporter with the current auth headers
179
+ */
180
+ function createMetricExporter() {
181
+ const headers = {};
182
+ if (core_1.settings.authorization) {
183
+ headers["x-blaxel-authorization"] = core_1.settings.authorization;
184
+ core_1.logger.debug("[createMetricExporter] Added authorization header");
185
+ }
186
+ else {
187
+ core_1.logger.warn("[createMetricExporter] No authorization available");
188
+ }
189
+ if (core_1.settings.workspace) {
190
+ headers["x-blaxel-workspace"] = core_1.settings.workspace;
191
+ core_1.logger.debug(`[createMetricExporter] Added workspace header: ${core_1.settings.workspace}`);
192
+ }
193
+ else {
194
+ core_1.logger.warn("[createMetricExporter] No workspace available");
195
+ }
196
+ core_1.logger.debug("[createMetricExporter] Creating OTLPMetricExporter with headers:", Object.keys(headers));
197
+ return new exporter_metrics_otlp_http_1.OTLPMetricExporter({
198
+ headers,
199
+ });
200
+ }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
1
  import { blaxelTelemetry } from "./telemetry";
2
+ export { AuthRefreshingMetricExporter, AuthRefreshingSpanExporter, createMetricExporter, createTraceExporter } from "./auth_refresh_exporters";
2
3
  export { setJsonLogger } from "./json_logger";
3
4
  export { blaxelTelemetry };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.blaxelTelemetry = exports.setJsonLogger = void 0;
3
+ exports.blaxelTelemetry = exports.setJsonLogger = exports.createTraceExporter = exports.createMetricExporter = exports.AuthRefreshingSpanExporter = exports.AuthRefreshingMetricExporter = void 0;
4
4
  const core_1 = require("@blaxel/core");
5
5
  const json_logger_1 = require("./json_logger");
6
6
  const telemetry_1 = require("./telemetry");
@@ -9,5 +9,10 @@ telemetry_1.blaxelTelemetry.initialize();
9
9
  if (core_1.settings.loggerType === "json") {
10
10
  (0, json_logger_1.setJsonLogger)();
11
11
  }
12
+ var auth_refresh_exporters_1 = require("./auth_refresh_exporters");
13
+ Object.defineProperty(exports, "AuthRefreshingMetricExporter", { enumerable: true, get: function () { return auth_refresh_exporters_1.AuthRefreshingMetricExporter; } });
14
+ Object.defineProperty(exports, "AuthRefreshingSpanExporter", { enumerable: true, get: function () { return auth_refresh_exporters_1.AuthRefreshingSpanExporter; } });
15
+ Object.defineProperty(exports, "createMetricExporter", { enumerable: true, get: function () { return auth_refresh_exporters_1.createMetricExporter; } });
16
+ Object.defineProperty(exports, "createTraceExporter", { enumerable: true, get: function () { return auth_refresh_exporters_1.createTraceExporter; } });
12
17
  var json_logger_2 = require("./json_logger");
13
18
  Object.defineProperty(exports, "setJsonLogger", { enumerable: true, get: function () { return json_logger_2.setJsonLogger; } });
@@ -1,6 +1,4 @@
1
1
  import { Span } from "@opentelemetry/api";
2
- import { OTLPMetricExporter } from "@opentelemetry/exporter-metrics-otlp-http";
3
- import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
4
2
  import { RawResourceAttribute, Resource } from "@opentelemetry/resources";
5
3
  import { SpanProcessor } from "@opentelemetry/sdk-trace-node";
6
4
  export declare class BlaxelResource implements Resource {
@@ -44,11 +42,11 @@ declare class TelemetryManager {
44
42
  /**
45
43
  * Initialize and return the OTLP Metric Exporter.
46
44
  */
47
- getMetricExporter(): OTLPMetricExporter;
45
+ getMetricExporter(): import("@opentelemetry/exporter-metrics-otlp-http").OTLPMetricExporter;
48
46
  /**
49
47
  * Initialize and return the OTLP Trace Exporter.
50
48
  */
51
- getTraceExporter(): OTLPTraceExporter;
49
+ getTraceExporter(): import("@opentelemetry/exporter-trace-otlp-http").OTLPTraceExporter;
52
50
  instrumentApp(): void;
53
51
  setExporters(): void;
54
52
  shutdownApp(): Promise<void>;
package/dist/telemetry.js CHANGED
@@ -3,13 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.blaxelTelemetry = exports.DefaultAttributesSpanProcessor = exports.BlaxelResource = void 0;
4
4
  const core_1 = require("@blaxel/core");
5
5
  const api_1 = require("@opentelemetry/api");
6
- const exporter_metrics_otlp_http_1 = require("@opentelemetry/exporter-metrics-otlp-http");
7
- const exporter_trace_otlp_http_1 = require("@opentelemetry/exporter-trace-otlp-http");
8
6
  const instrumentation_1 = require("@opentelemetry/instrumentation");
9
7
  const instrumentation_http_1 = require("@opentelemetry/instrumentation-http");
10
8
  const resources_1 = require("@opentelemetry/resources");
11
9
  const sdk_metrics_1 = require("@opentelemetry/sdk-metrics");
12
10
  const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
11
+ const auth_refresh_exporters_1 = require("./auth_refresh_exporters");
13
12
  const telemetry_provider_1 = require("./telemetry_provider");
14
13
  class BlaxelResource {
15
14
  attributes;
@@ -72,22 +71,28 @@ class TelemetryManager {
72
71
  // This method need to stay sync to avoid non booted instrumentations
73
72
  initialize() {
74
73
  if (!this.enabled || this.initialized) {
74
+ core_1.logger.debug(`[TelemetryManager] Initialize skipped - enabled: ${this.enabled}, initialized: ${this.initialized}`);
75
75
  return;
76
76
  }
77
+ core_1.logger.debug("[TelemetryManager] Starting telemetry initialization");
77
78
  this.instrumentApp();
78
79
  this.setupSignalHandler();
79
80
  this.initialized = true;
81
+ core_1.logger.debug("[TelemetryManager] Telemetry initialized, setting configuration async");
80
82
  this.setConfiguration().catch((error) => {
81
- core_1.logger.error("Error setting configuration:", error);
83
+ core_1.logger.error("[TelemetryManager] Error setting configuration:", error);
82
84
  });
83
85
  }
84
86
  async setConfiguration() {
85
87
  if (!this.enabled || this.configured) {
88
+ core_1.logger.debug(`[TelemetryManager] SetConfiguration skipped - enabled: ${this.enabled}, configured: ${this.configured}`);
86
89
  return;
87
90
  }
91
+ core_1.logger.debug("[TelemetryManager] Starting authentication for telemetry configuration");
88
92
  await (0, core_1.authenticate)();
93
+ core_1.logger.debug("[TelemetryManager] Authentication completed, setting up exporters");
89
94
  this.setExporters();
90
- core_1.logger.debug("Telemetry ready");
95
+ core_1.logger.debug("[TelemetryManager] Telemetry configuration complete");
91
96
  this.configured = true;
92
97
  }
93
98
  get tracer() {
@@ -156,17 +161,13 @@ class TelemetryManager {
156
161
  * Initialize and return the OTLP Metric Exporter.
157
162
  */
158
163
  getMetricExporter() {
159
- return new exporter_metrics_otlp_http_1.OTLPMetricExporter({
160
- headers: this.authHeaders,
161
- });
164
+ return (0, auth_refresh_exporters_1.createMetricExporter)();
162
165
  }
163
166
  /**
164
167
  * Initialize and return the OTLP Trace Exporter.
165
168
  */
166
169
  getTraceExporter() {
167
- return new exporter_trace_otlp_http_1.OTLPTraceExporter({
168
- headers: this.authHeaders,
169
- });
170
+ return (0, auth_refresh_exporters_1.createTraceExporter)();
170
171
  }
171
172
  instrumentApp() {
172
173
  core_1.telemetryRegistry.registerProvider(new telemetry_provider_1.OtelTelemetryProvider());
@@ -179,6 +180,7 @@ class TelemetryManager {
179
180
  }
180
181
  setExporters() {
181
182
  const resource = new BlaxelResource(this.resourceAttributes);
183
+ core_1.logger.debug("[TelemetryManager] Setting up exporters with authentication refresh");
182
184
  // Configure batch processor options with 1-second delay
183
185
  const batchProcessorOptions = {
184
186
  scheduledDelayMillis: 1000, // Export every 1 second
@@ -186,7 +188,10 @@ class TelemetryManager {
186
188
  maxExportBatchSize: 512, // Max batch size
187
189
  maxQueueSize: 2048 // Max queue size
188
190
  };
189
- const traceExporter = this.getTraceExporter();
191
+ core_1.logger.debug("[TelemetryManager] Batch processor options:", batchProcessorOptions);
192
+ // Create auth-refreshing trace exporter
193
+ const traceExporter = new auth_refresh_exporters_1.AuthRefreshingSpanExporter(() => this.getTraceExporter());
194
+ core_1.logger.debug("[TelemetryManager] Created AuthRefreshingSpanExporter");
190
195
  this.nodeTracerProvider = new sdk_trace_node_1.NodeTracerProvider({
191
196
  resource,
192
197
  sampler: new sdk_trace_node_1.AlwaysOnSampler(),
@@ -201,7 +206,10 @@ class TelemetryManager {
201
206
  ],
202
207
  });
203
208
  this.nodeTracerProvider.register();
204
- const metricExporter = this.getMetricExporter();
209
+ core_1.logger.debug("[TelemetryManager] Trace provider registered");
210
+ // Create auth-refreshing metric exporter
211
+ const metricExporter = new auth_refresh_exporters_1.AuthRefreshingMetricExporter(() => this.getMetricExporter());
212
+ core_1.logger.debug("[TelemetryManager] Created AuthRefreshingMetricExporter");
205
213
  this.meterProvider = new sdk_metrics_1.MeterProvider({
206
214
  resource,
207
215
  readers: [
@@ -212,6 +220,7 @@ class TelemetryManager {
212
220
  ],
213
221
  });
214
222
  api_1.metrics.setGlobalMeterProvider(this.meterProvider);
223
+ core_1.logger.debug("[TelemetryManager] Metric provider configured with 1-second export interval");
215
224
  }
216
225
  async shutdownApp() {
217
226
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blaxel/telemetry",
3
- "version": "0.2.23-dev.173",
3
+ "version": "0.2.23-dev.174",
4
4
  "description": "Blaxel SDK for TypeScript",
5
5
  "license": "MIT",
6
6
  "author": "Blaxel, INC (https://blaxel.ai)",
@@ -71,7 +71,7 @@
71
71
  "@opentelemetry/sdk-trace-base": "^2.0.0",
72
72
  "@opentelemetry/sdk-trace-node": "^2.0.0",
73
73
  "ai": "^4.3.13",
74
- "@blaxel/core": "0.2.23-dev.173"
74
+ "@blaxel/core": "0.2.23-dev.174"
75
75
  },
76
76
  "devDependencies": {
77
77
  "@eslint/js": "^9.26.0",