@glasstrace/sdk 0.12.1 → 0.12.2

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 CHANGED
@@ -16951,6 +16951,60 @@ async function getOrCreateAnonKey(projectRoot) {
16951
16951
 
16952
16952
  // src/init-client.ts
16953
16953
  init_dist();
16954
+
16955
+ // src/health-collector.ts
16956
+ var tracesExported = 0;
16957
+ var tracesDropped = 0;
16958
+ var initFailures = 0;
16959
+ var lastConfigSyncAt = null;
16960
+ function recordSpansExported(count) {
16961
+ if (!Number.isFinite(count) || count < 0 || !Number.isInteger(count)) return;
16962
+ tracesExported += count;
16963
+ }
16964
+ function recordSpansDropped(count) {
16965
+ if (!Number.isFinite(count) || count < 0 || !Number.isInteger(count)) return;
16966
+ tracesDropped += count;
16967
+ }
16968
+ function recordInitFailure() {
16969
+ try {
16970
+ initFailures += 1;
16971
+ } catch {
16972
+ }
16973
+ }
16974
+ function recordConfigSync(timestamp) {
16975
+ try {
16976
+ lastConfigSyncAt = timestamp;
16977
+ } catch {
16978
+ }
16979
+ }
16980
+ function collectHealthReport(sdkVersion) {
16981
+ try {
16982
+ const now = Date.now();
16983
+ const configAge = lastConfigSyncAt !== null ? Math.max(0, now - lastConfigSyncAt) : 0;
16984
+ return {
16985
+ tracesExportedSinceLastInit: tracesExported,
16986
+ tracesDropped,
16987
+ initFailures,
16988
+ configAge: Math.round(configAge),
16989
+ sdkVersion
16990
+ };
16991
+ } catch {
16992
+ return null;
16993
+ }
16994
+ }
16995
+ function acknowledgeHealthReport(report) {
16996
+ const exp = Math.max(0, report.tracesExportedSinceLastInit);
16997
+ const expVal = tracesExported - exp;
16998
+ tracesExported = Number.isFinite(expVal) ? Math.max(0, expVal) : tracesExported;
16999
+ const drop = Math.max(0, report.tracesDropped);
17000
+ const dropVal = tracesDropped - drop;
17001
+ tracesDropped = Number.isFinite(dropVal) ? Math.max(0, dropVal) : tracesDropped;
17002
+ const fail = Math.max(0, report.initFailures);
17003
+ const failVal = initFailures - fail;
17004
+ initFailures = Number.isFinite(failVal) ? Math.max(0, failVal) : initFailures;
17005
+ }
17006
+
17007
+ // src/init-client.ts
16954
17008
  var GLASSTRACE_DIR2 = ".glasstrace";
16955
17009
  var CONFIG_FILE = "config";
16956
17010
  var TWENTY_FOUR_HOURS_MS = 24 * 60 * 60 * 1e3;
@@ -16999,6 +17053,7 @@ function loadCachedConfig(projectRoot) {
16999
17053
  }
17000
17054
  const result = SdkInitResponseSchema.safeParse(cached2.response);
17001
17055
  if (result.success) {
17056
+ recordConfigSync(cached2.cachedAt);
17002
17057
  return result.data;
17003
17058
  }
17004
17059
  console.warn("[glasstrace] Cached config failed validation. Using defaults.");
@@ -17149,7 +17204,7 @@ async function writeClaimedKey(newApiKey, projectRoot) {
17149
17204
  } catch {
17150
17205
  }
17151
17206
  }
