@glasstrace/sdk 0.13.6 → 0.14.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/{chunk-DF52INSK.js → chunk-ECEN724Y.js} +2 -2
- package/dist/{chunk-7MHQRVVW.js → chunk-ERGEG4ZQ.js} +2 -3
- package/dist/chunk-ERGEG4ZQ.js.map +1 -0
- package/dist/{chunk-AMFO5UL4.js → chunk-UPS5BGER.js} +2 -2
- package/dist/{chunk-UJ74MD4Y.js → chunk-YMEXDDTA.js} +7 -3
- package/dist/{chunk-UJ74MD4Y.js.map → chunk-YMEXDDTA.js.map} +1 -1
- package/dist/cli/init.cjs +68 -3
- package/dist/cli/init.cjs.map +1 -1
- package/dist/cli/init.js +3 -3
- package/dist/cli/mcp-add.cjs +2 -1
- package/dist/cli/mcp-add.cjs.map +1 -1
- package/dist/cli/mcp-add.js +2 -2
- package/dist/cli/status.cjs +65 -1
- package/dist/cli/status.cjs.map +1 -1
- package/dist/cli/status.d.cts +22 -1
- package/dist/cli/status.d.ts +22 -1
- package/dist/cli/status.js +65 -1
- package/dist/cli/status.js.map +1 -1
- package/dist/index.cjs +775 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +69 -1
- package/dist/index.d.ts +69 -1
- package/dist/index.js +765 -62
- package/dist/index.js.map +1 -1
- package/dist/{source-map-uploader-EWA2XQI4.js → source-map-uploader-W6VPGY26.js} +3 -3
- package/package.json +1 -1
- package/dist/chunk-7MHQRVVW.js.map +0 -1
- /package/dist/{chunk-DF52INSK.js.map → chunk-ECEN724Y.js.map} +0 -0
- /package/dist/{chunk-AMFO5UL4.js.map → chunk-UPS5BGER.js.map} +0 -0
- /package/dist/{source-map-uploader-EWA2XQI4.js.map → source-map-uploader-W6VPGY26.js.map} +0 -0
package/dist/index.cjs
CHANGED
|
@@ -14601,7 +14601,8 @@ var init_dist = __esm({
|
|
|
14601
14601
|
envVarValues: external_exports.boolean(),
|
|
14602
14602
|
fullConsoleOutput: external_exports.boolean(),
|
|
14603
14603
|
importGraph: external_exports.boolean(),
|
|
14604
|
-
consoleErrors: external_exports.boolean().optional().default(false)
|
|
14604
|
+
consoleErrors: external_exports.boolean().optional().default(false),
|
|
14605
|
+
errorResponseBodies: external_exports.boolean().optional().default(false)
|
|
14605
14606
|
});
|
|
14606
14607
|
SdkCachedConfigSchema = external_exports.object({
|
|
14607
14608
|
response: external_exports.record(external_exports.string(), external_exports.unknown()),
|
|
@@ -14732,6 +14733,8 @@ var init_dist = __esm({
|
|
|
14732
14733
|
SOURCE_FILE: "glasstrace.source.file",
|
|
14733
14734
|
SOURCE_LINE: "glasstrace.source.line",
|
|
14734
14735
|
SOURCE_MAPPED: "glasstrace.source.mapped",
|
|
14736
|
+
TRPC_PROCEDURE: "glasstrace.trpc.procedure",
|
|
14737
|
+
ERROR_RESPONSE_BODY: "glasstrace.error.response_body",
|
|
14735
14738
|
// Client-side attributes
|
|
14736
14739
|
PLATFORM: "glasstrace.platform",
|
|
14737
14740
|
GESTURE_TYPE: "glasstrace.gesture.type",
|
|
@@ -14746,7 +14749,8 @@ var init_dist = __esm({
|
|
|
14746
14749
|
envVarValues: false,
|
|
14747
14750
|
fullConsoleOutput: false,
|
|
14748
14751
|
importGraph: false,
|
|
14749
|
-
consoleErrors: false
|
|
14752
|
+
consoleErrors: false,
|
|
14753
|
+
errorResponseBodies: false
|
|
14750
14754
|
};
|
|
14751
14755
|
}
|
|
14752
14756
|
});
|
|
@@ -16614,7 +16618,6 @@ async function uploadSourceMaps(apiKey, endpoint, buildHash, maps) {
|
|
|
16614
16618
|
}
|
|
16615
16619
|
}
|
|
16616
16620
|
const body = {
|
|
16617
|
-
apiKey,
|
|
16618
16621
|
buildHash,
|
|
16619
16622
|
files
|
|
16620
16623
|
};
|
|
@@ -16836,6 +16839,7 @@ __export(src_exports, {
|
|
|
16836
16839
|
collectSourceMaps: () => collectSourceMaps,
|
|
16837
16840
|
computeBuildHash: () => computeBuildHash,
|
|
16838
16841
|
createDiscoveryHandler: () => createDiscoveryHandler,
|
|
16842
|
+
createGlasstraceSpanProcessor: () => createGlasstraceSpanProcessor,
|
|
16839
16843
|
deriveSessionId: () => deriveSessionId,
|
|
16840
16844
|
discoverSourceMapFiles: () => discoverSourceMapFiles,
|
|
16841
16845
|
discoverTestFiles: () => discoverTestFiles,
|
|
@@ -16846,8 +16850,10 @@ __export(src_exports, {
|
|
|
16846
16850
|
getLinkedAccountId: () => getLinkedAccountId,
|
|
16847
16851
|
getOrCreateAnonKey: () => getOrCreateAnonKey,
|
|
16848
16852
|
getOrigin: () => getOrigin,
|
|
16853
|
+
getStatus: () => getStatus,
|
|
16849
16854
|
isAnonymousMode: () => isAnonymousMode,
|
|
16850
16855
|
isProductionDisabled: () => isProductionDisabled,
|
|
16856
|
+
isReady: () => isReady,
|
|
16851
16857
|
loadCachedConfig: () => loadCachedConfig,
|
|
16852
16858
|
performInit: () => performInit,
|
|
16853
16859
|
readAnonKey: () => readAnonKey,
|
|
@@ -16859,6 +16865,7 @@ __export(src_exports, {
|
|
|
16859
16865
|
uploadSourceMaps: () => uploadSourceMaps,
|
|
16860
16866
|
uploadSourceMapsAuto: () => uploadSourceMapsAuto,
|
|
16861
16867
|
uploadSourceMapsPresigned: () => uploadSourceMapsPresigned,
|
|
16868
|
+
waitForReady: () => waitForReady,
|
|
16862
16869
|
withGlasstraceConfig: () => withGlasstraceConfig
|
|
16863
16870
|
});
|
|
16864
16871
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -17229,7 +17236,6 @@ async function sendInitRequest(config2, anonKey, sdkVersion, importGraph, health
|
|
|
17229
17236
|
throw new Error("No API key available for init request");
|
|
17230
17237
|
}
|
|
17231
17238
|
const payload = {
|
|
17232
|
-
apiKey: effectiveKey,
|
|
17233
17239
|
sdkVersion
|
|
17234
17240
|
};
|
|
17235
17241
|
if (config2.apiKey && anonKey) {
|
|
@@ -17466,7 +17472,7 @@ init_cjs_shims();
|
|
|
17466
17472
|
var GlasstraceSpanProcessor = class {
|
|
17467
17473
|
wrappedProcessor;
|
|
17468
17474
|
/* eslint-disable @typescript-eslint/no-unused-vars -- backward compat signature */
|
|
17469
|
-
constructor(wrappedProcessor,
|
|
17475
|
+
constructor(wrappedProcessor, _sessionManager2, _apiKey, _getConfig, _environment) {
|
|
17470
17476
|
this.wrappedProcessor = wrappedProcessor;
|
|
17471
17477
|
}
|
|
17472
17478
|
onStart(span, parentContext) {
|
|
@@ -17512,6 +17518,7 @@ var GlasstraceExporter = class {
|
|
|
17512
17518
|
this.endpointUrl = options.endpointUrl;
|
|
17513
17519
|
this.createDelegateFn = options.createDelegate;
|
|
17514
17520
|
this.verbose = options.verbose ?? false;
|
|
17521
|
+
this[/* @__PURE__ */ Symbol.for("glasstrace.exporter")] = true;
|
|
17515
17522
|
}
|
|
17516
17523
|
export(spans, resultCallback) {
|
|
17517
17524
|
const currentKey = this.getApiKey();
|
|
@@ -17609,6 +17616,22 @@ var GlasstraceExporter = class {
|
|
|
17609
17616
|
if (route) {
|
|
17610
17617
|
extra[ATTR.ROUTE] = route;
|
|
17611
17618
|
}
|
|
17619
|
+
const rawUrl = attrs["http.url"] ?? attrs["url.full"] ?? attrs["http.target"];
|
|
17620
|
+
const trpcUrl = typeof rawUrl === "string" ? rawUrl : void 0;
|
|
17621
|
+
if (trpcUrl) {
|
|
17622
|
+
const trpcMatch = trpcUrl.match(/\/api\/trpc\/([^/?#]+)/);
|
|
17623
|
+
if (trpcMatch) {
|
|
17624
|
+
let procedure;
|
|
17625
|
+
try {
|
|
17626
|
+
procedure = decodeURIComponent(trpcMatch[1]);
|
|
17627
|
+
} catch {
|
|
17628
|
+
procedure = trpcMatch[1];
|
|
17629
|
+
}
|
|
17630
|
+
if (procedure) {
|
|
17631
|
+
extra[ATTR.TRPC_PROCEDURE] = procedure;
|
|
17632
|
+
}
|
|
17633
|
+
}
|
|
17634
|
+
}
|
|
17612
17635
|
const method = attrs["http.method"] ?? attrs["http.request.method"];
|
|
17613
17636
|
if (method) {
|
|
17614
17637
|
extra[ATTR.HTTP_METHOD] = method;
|
|
@@ -17683,6 +17706,12 @@ var GlasstraceExporter = class {
|
|
|
17683
17706
|
if (typeof errorField === "string") {
|
|
17684
17707
|
extra[ATTR.ERROR_FIELD] = errorField;
|
|
17685
17708
|
}
|
|
17709
|
+
if (this.getConfig().errorResponseBodies) {
|
|
17710
|
+
const responseBody = attrs["glasstrace.internal.response_body"];
|
|
17711
|
+
if (typeof responseBody === "string") {
|
|
17712
|
+
extra[ATTR.ERROR_RESPONSE_BODY] = responseBody.slice(0, 500);
|
|
17713
|
+
}
|
|
17714
|
+
}
|
|
17686
17715
|
const spanAny = span;
|
|
17687
17716
|
const instrumentationName = spanAny.instrumentationScope?.name ?? spanAny.instrumentationLibrary?.name ?? "";
|
|
17688
17717
|
const ormProvider = deriveOrmProvider(instrumentationName);
|
|
@@ -20684,9 +20713,461 @@ var BasicTracerProvider = class {
|
|
|
20684
20713
|
// src/otel-config.ts
|
|
20685
20714
|
init_esm();
|
|
20686
20715
|
init_console_capture();
|
|
20716
|
+
|
|
20717
|
+
// src/lifecycle.ts
|
|
20718
|
+
init_cjs_shims();
|
|
20719
|
+
var import_node_events = require("events");
|
|
20720
|
+
var CoreState = {
|
|
20721
|
+
IDLE: "IDLE",
|
|
20722
|
+
REGISTERING: "REGISTERING",
|
|
20723
|
+
KEY_PENDING: "KEY_PENDING",
|
|
20724
|
+
KEY_RESOLVED: "KEY_RESOLVED",
|
|
20725
|
+
ACTIVE: "ACTIVE",
|
|
20726
|
+
ACTIVE_DEGRADED: "ACTIVE_DEGRADED",
|
|
20727
|
+
SHUTTING_DOWN: "SHUTTING_DOWN",
|
|
20728
|
+
SHUTDOWN: "SHUTDOWN",
|
|
20729
|
+
PRODUCTION_DISABLED: "PRODUCTION_DISABLED",
|
|
20730
|
+
REGISTRATION_FAILED: "REGISTRATION_FAILED"
|
|
20731
|
+
};
|
|
20732
|
+
var AuthState = {
|
|
20733
|
+
ANONYMOUS: "ANONYMOUS",
|
|
20734
|
+
AUTHENTICATED: "AUTHENTICATED",
|
|
20735
|
+
CLAIMING: "CLAIMING",
|
|
20736
|
+
CLAIMED: "CLAIMED"
|
|
20737
|
+
};
|
|
20738
|
+
var OtelState = {
|
|
20739
|
+
UNCONFIGURED: "UNCONFIGURED",
|
|
20740
|
+
CONFIGURING: "CONFIGURING",
|
|
20741
|
+
OWNS_PROVIDER: "OWNS_PROVIDER",
|
|
20742
|
+
AUTO_ATTACHED: "AUTO_ATTACHED",
|
|
20743
|
+
PROCESSOR_PRESENT: "PROCESSOR_PRESENT",
|
|
20744
|
+
COEXISTENCE_FAILED: "COEXISTENCE_FAILED"
|
|
20745
|
+
};
|
|
20746
|
+
var VALID_CORE_TRANSITIONS = {
|
|
20747
|
+
[CoreState.IDLE]: [CoreState.REGISTERING, CoreState.REGISTRATION_FAILED, CoreState.SHUTTING_DOWN],
|
|
20748
|
+
[CoreState.REGISTERING]: [
|
|
20749
|
+
CoreState.KEY_PENDING,
|
|
20750
|
+
CoreState.PRODUCTION_DISABLED,
|
|
20751
|
+
CoreState.REGISTRATION_FAILED,
|
|
20752
|
+
CoreState.SHUTTING_DOWN
|
|
20753
|
+
],
|
|
20754
|
+
[CoreState.KEY_PENDING]: [
|
|
20755
|
+
CoreState.KEY_RESOLVED,
|
|
20756
|
+
CoreState.REGISTRATION_FAILED,
|
|
20757
|
+
CoreState.SHUTTING_DOWN
|
|
20758
|
+
],
|
|
20759
|
+
[CoreState.KEY_RESOLVED]: [
|
|
20760
|
+
CoreState.ACTIVE,
|
|
20761
|
+
CoreState.ACTIVE_DEGRADED,
|
|
20762
|
+
CoreState.SHUTTING_DOWN
|
|
20763
|
+
],
|
|
20764
|
+
[CoreState.ACTIVE]: [
|
|
20765
|
+
CoreState.ACTIVE_DEGRADED,
|
|
20766
|
+
CoreState.SHUTTING_DOWN
|
|
20767
|
+
],
|
|
20768
|
+
[CoreState.ACTIVE_DEGRADED]: [
|
|
20769
|
+
CoreState.ACTIVE,
|
|
20770
|
+
CoreState.SHUTTING_DOWN
|
|
20771
|
+
],
|
|
20772
|
+
[CoreState.SHUTTING_DOWN]: [CoreState.SHUTDOWN],
|
|
20773
|
+
[CoreState.SHUTDOWN]: [],
|
|
20774
|
+
[CoreState.PRODUCTION_DISABLED]: [],
|
|
20775
|
+
[CoreState.REGISTRATION_FAILED]: []
|
|
20776
|
+
};
|
|
20777
|
+
var VALID_AUTH_TRANSITIONS = {
|
|
20778
|
+
[AuthState.ANONYMOUS]: [AuthState.CLAIMING],
|
|
20779
|
+
[AuthState.AUTHENTICATED]: [AuthState.CLAIMING],
|
|
20780
|
+
[AuthState.CLAIMING]: [AuthState.CLAIMED],
|
|
20781
|
+
[AuthState.CLAIMED]: [AuthState.CLAIMING]
|
|
20782
|
+
};
|
|
20783
|
+
var VALID_OTEL_TRANSITIONS = {
|
|
20784
|
+
[OtelState.UNCONFIGURED]: [OtelState.CONFIGURING],
|
|
20785
|
+
[OtelState.CONFIGURING]: [
|
|
20786
|
+
OtelState.OWNS_PROVIDER,
|
|
20787
|
+
OtelState.AUTO_ATTACHED,
|
|
20788
|
+
OtelState.PROCESSOR_PRESENT,
|
|
20789
|
+
OtelState.COEXISTENCE_FAILED
|
|
20790
|
+
],
|
|
20791
|
+
[OtelState.OWNS_PROVIDER]: [],
|
|
20792
|
+
[OtelState.AUTO_ATTACHED]: [],
|
|
20793
|
+
[OtelState.PROCESSOR_PRESENT]: [],
|
|
20794
|
+
[OtelState.COEXISTENCE_FAILED]: []
|
|
20795
|
+
};
|
|
20796
|
+
var _coreState = CoreState.IDLE;
|
|
20797
|
+
var _authState = AuthState.ANONYMOUS;
|
|
20798
|
+
var _otelState = OtelState.UNCONFIGURED;
|
|
20799
|
+
var _emitter = new import_node_events.EventEmitter();
|
|
20800
|
+
var _logger = null;
|
|
20801
|
+
var _initialized = false;
|
|
20802
|
+
var _initWarned = false;
|
|
20803
|
+
var _coreReadyEmitted = false;
|
|
20804
|
+
var _authInitialized = false;
|
|
20805
|
+
var _emitting = false;
|
|
20806
|
+
function initLifecycle(options) {
|
|
20807
|
+
if (_initialized) {
|
|
20808
|
+
options.logger("warn", "[glasstrace] initLifecycle() called twice \u2014 ignored.");
|
|
20809
|
+
return;
|
|
20810
|
+
}
|
|
20811
|
+
_logger = options.logger;
|
|
20812
|
+
_initialized = true;
|
|
20813
|
+
}
|
|
20814
|
+
function warnIfNotInitialized() {
|
|
20815
|
+
if (!_initialized && !_initWarned) {
|
|
20816
|
+
_initWarned = true;
|
|
20817
|
+
console.warn(
|
|
20818
|
+
"[glasstrace] Lifecycle state changed before initLifecycle() was called. Logger not available \u2014 errors will be silent."
|
|
20819
|
+
);
|
|
20820
|
+
}
|
|
20821
|
+
}
|
|
20822
|
+
function setCoreState(to) {
|
|
20823
|
+
warnIfNotInitialized();
|
|
20824
|
+
const from = _coreState;
|
|
20825
|
+
if (from === to) return;
|
|
20826
|
+
const valid = VALID_CORE_TRANSITIONS[from];
|
|
20827
|
+
if (!valid.includes(to)) {
|
|
20828
|
+
_logger?.(
|
|
20829
|
+
"warn",
|
|
20830
|
+
`[glasstrace] Invalid core state transition: ${from} \u2192 ${to}. Ignored.`
|
|
20831
|
+
);
|
|
20832
|
+
return;
|
|
20833
|
+
}
|
|
20834
|
+
_coreState = to;
|
|
20835
|
+
if (_emitting) return;
|
|
20836
|
+
_emitting = true;
|
|
20837
|
+
try {
|
|
20838
|
+
emitSafe("core:state_changed", { from, to });
|
|
20839
|
+
const current = _coreState;
|
|
20840
|
+
if (!_coreReadyEmitted && (current === CoreState.ACTIVE || current === CoreState.ACTIVE_DEGRADED)) {
|
|
20841
|
+
_coreReadyEmitted = true;
|
|
20842
|
+
emitSafe("core:ready", {});
|
|
20843
|
+
}
|
|
20844
|
+
if (current === CoreState.SHUTTING_DOWN) {
|
|
20845
|
+
emitSafe("core:shutdown_started", {});
|
|
20846
|
+
}
|
|
20847
|
+
if (current === CoreState.SHUTDOWN) {
|
|
20848
|
+
emitSafe("core:shutdown_completed", {});
|
|
20849
|
+
}
|
|
20850
|
+
} finally {
|
|
20851
|
+
_emitting = false;
|
|
20852
|
+
}
|
|
20853
|
+
}
|
|
20854
|
+
function initAuthState(state) {
|
|
20855
|
+
if (_authInitialized) {
|
|
20856
|
+
_logger?.(
|
|
20857
|
+
"warn",
|
|
20858
|
+
"[glasstrace] initAuthState() called after auth state already initialized. Ignored."
|
|
20859
|
+
);
|
|
20860
|
+
return;
|
|
20861
|
+
}
|
|
20862
|
+
_authInitialized = true;
|
|
20863
|
+
_authState = state;
|
|
20864
|
+
}
|
|
20865
|
+
function setAuthState(to) {
|
|
20866
|
+
warnIfNotInitialized();
|
|
20867
|
+
const from = _authState;
|
|
20868
|
+
if (from === to) return;
|
|
20869
|
+
const valid = VALID_AUTH_TRANSITIONS[from];
|
|
20870
|
+
if (!valid.includes(to)) {
|
|
20871
|
+
_logger?.(
|
|
20872
|
+
"warn",
|
|
20873
|
+
`[glasstrace] Invalid auth state transition: ${from} \u2192 ${to}. Ignored.`
|
|
20874
|
+
);
|
|
20875
|
+
return;
|
|
20876
|
+
}
|
|
20877
|
+
_authState = to;
|
|
20878
|
+
}
|
|
20879
|
+
function setOtelState(to) {
|
|
20880
|
+
warnIfNotInitialized();
|
|
20881
|
+
const from = _otelState;
|
|
20882
|
+
if (from === to) return;
|
|
20883
|
+
const valid = VALID_OTEL_TRANSITIONS[from];
|
|
20884
|
+
if (!valid.includes(to)) {
|
|
20885
|
+
_logger?.(
|
|
20886
|
+
"warn",
|
|
20887
|
+
`[glasstrace] Invalid OTel state transition: ${from} \u2192 ${to}. Ignored.`
|
|
20888
|
+
);
|
|
20889
|
+
return;
|
|
20890
|
+
}
|
|
20891
|
+
_otelState = to;
|
|
20892
|
+
}
|
|
20893
|
+
function getCoreState() {
|
|
20894
|
+
return _coreState;
|
|
20895
|
+
}
|
|
20896
|
+
function getSdkState() {
|
|
20897
|
+
return {
|
|
20898
|
+
core: _coreState,
|
|
20899
|
+
auth: _authState,
|
|
20900
|
+
otel: _otelState
|
|
20901
|
+
};
|
|
20902
|
+
}
|
|
20903
|
+
function onLifecycleEvent(event, listener) {
|
|
20904
|
+
_emitter.on(event, listener);
|
|
20905
|
+
}
|
|
20906
|
+
function emitLifecycleEvent(event, payload) {
|
|
20907
|
+
emitSafe(event, payload);
|
|
20908
|
+
}
|
|
20909
|
+
function offLifecycleEvent(event, listener) {
|
|
20910
|
+
_emitter.off(event, listener);
|
|
20911
|
+
}
|
|
20912
|
+
function emitSafe(event, payload) {
|
|
20913
|
+
const listeners = _emitter.listeners(event);
|
|
20914
|
+
for (const listener of listeners) {
|
|
20915
|
+
try {
|
|
20916
|
+
const result = listener(payload);
|
|
20917
|
+
if (result && typeof result.catch === "function") {
|
|
20918
|
+
result.catch((err) => {
|
|
20919
|
+
_logger?.(
|
|
20920
|
+
"error",
|
|
20921
|
+
`[glasstrace] Async error in lifecycle event listener for "${event}": ${err instanceof Error ? err.message : String(err)}`
|
|
20922
|
+
);
|
|
20923
|
+
});
|
|
20924
|
+
}
|
|
20925
|
+
} catch (err) {
|
|
20926
|
+
_logger?.(
|
|
20927
|
+
"error",
|
|
20928
|
+
`[glasstrace] Error in lifecycle event listener for "${event}": ${err instanceof Error ? err.message : String(err)}`
|
|
20929
|
+
);
|
|
20930
|
+
}
|
|
20931
|
+
}
|
|
20932
|
+
}
|
|
20933
|
+
function isReady() {
|
|
20934
|
+
return _coreState === CoreState.ACTIVE || _coreState === CoreState.ACTIVE_DEGRADED;
|
|
20935
|
+
}
|
|
20936
|
+
function waitForReady(timeoutMs = 3e4) {
|
|
20937
|
+
if (isReady()) {
|
|
20938
|
+
return Promise.resolve();
|
|
20939
|
+
}
|
|
20940
|
+
if (_coreState === CoreState.PRODUCTION_DISABLED || _coreState === CoreState.REGISTRATION_FAILED || _coreState === CoreState.SHUTTING_DOWN || _coreState === CoreState.SHUTDOWN) {
|
|
20941
|
+
return Promise.reject(new Error(`SDK is in terminal state: ${_coreState}`));
|
|
20942
|
+
}
|
|
20943
|
+
return new Promise((resolve3, reject) => {
|
|
20944
|
+
let settled = false;
|
|
20945
|
+
const listener = ({ to }) => {
|
|
20946
|
+
if (settled) return;
|
|
20947
|
+
if (to === CoreState.ACTIVE || to === CoreState.ACTIVE_DEGRADED) {
|
|
20948
|
+
settled = true;
|
|
20949
|
+
offLifecycleEvent("core:state_changed", listener);
|
|
20950
|
+
resolve3();
|
|
20951
|
+
} else if (to === CoreState.PRODUCTION_DISABLED || to === CoreState.REGISTRATION_FAILED || to === CoreState.SHUTTING_DOWN || to === CoreState.SHUTDOWN) {
|
|
20952
|
+
settled = true;
|
|
20953
|
+
offLifecycleEvent("core:state_changed", listener);
|
|
20954
|
+
reject(new Error(`SDK reached terminal state: ${to}`));
|
|
20955
|
+
}
|
|
20956
|
+
};
|
|
20957
|
+
onLifecycleEvent("core:state_changed", listener);
|
|
20958
|
+
if (timeoutMs > 0) {
|
|
20959
|
+
const timer = setTimeout(() => {
|
|
20960
|
+
if (settled) return;
|
|
20961
|
+
settled = true;
|
|
20962
|
+
offLifecycleEvent("core:state_changed", listener);
|
|
20963
|
+
reject(new Error(`waitForReady timed out after ${timeoutMs}ms (state: ${_coreState})`));
|
|
20964
|
+
}, timeoutMs);
|
|
20965
|
+
if (typeof timer === "object" && "unref" in timer) {
|
|
20966
|
+
timer.unref();
|
|
20967
|
+
}
|
|
20968
|
+
}
|
|
20969
|
+
});
|
|
20970
|
+
}
|
|
20971
|
+
function getStatus() {
|
|
20972
|
+
let mode;
|
|
20973
|
+
if (_coreState === CoreState.PRODUCTION_DISABLED) {
|
|
20974
|
+
mode = "disabled";
|
|
20975
|
+
} else if (_authState === AuthState.CLAIMING || _authState === AuthState.CLAIMED) {
|
|
20976
|
+
mode = "claiming";
|
|
20977
|
+
} else if (_authState === AuthState.AUTHENTICATED) {
|
|
20978
|
+
mode = "authenticated";
|
|
20979
|
+
} else {
|
|
20980
|
+
mode = "anonymous";
|
|
20981
|
+
}
|
|
20982
|
+
let tracing;
|
|
20983
|
+
if (_otelState === OtelState.COEXISTENCE_FAILED || _otelState === OtelState.UNCONFIGURED || _otelState === OtelState.CONFIGURING) {
|
|
20984
|
+
tracing = "not-configured";
|
|
20985
|
+
} else if (_coreState === CoreState.ACTIVE_DEGRADED) {
|
|
20986
|
+
tracing = "degraded";
|
|
20987
|
+
} else if (_otelState === OtelState.AUTO_ATTACHED || _otelState === OtelState.PROCESSOR_PRESENT) {
|
|
20988
|
+
tracing = "coexistence";
|
|
20989
|
+
} else {
|
|
20990
|
+
tracing = "active";
|
|
20991
|
+
}
|
|
20992
|
+
return {
|
|
20993
|
+
ready: isReady(),
|
|
20994
|
+
mode,
|
|
20995
|
+
tracing
|
|
20996
|
+
};
|
|
20997
|
+
}
|
|
20998
|
+
var _shutdownHooks = [];
|
|
20999
|
+
var _signalHandlersRegistered = false;
|
|
21000
|
+
var _signalHandler = null;
|
|
21001
|
+
var _beforeExitRegistered = false;
|
|
21002
|
+
var _beforeExitHandler = null;
|
|
21003
|
+
var _shutdownExecuted = false;
|
|
21004
|
+
function registerShutdownHook(hook) {
|
|
21005
|
+
_shutdownHooks.push(hook);
|
|
21006
|
+
_shutdownHooks.sort((a, b) => a.priority - b.priority);
|
|
21007
|
+
}
|
|
21008
|
+
async function executeShutdown(timeoutMs = 5e3) {
|
|
21009
|
+
if (_shutdownExecuted) return;
|
|
21010
|
+
_shutdownExecuted = true;
|
|
21011
|
+
setCoreState(CoreState.SHUTTING_DOWN);
|
|
21012
|
+
for (const hook of _shutdownHooks) {
|
|
21013
|
+
try {
|
|
21014
|
+
const hookPromise = hook.fn();
|
|
21015
|
+
hookPromise.catch(() => {
|
|
21016
|
+
});
|
|
21017
|
+
await Promise.race([
|
|
21018
|
+
hookPromise,
|
|
21019
|
+
new Promise((_, reject) => {
|
|
21020
|
+
const timer = setTimeout(() => reject(new Error(`Shutdown hook "${hook.name}" timed out`)), timeoutMs);
|
|
21021
|
+
if (typeof timer === "object" && "unref" in timer) {
|
|
21022
|
+
timer.unref();
|
|
21023
|
+
}
|
|
21024
|
+
})
|
|
21025
|
+
]);
|
|
21026
|
+
} catch (err) {
|
|
21027
|
+
_logger?.(
|
|
21028
|
+
"warn",
|
|
21029
|
+
`[glasstrace] Shutdown hook "${hook.name}" failed: ${err instanceof Error ? err.message : String(err)}`
|
|
21030
|
+
);
|
|
21031
|
+
}
|
|
21032
|
+
}
|
|
21033
|
+
setCoreState(CoreState.SHUTDOWN);
|
|
21034
|
+
}
|
|
21035
|
+
function registerSignalHandlers() {
|
|
21036
|
+
if (_signalHandlersRegistered) return;
|
|
21037
|
+
if (typeof process === "undefined" || typeof process.once !== "function") return;
|
|
21038
|
+
_signalHandlersRegistered = true;
|
|
21039
|
+
const handler = (signal) => {
|
|
21040
|
+
void executeShutdown().finally(() => {
|
|
21041
|
+
if (_signalHandler) {
|
|
21042
|
+
process.removeListener("SIGTERM", _signalHandler);
|
|
21043
|
+
process.removeListener("SIGINT", _signalHandler);
|
|
21044
|
+
}
|
|
21045
|
+
process.kill(process.pid, signal);
|
|
21046
|
+
});
|
|
21047
|
+
};
|
|
21048
|
+
_signalHandler = handler;
|
|
21049
|
+
process.once("SIGTERM", handler);
|
|
21050
|
+
process.once("SIGINT", handler);
|
|
21051
|
+
}
|
|
21052
|
+
function registerBeforeExitTrigger() {
|
|
21053
|
+
if (_beforeExitRegistered) return;
|
|
21054
|
+
if (typeof process === "undefined" || typeof process.once !== "function") return;
|
|
21055
|
+
_beforeExitRegistered = true;
|
|
21056
|
+
const handler = () => {
|
|
21057
|
+
void executeShutdown();
|
|
21058
|
+
};
|
|
21059
|
+
_beforeExitHandler = handler;
|
|
21060
|
+
process.once("beforeExit", handler);
|
|
21061
|
+
}
|
|
21062
|
+
|
|
21063
|
+
// src/coexistence.ts
|
|
21064
|
+
init_cjs_shims();
|
|
21065
|
+
init_env_detection();
|
|
21066
|
+
init_console_capture();
|
|
21067
|
+
function createGlasstraceSpanProcessor(options) {
|
|
21068
|
+
const config2 = resolveConfig(options);
|
|
21069
|
+
const exporterUrl = `${config2.endpoint}/v1/traces`;
|
|
21070
|
+
const createOtlpExporter = (url2, headers) => new OTLPTraceExporter({ url: url2, headers });
|
|
21071
|
+
const exporter = new GlasstraceExporter({
|
|
21072
|
+
getApiKey: getResolvedApiKey,
|
|
21073
|
+
sessionManager: getSessionManager(),
|
|
21074
|
+
getConfig: () => getActiveConfig(),
|
|
21075
|
+
environment: config2.environment,
|
|
21076
|
+
endpointUrl: exporterUrl,
|
|
21077
|
+
createDelegate: createOtlpExporter
|
|
21078
|
+
});
|
|
21079
|
+
registerExporterForKeyNotification(exporter);
|
|
21080
|
+
return new BatchSpanProcessor(exporter, {
|
|
21081
|
+
scheduledDelayMillis: 1e3
|
|
21082
|
+
});
|
|
21083
|
+
}
|
|
21084
|
+
function emitNudgeMessage() {
|
|
21085
|
+
const isSentry = detectSentry();
|
|
21086
|
+
if (isSentry) {
|
|
21087
|
+
sdkLog(
|
|
21088
|
+
"info",
|
|
21089
|
+
`[glasstrace] Detected existing OTel provider \u2014 auto-attached Glasstrace span processor.
|
|
21090
|
+
For a cleaner setup, add Glasstrace to your Sentry config:
|
|
21091
|
+
|
|
21092
|
+
import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
|
|
21093
|
+
|
|
21094
|
+
Sentry.init({
|
|
21095
|
+
dsn: '...',
|
|
21096
|
+
openTelemetrySpanProcessors: [createGlasstraceSpanProcessor()],
|
|
21097
|
+
});
|
|
21098
|
+
|
|
21099
|
+
This message will not appear once Glasstrace is added to your provider config.`
|
|
21100
|
+
);
|
|
21101
|
+
} else {
|
|
21102
|
+
sdkLog(
|
|
21103
|
+
"info",
|
|
21104
|
+
`[glasstrace] Detected existing OTel provider \u2014 auto-attached Glasstrace span processor.
|
|
21105
|
+
For a cleaner setup, add Glasstrace to your provider config:
|
|
21106
|
+
|
|
21107
|
+
import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
|
|
21108
|
+
|
|
21109
|
+
const provider = new BasicTracerProvider({
|
|
21110
|
+
spanProcessors: [
|
|
21111
|
+
// ... your existing processors,
|
|
21112
|
+
createGlasstraceSpanProcessor(),
|
|
21113
|
+
],
|
|
21114
|
+
});
|
|
21115
|
+
|
|
21116
|
+
This message will not appear once Glasstrace is added to your provider config.`
|
|
21117
|
+
);
|
|
21118
|
+
}
|
|
21119
|
+
}
|
|
21120
|
+
function emitGuidanceMessage() {
|
|
21121
|
+
const isSentry = detectSentry();
|
|
21122
|
+
if (isSentry) {
|
|
21123
|
+
sdkLog(
|
|
21124
|
+
"warn",
|
|
21125
|
+
`[glasstrace] An existing OTel TracerProvider is registered but Glasstrace could not auto-attach its span processor.
|
|
21126
|
+
Add Glasstrace to your Sentry config:
|
|
21127
|
+
|
|
21128
|
+
import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
|
|
21129
|
+
|
|
21130
|
+
Sentry.init({
|
|
21131
|
+
dsn: '...',
|
|
21132
|
+
openTelemetrySpanProcessors: [createGlasstraceSpanProcessor()],
|
|
21133
|
+
});`
|
|
21134
|
+
);
|
|
21135
|
+
} else {
|
|
21136
|
+
sdkLog(
|
|
21137
|
+
"warn",
|
|
21138
|
+
`[glasstrace] An existing OTel TracerProvider is registered but Glasstrace could not auto-attach its span processor.
|
|
21139
|
+
Add Glasstrace to your provider configuration:
|
|
21140
|
+
|
|
21141
|
+
import { createGlasstraceSpanProcessor } from '@glasstrace/sdk';
|
|
21142
|
+
|
|
21143
|
+
const provider = new BasicTracerProvider({
|
|
21144
|
+
spanProcessors: [
|
|
21145
|
+
// ... your existing processors,
|
|
21146
|
+
createGlasstraceSpanProcessor(),
|
|
21147
|
+
],
|
|
21148
|
+
});`
|
|
21149
|
+
);
|
|
21150
|
+
}
|
|
21151
|
+
}
|
|
21152
|
+
function detectSentry() {
|
|
21153
|
+
try {
|
|
21154
|
+
require.resolve("@sentry/node");
|
|
21155
|
+
return true;
|
|
21156
|
+
} catch {
|
|
21157
|
+
try {
|
|
21158
|
+
require.resolve("@sentry/nextjs");
|
|
21159
|
+
return true;
|
|
21160
|
+
} catch {
|
|
21161
|
+
return false;
|
|
21162
|
+
}
|
|
21163
|
+
}
|
|
21164
|
+
}
|
|
21165
|
+
|
|
21166
|
+
// src/otel-config.ts
|
|
20687
21167
|
var _resolvedApiKey = API_KEY_PENDING;
|
|
20688
21168
|
var _activeExporter = null;
|
|
20689
|
-
var
|
|
21169
|
+
var _additionalExporters = [];
|
|
21170
|
+
var _injectedProcessor = null;
|
|
20690
21171
|
function setResolvedApiKey(key) {
|
|
20691
21172
|
_resolvedApiKey = key;
|
|
20692
21173
|
}
|
|
@@ -20695,6 +21176,12 @@ function getResolvedApiKey() {
|
|
|
20695
21176
|
}
|
|
20696
21177
|
function notifyApiKeyResolved() {
|
|
20697
21178
|
_activeExporter?.notifyKeyResolved();
|
|
21179
|
+
for (const exporter of _additionalExporters) {
|
|
21180
|
+
exporter.notifyKeyResolved();
|
|
21181
|
+
}
|
|
21182
|
+
}
|
|
21183
|
+
function registerExporterForKeyNotification(exporter) {
|
|
21184
|
+
_additionalExporters.push(exporter);
|
|
20698
21185
|
}
|
|
20699
21186
|
async function tryImport(moduleId) {
|
|
20700
21187
|
try {
|
|
@@ -20703,34 +21190,65 @@ async function tryImport(moduleId) {
|
|
|
20703
21190
|
return null;
|
|
20704
21191
|
}
|
|
20705
21192
|
}
|
|
20706
|
-
function
|
|
20707
|
-
|
|
20708
|
-
|
|
20709
|
-
|
|
20710
|
-
|
|
20711
|
-
|
|
20712
|
-
|
|
21193
|
+
function tryInjectProcessor(tracerProvider, glasstraceExporter) {
|
|
21194
|
+
try {
|
|
21195
|
+
const proxy = tracerProvider;
|
|
21196
|
+
const delegate = typeof proxy.getDelegate === "function" ? proxy.getDelegate() : tracerProvider;
|
|
21197
|
+
const withAdd = delegate;
|
|
21198
|
+
if (typeof withAdd.addSpanProcessor === "function") {
|
|
21199
|
+
if (typeof withAdd.getActiveSpanProcessor === "function") {
|
|
21200
|
+
const active = withAdd.getActiveSpanProcessor();
|
|
21201
|
+
const brand = /* @__PURE__ */ Symbol.for("glasstrace.exporter");
|
|
21202
|
+
const processors = active?._spanProcessors;
|
|
21203
|
+
if (Array.isArray(processors) && processors.some((p) => {
|
|
21204
|
+
const exp = p._exporter;
|
|
21205
|
+
return exp?.[brand] === true;
|
|
21206
|
+
})) {
|
|
21207
|
+
return "already_present";
|
|
21208
|
+
}
|
|
21209
|
+
}
|
|
21210
|
+
const processor2 = new BatchSpanProcessor(glasstraceExporter, {
|
|
21211
|
+
scheduledDelayMillis: 1e3
|
|
21212
|
+
});
|
|
21213
|
+
withAdd.addSpanProcessor(processor2);
|
|
21214
|
+
_injectedProcessor = processor2;
|
|
21215
|
+
return "v1_public";
|
|
21216
|
+
}
|
|
21217
|
+
const provider = delegate;
|
|
21218
|
+
const multiProcessor = provider._activeSpanProcessor;
|
|
21219
|
+
if (!multiProcessor || !Array.isArray(multiProcessor._spanProcessors)) {
|
|
21220
|
+
return null;
|
|
21221
|
+
}
|
|
21222
|
+
const processor = new BatchSpanProcessor(glasstraceExporter, {
|
|
21223
|
+
scheduledDelayMillis: 1e3
|
|
21224
|
+
});
|
|
21225
|
+
multiProcessor._spanProcessors.push(processor);
|
|
21226
|
+
_injectedProcessor = processor;
|
|
21227
|
+
return "v2_private";
|
|
21228
|
+
} catch {
|
|
21229
|
+
return null;
|
|
20713
21230
|
}
|
|
20714
|
-
|
|
20715
|
-
|
|
20716
|
-
|
|
20717
|
-
|
|
20718
|
-
|
|
20719
|
-
|
|
20720
|
-
|
|
20721
|
-
|
|
20722
|
-
|
|
20723
|
-
|
|
20724
|
-
|
|
20725
|
-
|
|
21231
|
+
}
|
|
21232
|
+
function isGlasstraceProcessorPresent(tracerProvider) {
|
|
21233
|
+
try {
|
|
21234
|
+
const proxy = tracerProvider;
|
|
21235
|
+
const delegate = typeof proxy.getDelegate === "function" ? proxy.getDelegate() : tracerProvider;
|
|
21236
|
+
const provider = delegate;
|
|
21237
|
+
const processors = provider._activeSpanProcessor?._spanProcessors;
|
|
21238
|
+
if (!Array.isArray(processors)) {
|
|
21239
|
+
return false;
|
|
21240
|
+
}
|
|
21241
|
+
const brand = /* @__PURE__ */ Symbol.for("glasstrace.exporter");
|
|
21242
|
+
return processors.some((p) => {
|
|
21243
|
+
const exporter = p._exporter;
|
|
21244
|
+
return exporter?.[brand] === true;
|
|
20726
21245
|
});
|
|
20727
|
-
}
|
|
20728
|
-
|
|
20729
|
-
|
|
20730
|
-
process.once("SIGTERM", handler);
|
|
20731
|
-
process.once("SIGINT", handler);
|
|
21246
|
+
} catch {
|
|
21247
|
+
return false;
|
|
21248
|
+
}
|
|
20732
21249
|
}
|
|
20733
21250
|
async function configureOtel(config2, sessionManager) {
|
|
21251
|
+
setOtelState(OtelState.CONFIGURING);
|
|
20734
21252
|
const exporterUrl = `${config2.endpoint}/v1/traces`;
|
|
20735
21253
|
const createOtlpExporter = (url2, headers) => new OTLPTraceExporter({ url: url2, headers });
|
|
20736
21254
|
const glasstraceExporter = new GlasstraceExporter({
|
|
@@ -20743,29 +21261,87 @@ async function configureOtel(config2, sessionManager) {
|
|
|
20743
21261
|
verbose: config2.verbose
|
|
20744
21262
|
});
|
|
20745
21263
|
_activeExporter = glasstraceExporter;
|
|
21264
|
+
await new Promise((resolve3) => {
|
|
21265
|
+
if (typeof setImmediate === "function") {
|
|
21266
|
+
setImmediate(resolve3);
|
|
21267
|
+
} else {
|
|
21268
|
+
setTimeout(resolve3, 0);
|
|
21269
|
+
}
|
|
21270
|
+
});
|
|
21271
|
+
const existingProvider = trace.getTracerProvider();
|
|
21272
|
+
const probeTracer = existingProvider.getTracer("glasstrace-probe");
|
|
21273
|
+
const anotherProviderRegistered = probeTracer.constructor.name !== "ProxyTracer";
|
|
21274
|
+
if (anotherProviderRegistered) {
|
|
21275
|
+
if (isGlasstraceProcessorPresent(existingProvider)) {
|
|
21276
|
+
if (config2.verbose) {
|
|
21277
|
+
sdkLog("info", "[glasstrace] Existing provider detected \u2014 Glasstrace processor already present.");
|
|
21278
|
+
}
|
|
21279
|
+
_activeExporter = null;
|
|
21280
|
+
setOtelState(OtelState.PROCESSOR_PRESENT);
|
|
21281
|
+
emitLifecycleEvent("otel:configured", { state: OtelState.PROCESSOR_PRESENT, scenario: "B-clean" });
|
|
21282
|
+
return;
|
|
21283
|
+
}
|
|
21284
|
+
const injectionMethod = tryInjectProcessor(existingProvider, glasstraceExporter);
|
|
21285
|
+
if (injectionMethod === "already_present") {
|
|
21286
|
+
if (config2.verbose) {
|
|
21287
|
+
sdkLog("info", "[glasstrace] Existing provider detected \u2014 Glasstrace processor already present (v1 check).");
|
|
21288
|
+
}
|
|
21289
|
+
_activeExporter = null;
|
|
21290
|
+
setOtelState(OtelState.PROCESSOR_PRESENT);
|
|
21291
|
+
emitLifecycleEvent("otel:configured", { state: OtelState.PROCESSOR_PRESENT, scenario: "B-clean" });
|
|
21292
|
+
return;
|
|
21293
|
+
}
|
|
21294
|
+
if (injectionMethod) {
|
|
21295
|
+
if (config2.verbose) {
|
|
21296
|
+
sdkLog("info", "[glasstrace] Existing provider detected \u2014 auto-attaching Glasstrace processor.");
|
|
21297
|
+
}
|
|
21298
|
+
registerShutdownHook({
|
|
21299
|
+
name: "coexistence-flush",
|
|
21300
|
+
priority: 5,
|
|
21301
|
+
fn: async () => {
|
|
21302
|
+
if (_injectedProcessor) {
|
|
21303
|
+
await _injectedProcessor.forceFlush();
|
|
21304
|
+
}
|
|
21305
|
+
}
|
|
21306
|
+
});
|
|
21307
|
+
registerBeforeExitTrigger();
|
|
21308
|
+
const scenario = injectionMethod === "v1_public" ? "D1" : "B-auto";
|
|
21309
|
+
setOtelState(OtelState.AUTO_ATTACHED);
|
|
21310
|
+
emitLifecycleEvent("otel:configured", { state: OtelState.AUTO_ATTACHED, scenario });
|
|
21311
|
+
emitLifecycleEvent("otel:injection_succeeded", { method: injectionMethod });
|
|
21312
|
+
emitNudgeMessage();
|
|
21313
|
+
return;
|
|
21314
|
+
}
|
|
21315
|
+
if (config2.verbose) {
|
|
21316
|
+
sdkLog("info", "[glasstrace] Existing provider detected \u2014 could not auto-attach.");
|
|
21317
|
+
}
|
|
21318
|
+
emitGuidanceMessage();
|
|
21319
|
+
_activeExporter = null;
|
|
21320
|
+
setOtelState(OtelState.COEXISTENCE_FAILED);
|
|
21321
|
+
emitLifecycleEvent("otel:configured", { state: OtelState.COEXISTENCE_FAILED, scenario: "C/F" });
|
|
21322
|
+
emitLifecycleEvent("otel:injection_failed", { reason: "provider internals inaccessible" });
|
|
21323
|
+
const coreState = getCoreState();
|
|
21324
|
+
if (coreState === CoreState.ACTIVE || coreState === CoreState.KEY_RESOLVED) {
|
|
21325
|
+
setCoreState(CoreState.ACTIVE_DEGRADED);
|
|
21326
|
+
}
|
|
21327
|
+
return;
|
|
21328
|
+
}
|
|
20746
21329
|
const vercelOtel = await tryImport("@vercel/otel");
|
|
20747
21330
|
if (vercelOtel && typeof vercelOtel.registerOTel === "function") {
|
|
20748
21331
|
const otelConfig = {
|
|
20749
21332
|
serviceName: "glasstrace-sdk",
|
|
20750
21333
|
traceExporter: glasstraceExporter
|
|
20751
21334
|
};
|
|
20752
|
-
const
|
|
20753
|
-
if (
|
|
20754
|
-
const PrismaInstrumentation =
|
|
21335
|
+
const prismaModule2 = await tryImport("@prisma/instrumentation");
|
|
21336
|
+
if (prismaModule2) {
|
|
21337
|
+
const PrismaInstrumentation = prismaModule2.PrismaInstrumentation;
|
|
20755
21338
|
if (PrismaInstrumentation) {
|
|
20756
21339
|
otelConfig.instrumentations = [new PrismaInstrumentation()];
|
|
20757
21340
|
}
|
|
20758
21341
|
}
|
|
20759
21342
|
vercelOtel.registerOTel(otelConfig);
|
|
20760
|
-
|
|
20761
|
-
|
|
20762
|
-
const existingProvider = trace.getTracerProvider();
|
|
20763
|
-
const probeTracer = existingProvider.getTracer("glasstrace-probe");
|
|
20764
|
-
if (probeTracer.constructor.name !== "ProxyTracer") {
|
|
20765
|
-
console.warn(
|
|
20766
|
-
"[glasstrace] An existing OpenTelemetry TracerProvider is already registered. Glasstrace will not overwrite it. To use Glasstrace alongside another tracing tool, add GlasstraceExporter as an additional span processor on your existing provider."
|
|
20767
|
-
);
|
|
20768
|
-
_activeExporter = null;
|
|
21343
|
+
setOtelState(OtelState.OWNS_PROVIDER);
|
|
21344
|
+
emitLifecycleEvent("otel:configured", { state: OtelState.OWNS_PROVIDER, scenario: "E" });
|
|
20769
21345
|
return;
|
|
20770
21346
|
}
|
|
20771
21347
|
if (config2.verbose) {
|
|
@@ -20787,7 +21363,29 @@ async function configureOtel(config2, sessionManager) {
|
|
|
20787
21363
|
spanProcessors: [processor]
|
|
20788
21364
|
});
|
|
20789
21365
|
trace.setGlobalTracerProvider(provider);
|
|
20790
|
-
|
|
21366
|
+
registerShutdownHook({
|
|
21367
|
+
name: "otel-provider-shutdown",
|
|
21368
|
+
priority: 0,
|
|
21369
|
+
fn: async () => {
|
|
21370
|
+
await provider.shutdown();
|
|
21371
|
+
}
|
|
21372
|
+
});
|
|
21373
|
+
registerSignalHandlers();
|
|
21374
|
+
registerBeforeExitTrigger();
|
|
21375
|
+
const prismaModule = await tryImport("@prisma/instrumentation");
|
|
21376
|
+
if (prismaModule) {
|
|
21377
|
+
const PrismaInstrumentation = prismaModule.PrismaInstrumentation;
|
|
21378
|
+
if (PrismaInstrumentation) {
|
|
21379
|
+
try {
|
|
21380
|
+
const inst = new PrismaInstrumentation();
|
|
21381
|
+
inst.setTracerProvider(provider);
|
|
21382
|
+
inst.enable();
|
|
21383
|
+
} catch {
|
|
21384
|
+
}
|
|
21385
|
+
}
|
|
21386
|
+
}
|
|
21387
|
+
setOtelState(OtelState.OWNS_PROVIDER);
|
|
21388
|
+
emitLifecycleEvent("otel:configured", { state: OtelState.OWNS_PROVIDER, scenario: "A" });
|
|
20791
21389
|
}
|
|
20792
21390
|
|
|
20793
21391
|
// src/context-manager.ts
|
|
@@ -20838,7 +21436,7 @@ var heartbeatGeneration = 0;
|
|
|
20838
21436
|
var backoffAttempts = 0;
|
|
20839
21437
|
var backoffUntil = 0;
|
|
20840
21438
|
var tickInProgress = false;
|
|
20841
|
-
var
|
|
21439
|
+
var _shutdownHandler = null;
|
|
20842
21440
|
function startHeartbeat(config2, anonKey, sdkVersion, generation, onClaimTransition) {
|
|
20843
21441
|
if (heartbeatTimer !== null) return;
|
|
20844
21442
|
heartbeatGeneration = generation;
|
|
@@ -20891,7 +21489,7 @@ async function heartbeatTick(config2, anonKey, sdkVersion, generation, onClaimTr
|
|
|
20891
21489
|
backoffUntil = 0;
|
|
20892
21490
|
}
|
|
20893
21491
|
if (initResult?.claimResult) {
|
|
20894
|
-
onClaimTransition(initResult.claimResult.newApiKey);
|
|
21492
|
+
onClaimTransition(initResult.claimResult.newApiKey, initResult.claimResult.accountId);
|
|
20895
21493
|
}
|
|
20896
21494
|
if (config2.verbose) {
|
|
20897
21495
|
sdkLog("info", "[glasstrace] Heartbeat completed.");
|
|
@@ -20919,39 +21517,125 @@ function registerShutdownHandlers(config2, anonKey, sdkVersion) {
|
|
|
20919
21517
|
process.kill(process.pid, signal);
|
|
20920
21518
|
});
|
|
20921
21519
|
};
|
|
20922
|
-
|
|
20923
|
-
process.once("SIGTERM",
|
|
20924
|
-
process.once("SIGINT",
|
|
21520
|
+
_shutdownHandler = handler;
|
|
21521
|
+
process.once("SIGTERM", _shutdownHandler);
|
|
21522
|
+
process.once("SIGINT", _shutdownHandler);
|
|
20925
21523
|
}
|
|
20926
21524
|
function removeShutdownHandlers() {
|
|
20927
|
-
if (
|
|
20928
|
-
process.removeListener("SIGTERM",
|
|
20929
|
-
process.removeListener("SIGINT",
|
|
20930
|
-
|
|
21525
|
+
if (_shutdownHandler && typeof process !== "undefined") {
|
|
21526
|
+
process.removeListener("SIGTERM", _shutdownHandler);
|
|
21527
|
+
process.removeListener("SIGINT", _shutdownHandler);
|
|
21528
|
+
_shutdownHandler = null;
|
|
21529
|
+
}
|
|
21530
|
+
}
|
|
21531
|
+
|
|
21532
|
+
// src/runtime-state.ts
|
|
21533
|
+
init_cjs_shims();
|
|
21534
|
+
var import_node_fs = require("fs");
|
|
21535
|
+
var import_node_path = require("path");
|
|
21536
|
+
init_console_capture();
|
|
21537
|
+
var _projectRoot = null;
|
|
21538
|
+
var _sdkVersion = "unknown";
|
|
21539
|
+
var _lastScenario;
|
|
21540
|
+
var _debounceTimer = null;
|
|
21541
|
+
var _started = false;
|
|
21542
|
+
function startRuntimeStateWriter(options) {
|
|
21543
|
+
if (_started) return;
|
|
21544
|
+
_started = true;
|
|
21545
|
+
_projectRoot = options.projectRoot;
|
|
21546
|
+
_sdkVersion = options.sdkVersion;
|
|
21547
|
+
onLifecycleEvent("core:state_changed", ({ to }) => {
|
|
21548
|
+
if (to === CoreState.SHUTDOWN) {
|
|
21549
|
+
writeStateNow();
|
|
21550
|
+
} else {
|
|
21551
|
+
debouncedWrite();
|
|
21552
|
+
}
|
|
21553
|
+
});
|
|
21554
|
+
onLifecycleEvent("otel:configured", ({ scenario }) => {
|
|
21555
|
+
_lastScenario = scenario;
|
|
21556
|
+
debouncedWrite();
|
|
21557
|
+
});
|
|
21558
|
+
onLifecycleEvent("auth:key_resolved", () => debouncedWrite());
|
|
21559
|
+
onLifecycleEvent("auth:claim_started", () => debouncedWrite());
|
|
21560
|
+
onLifecycleEvent("auth:claim_completed", () => debouncedWrite());
|
|
21561
|
+
writeStateNow();
|
|
21562
|
+
}
|
|
21563
|
+
function debouncedWrite() {
|
|
21564
|
+
if (_debounceTimer) return;
|
|
21565
|
+
_debounceTimer = setTimeout(() => {
|
|
21566
|
+
_debounceTimer = null;
|
|
21567
|
+
writeStateNow();
|
|
21568
|
+
}, 1e3);
|
|
21569
|
+
if (typeof _debounceTimer === "object" && "unref" in _debounceTimer) {
|
|
21570
|
+
_debounceTimer.unref();
|
|
21571
|
+
}
|
|
21572
|
+
}
|
|
21573
|
+
function writeStateNow() {
|
|
21574
|
+
if (!_projectRoot) return;
|
|
21575
|
+
try {
|
|
21576
|
+
const state = getSdkState();
|
|
21577
|
+
const runtimeState = {
|
|
21578
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
21579
|
+
pid: process.pid,
|
|
21580
|
+
sdkVersion: _sdkVersion,
|
|
21581
|
+
core: { state: state.core },
|
|
21582
|
+
auth: { state: state.auth },
|
|
21583
|
+
otel: { state: state.otel, scenario: _lastScenario }
|
|
21584
|
+
};
|
|
21585
|
+
const dir = (0, import_node_path.join)(_projectRoot, ".glasstrace");
|
|
21586
|
+
const filePath = (0, import_node_path.join)(dir, "runtime-state.json");
|
|
21587
|
+
const tmpPath = (0, import_node_path.join)(dir, "runtime-state.json.tmp");
|
|
21588
|
+
(0, import_node_fs.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
21589
|
+
(0, import_node_fs.writeFileSync)(tmpPath, JSON.stringify(runtimeState, null, 2) + "\n", {
|
|
21590
|
+
mode: 384
|
|
21591
|
+
});
|
|
21592
|
+
(0, import_node_fs.renameSync)(tmpPath, filePath);
|
|
21593
|
+
} catch (err) {
|
|
21594
|
+
sdkLog(
|
|
21595
|
+
"warn",
|
|
21596
|
+
`[glasstrace] Failed to write runtime state: ${err instanceof Error ? err.message : String(err)}`
|
|
21597
|
+
);
|
|
20931
21598
|
}
|
|
20932
21599
|
}
|
|
20933
21600
|
|
|
20934
21601
|
// src/register.ts
|
|
21602
|
+
function maskKey(key) {
|
|
21603
|
+
if (key.length <= 12) return key.slice(0, 4) + "...";
|
|
21604
|
+
return key.slice(0, 8) + "..." + key.slice(-4);
|
|
21605
|
+
}
|
|
20935
21606
|
var consoleCaptureInstalled = false;
|
|
20936
21607
|
var discoveryHandler = null;
|
|
20937
|
-
var isRegistered = false;
|
|
20938
21608
|
var registrationGeneration = 0;
|
|
21609
|
+
var _sessionManager = null;
|
|
21610
|
+
function getSessionManager() {
|
|
21611
|
+
if (!_sessionManager) {
|
|
21612
|
+
_sessionManager = new SessionManager();
|
|
21613
|
+
}
|
|
21614
|
+
return _sessionManager;
|
|
21615
|
+
}
|
|
20939
21616
|
function registerGlasstrace(options) {
|
|
20940
21617
|
try {
|
|
20941
|
-
if (
|
|
21618
|
+
if (getCoreState() !== CoreState.IDLE) {
|
|
20942
21619
|
return;
|
|
20943
21620
|
}
|
|
21621
|
+
initLifecycle({ logger: sdkLog });
|
|
20944
21622
|
if (typeof process === "undefined" || typeof process.versions?.node !== "string") {
|
|
20945
21623
|
console.warn(
|
|
20946
21624
|
"[glasstrace] SDK requires a Node.js runtime. Edge Runtime, browser, and Deno without Node compat are not supported. Glasstrace is disabled in this environment."
|
|
20947
21625
|
);
|
|
20948
21626
|
return;
|
|
20949
21627
|
}
|
|
21628
|
+
setCoreState(CoreState.REGISTERING);
|
|
21629
|
+
startRuntimeStateWriter({
|
|
21630
|
+
projectRoot: process.cwd(),
|
|
21631
|
+
sdkVersion: "0.14.1"
|
|
21632
|
+
});
|
|
20950
21633
|
const config2 = resolveConfig(options);
|
|
20951
21634
|
if (config2.verbose) {
|
|
20952
21635
|
console.info("[glasstrace] Config resolved.");
|
|
20953
21636
|
}
|
|
20954
21637
|
if (isProductionDisabled(config2)) {
|
|
21638
|
+
setCoreState(CoreState.PRODUCTION_DISABLED);
|
|
20955
21639
|
console.warn(
|
|
20956
21640
|
"[glasstrace] Disabled in production. Set GLASSTRACE_FORCE_ENABLE=true to override."
|
|
20957
21641
|
);
|
|
@@ -20962,8 +21646,13 @@ function registerGlasstrace(options) {
|
|
|
20962
21646
|
}
|
|
20963
21647
|
const anonymous = isAnonymousMode(config2);
|
|
20964
21648
|
let effectiveKey = config2.apiKey;
|
|
21649
|
+
initAuthState(anonymous ? AuthState.ANONYMOUS : AuthState.AUTHENTICATED);
|
|
20965
21650
|
if (effectiveKey) {
|
|
20966
21651
|
setResolvedApiKey(effectiveKey);
|
|
21652
|
+
emitLifecycleEvent("auth:key_resolved", {
|
|
21653
|
+
key: maskKey(effectiveKey),
|
|
21654
|
+
mode: anonymous ? "anonymous" : "dev"
|
|
21655
|
+
});
|
|
20967
21656
|
}
|
|
20968
21657
|
if (config2.verbose) {
|
|
20969
21658
|
console.info(
|
|
@@ -20979,11 +21668,11 @@ function registerGlasstrace(options) {
|
|
|
20979
21668
|
`[glasstrace] Cached config ${cachedInitResponse ? "loaded and applied" : "not found"}.`
|
|
20980
21669
|
);
|
|
20981
21670
|
}
|
|
20982
|
-
const sessionManager =
|
|
21671
|
+
const sessionManager = getSessionManager();
|
|
20983
21672
|
if (config2.verbose) {
|
|
20984
21673
|
console.info("[glasstrace] SessionManager created.");
|
|
20985
21674
|
}
|
|
20986
|
-
|
|
21675
|
+
setCoreState(CoreState.KEY_PENDING);
|
|
20987
21676
|
const currentGeneration = registrationGeneration;
|
|
20988
21677
|
const existingProbe = trace.getTracerProvider().getTracer("glasstrace-probe");
|
|
20989
21678
|
const anotherProviderRegistered = existingProbe.constructor.name !== "ProxyTracer";
|
|
@@ -21036,6 +21725,7 @@ function registerGlasstrace(options) {
|
|
|
21036
21725
|
resolvedAnonKey = anonKey;
|
|
21037
21726
|
setResolvedApiKey(anonKey);
|
|
21038
21727
|
notifyApiKeyResolved();
|
|
21728
|
+
emitLifecycleEvent("auth:key_resolved", { key: maskKey(anonKey), mode: "anonymous" });
|
|
21039
21729
|
effectiveKey = anonKey;
|
|
21040
21730
|
if (currentGeneration !== registrationGeneration) return;
|
|
21041
21731
|
discoveryHandler = createDiscoveryHandler(
|
|
@@ -21057,6 +21747,7 @@ function registerGlasstrace(options) {
|
|
|
21057
21747
|
const anonKey = await getOrCreateAnonKey();
|
|
21058
21748
|
setResolvedApiKey(anonKey);
|
|
21059
21749
|
notifyApiKeyResolved();
|
|
21750
|
+
emitLifecycleEvent("auth:key_resolved", { key: maskKey(anonKey), mode: "anonymous" });
|
|
21060
21751
|
effectiveKey = anonKey;
|
|
21061
21752
|
if (currentGeneration !== registrationGeneration) return;
|
|
21062
21753
|
await backgroundInit(config2, anonKey, currentGeneration);
|
|
@@ -21089,6 +21780,7 @@ function registerGlasstrace(options) {
|
|
|
21089
21780
|
console.info("[glasstrace] Import graph building skipped.");
|
|
21090
21781
|
}
|
|
21091
21782
|
} catch (err) {
|
|
21783
|
+
setCoreState(CoreState.REGISTRATION_FAILED);
|
|
21092
21784
|
console.warn(
|
|
21093
21785
|
`[glasstrace] Registration failed: ${err instanceof Error ? err.message : String(err)}`
|
|
21094
21786
|
);
|
|
@@ -21098,18 +21790,37 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
|
|
|
21098
21790
|
if (config2.verbose) {
|
|
21099
21791
|
console.info("[glasstrace] Background init firing.");
|
|
21100
21792
|
}
|
|
21101
|
-
const healthReport = collectHealthReport("0.
|
|
21102
|
-
const initResult = await performInit(config2, anonKeyForInit, "0.
|
|
21793
|
+
const healthReport = collectHealthReport("0.14.1");
|
|
21794
|
+
const initResult = await performInit(config2, anonKeyForInit, "0.14.1", healthReport);
|
|
21103
21795
|
if (generation !== registrationGeneration) return;
|
|
21796
|
+
const currentState = getCoreState();
|
|
21797
|
+
if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
|
|
21798
|
+
return;
|
|
21799
|
+
}
|
|
21800
|
+
if (currentState === CoreState.KEY_PENDING) {
|
|
21801
|
+
setCoreState(CoreState.KEY_RESOLVED);
|
|
21802
|
+
}
|
|
21803
|
+
if (getCoreState() === CoreState.KEY_RESOLVED) {
|
|
21804
|
+
setCoreState(didLastInitSucceed() ? CoreState.ACTIVE : CoreState.ACTIVE_DEGRADED);
|
|
21805
|
+
}
|
|
21104
21806
|
if (initResult?.claimResult) {
|
|
21105
|
-
|
|
21807
|
+
const { newApiKey, accountId } = initResult.claimResult;
|
|
21808
|
+
setAuthState(AuthState.CLAIMING);
|
|
21809
|
+
emitLifecycleEvent("auth:claim_started", { accountId });
|
|
21810
|
+
setResolvedApiKey(newApiKey);
|
|
21106
21811
|
notifyApiKeyResolved();
|
|
21812
|
+
setAuthState(AuthState.CLAIMED);
|
|
21813
|
+
emitLifecycleEvent("auth:claim_completed", { newKey: maskKey(newApiKey), accountId });
|
|
21107
21814
|
}
|
|
21108
21815
|
maybeInstallConsoleCapture();
|
|
21109
21816
|
if (didLastInitSucceed()) {
|
|
21110
|
-
startHeartbeat(config2, anonKeyForInit, "0.
|
|
21817
|
+
startHeartbeat(config2, anonKeyForInit, "0.14.1", generation, (newApiKey, accountId) => {
|
|
21818
|
+
setAuthState(AuthState.CLAIMING);
|
|
21819
|
+
emitLifecycleEvent("auth:claim_started", { accountId });
|
|
21111
21820
|
setResolvedApiKey(newApiKey);
|
|
21112
21821
|
notifyApiKeyResolved();
|
|
21822
|
+
setAuthState(AuthState.CLAIMED);
|
|
21823
|
+
emitLifecycleEvent("auth:claim_completed", { newKey: maskKey(newApiKey), accountId });
|
|
21113
21824
|
});
|
|
21114
21825
|
}
|
|
21115
21826
|
}
|
|
@@ -21407,6 +22118,7 @@ async function buildImportGraph(projectRoot) {
|
|
|
21407
22118
|
collectSourceMaps,
|
|
21408
22119
|
computeBuildHash,
|
|
21409
22120
|
createDiscoveryHandler,
|
|
22121
|
+
createGlasstraceSpanProcessor,
|
|
21410
22122
|
deriveSessionId,
|
|
21411
22123
|
discoverSourceMapFiles,
|
|
21412
22124
|
discoverTestFiles,
|
|
@@ -21417,8 +22129,10 @@ async function buildImportGraph(projectRoot) {
|
|
|
21417
22129
|
getLinkedAccountId,
|
|
21418
22130
|
getOrCreateAnonKey,
|
|
21419
22131
|
getOrigin,
|
|
22132
|
+
getStatus,
|
|
21420
22133
|
isAnonymousMode,
|
|
21421
22134
|
isProductionDisabled,
|
|
22135
|
+
isReady,
|
|
21422
22136
|
loadCachedConfig,
|
|
21423
22137
|
performInit,
|
|
21424
22138
|
readAnonKey,
|
|
@@ -21430,6 +22144,7 @@ async function buildImportGraph(projectRoot) {
|
|
|
21430
22144
|
uploadSourceMaps,
|
|
21431
22145
|
uploadSourceMapsAuto,
|
|
21432
22146
|
uploadSourceMapsPresigned,
|
|
22147
|
+
waitForReady,
|
|
21433
22148
|
withGlasstraceConfig
|
|
21434
22149
|
});
|
|
21435
22150
|
//# sourceMappingURL=index.cjs.map
|