@glasstrace/sdk 0.12.0 → 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 +73 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +71 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -307,7 +307,7 @@ interface InitClaimResult {
|
|
|
307
307
|
* or request failure). Callers that do not need claim information
|
|
308
308
|
* can safely ignore the return value.
|
|
309
309
|
*/
|
|
310
|
-
declare function performInit(config: ResolvedConfig, anonKey: AnonApiKey | null, sdkVersion: string): Promise<InitClaimResult | null>;
|
|
310
|
+
declare function performInit(config: ResolvedConfig, anonKey: AnonApiKey | null, sdkVersion: string, healthReport?: SdkHealthReport | null): Promise<InitClaimResult | null>;
|
|
311
311
|
/**
|
|
312
312
|
* Returns the current capture config from the three-tier fallback chain:
|
|
313
313
|
* 1. In-memory config from latest init response
|
package/dist/index.d.ts
CHANGED
|
@@ -307,7 +307,7 @@ interface InitClaimResult {
|
|
|
307
307
|
* or request failure). Callers that do not need claim information
|
|
308
308
|
* can safely ignore the return value.
|
|
309
309
|
*/
|
|
310
|
-
declare function performInit(config: ResolvedConfig, anonKey: AnonApiKey | null, sdkVersion: string): Promise<InitClaimResult | null>;
|
|
310
|
+
declare function performInit(config: ResolvedConfig, anonKey: AnonApiKey | null, sdkVersion: string, healthReport?: SdkHealthReport | null): Promise<InitClaimResult | null>;
|
|
311
311
|
/**
|
|
312
312
|
* Returns the current capture config from the three-tier fallback chain:
|
|
313
313
|
* 1. In-memory config from latest init response
|
package/dist/index.js
CHANGED
|
@@ -173,6 +173,58 @@ function classifyFetchTarget(url) {
|
|
|
173
173
|
return "unknown";
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
+
// src/health-collector.ts
|
|
177
|
+
var tracesExported = 0;
|
|
178
|
+
var tracesDropped = 0;
|
|
179
|
+
var initFailures = 0;
|
|
180
|
+
var lastConfigSyncAt = null;
|
|
181
|
+
function recordSpansExported(count) {
|
|
182
|
+
if (!Number.isFinite(count) || count < 0 || !Number.isInteger(count)) return;
|
|
183
|
+
tracesExported += count;
|
|
184
|
+
}
|
|
185
|
+
function recordSpansDropped(count) {
|
|
186
|
+
if (!Number.isFinite(count) || count < 0 || !Number.isInteger(count)) return;
|
|
187
|
+
tracesDropped += count;
|
|
188
|
+
}
|
|
189
|
+
function recordInitFailure() {
|
|
190
|
+
try {
|
|
191
|
+
initFailures += 1;
|
|
192
|
+
} catch {
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function recordConfigSync(timestamp) {
|
|
196
|
+
try {
|
|
197
|
+
lastConfigSyncAt = timestamp;
|
|
198
|
+
} catch {
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
function collectHealthReport(sdkVersion) {
|
|
202
|
+
try {
|
|
203
|
+
const now = Date.now();
|
|
204
|
+
const configAge = lastConfigSyncAt !== null ? Math.max(0, now - lastConfigSyncAt) : 0;
|
|
205
|
+
return {
|
|
206
|
+
tracesExportedSinceLastInit: tracesExported,
|
|
207
|
+
tracesDropped,
|
|
208
|
+
initFailures,
|
|
209
|
+
configAge: Math.round(configAge),
|
|
210
|
+
sdkVersion
|
|
211
|
+
};
|
|
212
|
+
} catch {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
function acknowledgeHealthReport(report) {
|
|
217
|
+
const exp = Math.max(0, report.tracesExportedSinceLastInit);
|
|
218
|
+
const expVal = tracesExported - exp;
|
|
219
|
+
tracesExported = Number.isFinite(expVal) ? Math.max(0, expVal) : tracesExported;
|
|
220
|
+
const drop = Math.max(0, report.tracesDropped);
|
|
221
|
+
const dropVal = tracesDropped - drop;
|
|
222
|
+
tracesDropped = Number.isFinite(dropVal) ? Math.max(0, dropVal) : tracesDropped;
|
|
223
|
+
const fail = Math.max(0, report.initFailures);
|
|
224
|
+
const failVal = initFailures - fail;
|
|
225
|
+
initFailures = Number.isFinite(failVal) ? Math.max(0, failVal) : initFailures;
|
|
226
|
+
}
|
|
227
|
+
|
|
176
228
|
// src/init-client.ts
|
|
177
229
|
var GLASSTRACE_DIR = ".glasstrace";
|
|
178
230
|
var CONFIG_FILE = "config";
|
|
@@ -222,6 +274,7 @@ function loadCachedConfig(projectRoot) {
|
|
|
222
274
|
}
|
|
223
275
|
const result = SdkInitResponseSchema.safeParse(cached.response);
|
|
224
276
|
if (result.success) {
|
|
277
|
+
recordConfigSync(cached.cachedAt);
|
|
225
278
|
return result.data;
|
|
226
279
|
}
|
|
227
280
|
console.warn("[glasstrace] Cached config failed validation. Using defaults.");
|
|
@@ -372,7 +425,7 @@ async function writeClaimedKey(newApiKey, projectRoot) {
|
|
|
372
425
|
} catch {
|
|
373
426
|
}
|
|
374
427
|
}
|
|
375
|
-
async function performInit(config, anonKey, sdkVersion) {
|
|
428
|
+
async function performInit(config, anonKey, sdkVersion, healthReport) {
|
|
376
429
|
if (rateLimitBackoff) {
|
|
377
430
|
rateLimitBackoff = false;
|
|
378
431
|
return null;
|
|
@@ -391,12 +444,16 @@ async function performInit(config, anonKey, sdkVersion) {
|
|
|
391
444
|
anonKey,
|
|
392
445
|
sdkVersion,
|
|
393
446
|
void 0,
|
|
394
|
-
void 0,
|
|
447
|
+
healthReport ?? void 0,
|
|
395
448
|
void 0,
|
|
396
449
|
controller.signal
|
|
397
450
|
);
|
|
398
451
|
clearTimeout(timeoutId);
|
|
399
452
|
currentConfig = result;
|
|
453
|
+
recordConfigSync(Date.now());
|
|
454
|
+
if (healthReport) {
|
|
455
|
+
acknowledgeHealthReport(healthReport);
|
|
456
|
+
}
|
|
400
457
|
await saveCachedConfig(result);
|
|
401
458
|
if (result.claimResult) {
|
|
402
459
|
try {
|
|
@@ -408,6 +465,7 @@ async function performInit(config, anonKey, sdkVersion) {
|
|
|
408
465
|
return null;
|
|
409
466
|
} catch (err) {
|
|
410
467
|
clearTimeout(timeoutId);
|
|
468
|
+
recordInitFailure();
|
|
411
469
|
if (err instanceof DOMException && err.name === "AbortError") {
|
|
412
470
|
console.warn("[glasstrace] ingestion_unreachable: Init request timed out.");
|
|
413
471
|
return null;
|
|
@@ -442,6 +500,7 @@ async function performInit(config, anonKey, sdkVersion) {
|
|
|
442
500
|
return null;
|
|
443
501
|
}
|
|
444
502
|
} catch (err) {
|
|
503
|
+
recordInitFailure();
|
|
445
504
|
console.warn(
|
|
446
505
|
`[glasstrace] Unexpected init error: ${err instanceof Error ? err.message : String(err)}`
|
|
447
506
|
);
|
|
@@ -527,7 +586,9 @@ var GlasstraceExporter = class {
|
|
|
527
586
|
const exporter = this.ensureDelegate();
|
|
528
587
|
if (exporter) {
|
|
529
588
|
exporter.export(enrichedSpans, resultCallback);
|
|
589
|
+
recordSpansExported(enrichedSpans.length);
|
|
530
590
|
} else {
|
|
591
|
+
recordSpansDropped(enrichedSpans.length);
|
|
531
592
|
resultCallback({ code: 0 });
|
|
532
593
|
}
|
|
533
594
|
}
|
|
@@ -546,6 +607,7 @@ var GlasstraceExporter = class {
|
|
|
546
607
|
console.warn(
|
|
547
608
|
`[glasstrace] Shutdown with ${this.pendingSpanCount} buffered spans \u2014 API key never resolved, spans lost.`
|
|
548
609
|
);
|
|
610
|
+
recordSpansDropped(this.pendingSpanCount);
|
|
549
611
|
for (const batch of this.pendingBatches) {
|
|
550
612
|
batch.resultCallback({ code: 0 });
|
|
551
613
|
}
|
|
@@ -688,6 +750,7 @@ var GlasstraceExporter = class {
|
|
|
688
750
|
while (this.pendingSpanCount > MAX_PENDING_SPANS && this.pendingBatches.length > 1) {
|
|
689
751
|
const evicted = this.pendingBatches.shift();
|
|
690
752
|
this.pendingSpanCount -= evicted.spans.length;
|
|
753
|
+
recordSpansDropped(evicted.spans.length);
|
|
691
754
|
evicted.resultCallback({ code: 0 });
|
|
692
755
|
if (!this.overflowLogged) {
|
|
693
756
|
this.overflowLogged = true;
|
|
@@ -709,9 +772,12 @@ var GlasstraceExporter = class {
|
|
|
709
772
|
if (this.pendingBatches.length === 0) return;
|
|
710
773
|
const exporter = this.ensureDelegate();
|
|
711
774
|
if (!exporter) {
|
|
775
|
+
let discardedCount = 0;
|
|
712
776
|
for (const batch of this.pendingBatches) {
|
|
777
|
+
discardedCount += batch.spans.length;
|
|
713
778
|
batch.resultCallback({ code: 0 });
|
|
714
779
|
}
|
|
780
|
+
recordSpansDropped(discardedCount);
|
|
715
781
|
this.pendingBatches = [];
|
|
716
782
|
this.pendingSpanCount = 0;
|
|
717
783
|
return;
|
|
@@ -722,6 +788,7 @@ var GlasstraceExporter = class {
|
|
|
722
788
|
for (const batch of batches) {
|
|
723
789
|
const enriched = batch.spans.map((span) => this.enrichSpan(span));
|
|
724
790
|
exporter.export(enriched, batch.resultCallback);
|
|
791
|
+
recordSpansExported(enriched.length);
|
|
725
792
|
}
|
|
726
793
|
}
|
|
727
794
|
};
|
|
@@ -3672,7 +3739,8 @@ async function backgroundInit(config, anonKeyForInit, generation) {
|
|
|
3672
3739
|
if (config.verbose) {
|
|
3673
3740
|
console.info("[glasstrace] Background init firing.");
|
|
3674
3741
|
}
|
|
3675
|
-
const
|
|
3742
|
+
const healthReport = collectHealthReport("0.12.2");
|
|
3743
|
+
const initResult = await performInit(config, anonKeyForInit, "0.12.2", healthReport);
|
|
3676
3744
|
if (generation !== registrationGeneration) return;
|
|
3677
3745
|
if (initResult?.claimResult) {
|
|
3678
3746
|
setResolvedApiKey(initResult.claimResult.newApiKey);
|