17152
- async function performInit(config2, anonKey, sdkVersion) {
17207
+ async function performInit(config2, anonKey, sdkVersion, healthReport) {
17153
17208
  if (rateLimitBackoff) {
17154
17209
  rateLimitBackoff = false;
17155
17210
  return null;
@@ -17168,12 +17223,16 @@ async function performInit(config2, anonKey, sdkVersion) {
17168
17223
  anonKey,
17169
17224
  sdkVersion,
17170
17225
  void 0,
17171
- void 0,
17226
+ healthReport ?? void 0,
17172
17227
  void 0,
17173
17228
  controller.signal
17174
17229
  );
17175
17230
  clearTimeout(timeoutId);
17176
17231
  currentConfig = result;
17232
+ recordConfigSync(Date.now());
17233
+ if (healthReport) {
17234
+ acknowledgeHealthReport(healthReport);
17235
+ }
17177
17236
  await saveCachedConfig(result);
17178
17237
  if (result.claimResult) {
17179
17238
  try {
@@ -17185,6 +17244,7 @@ async function performInit(config2, anonKey, sdkVersion) {
17185
17244
  return null;
17186
17245
  } catch (err) {
17187
17246
  clearTimeout(timeoutId);
17247
+ recordInitFailure();
17188
17248
  if (err instanceof DOMException && err.name === "AbortError") {
17189
17249
  console.warn("[glasstrace] ingestion_unreachable: Init request timed out.");
17190
17250
  return null;
@@ -17219,6 +17279,7 @@ async function performInit(config2, anonKey, sdkVersion) {
17219
17279
  return null;
17220
17280
  }
17221
17281
  } catch (err) {
17282
+ recordInitFailure();
17222
17283
  console.warn(
17223
17284
  `[glasstrace] Unexpected init error: ${err instanceof Error ? err.message : String(err)}`
17224
17285
  );
@@ -17306,7 +17367,9 @@ var GlasstraceExporter = class {
17306
17367
  const exporter = this.ensureDelegate();
17307
17368
  if (exporter) {
17308
17369
  exporter.export(enrichedSpans, resultCallback);
17370
+ recordSpansExported(enrichedSpans.length);
17309
17371
  } else {
17372
+ recordSpansDropped(enrichedSpans.length);
17310
17373
  resultCallback({ code: 0 });
17311
17374
  }
17312
17375
  }
@@ -17325,6 +17388,7 @@ var GlasstraceExporter = class {
17325
17388
  console.warn(
17326
17389
  `[glasstrace] Shutdown with ${this.pendingSpanCount} buffered spans \u2014 API key never resolved, spans lost.`
17327
17390
  );
17391
+ recordSpansDropped(this.pendingSpanCount);
17328
17392
  for (const batch of this.pendingBatches) {
17329
17393
  batch.resultCallback({ code: 0 });
17330
17394
  }
@@ -17467,6 +17531,7 @@ var GlasstraceExporter = class {
17467
17531
  while (this.pendingSpanCount > MAX_PENDING_SPANS && this.pendingBatches.length > 1) {
17468
17532
  const evicted = this.pendingBatches.shift();
17469
17533
  this.pendingSpanCount -= evicted.spans.length;
17534
+ recordSpansDropped(evicted.spans.length);
17470
17535
  evicted.resultCallback({ code: 0 });
17471
17536
  if (!this.overflowLogged) {
17472
17537
  this.overflowLogged = true;
@@ -17488,9 +17553,12 @@ var GlasstraceExporter = class {
17488
17553
  if (this.pendingBatches.length === 0) return;
17489
17554
  const exporter = this.ensureDelegate();
17490
17555
  if (!exporter) {
17556
+ let discardedCount = 0;
17491
17557
  for (const batch of this.pendingBatches) {
17558
+ discardedCount += batch.spans.length;
17492
17559
  batch.resultCallback({ code: 0 });
17493
17560
  }
17561
+ recordSpansDropped(discardedCount);
17494
17562
  this.pendingBatches = [];
17495
17563
  this.pendingSpanCount = 0;
17496
17564
  return;
@@ -17501,6 +17569,7 @@ var GlasstraceExporter = class {
17501
17569
  for (const batch of batches) {
17502
17570
  const enriched = batch.spans.map((span) => this.enrichSpan(span));
17503
17571
  exporter.export(enriched, batch.resultCallback);
17572
+ recordSpansExported(enriched.length);
17504
17573
  }
17505
17574
  }
17506
17575
  };
@@ -20485,7 +20554,8 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
20485
20554
  if (config2.verbose) {
20486
20555
  console.info("[glasstrace] Background init firing.");
20487
20556
  }
20488
- const initResult = await performInit(config2, anonKeyForInit, "0.12.1");
20557
+ const healthReport = collectHealthReport("0.12.2");
20558
+ const initResult = await performInit(config2, anonKeyForInit, "0.12.2", healthReport);
20489
20559
  if (generation !== registrationGeneration) return;
20490
20560
  if (initResult?.claimResult) {
20491
20561
  setResolvedApiKey(initResult.claimResult.newApiKey);