@glasstrace/sdk 1.15.0 → 1.15.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/README.md CHANGED
@@ -363,6 +363,49 @@ A future SDK release may extend the auto-attach detection to recognize
363
363
  additional Next 16 provider shapes; until that ships, the manual path
364
364
  above is the production-supported integration.
365
365
 
366
+ ## Database query spans (Prisma)
367
+
368
+ When Glasstrace manages the OpenTelemetry provider — the default when
369
+ your app does not already run its own OpenTelemetry or Sentry setup — it
370
+ automatically instruments [Prisma](https://www.prisma.io/) queries.
371
+ Install
372
+ [`@prisma/instrumentation`](https://www.npmjs.com/package/@prisma/instrumentation)
373
+ (an optional peer dependency, Prisma 4–7) and query spans appear once the
374
+ package is reachable; no extra wiring is required.
375
+
376
+ If Glasstrace instead detects a provider you already registered (Sentry,
377
+ a custom OpenTelemetry SDK, and similar), it attaches its exporter to
378
+ that provider rather than taking over instrumentation — so it does not
379
+ add Prisma instrumentation itself, and the diagnostic below does not
380
+ apply. Register `@prisma/instrumentation` on your own provider;
381
+ Glasstrace exports the spans it produces.
382
+
383
+ Prisma ORM versions **4.2.0 through 6.1.0** additionally require enabling
384
+ the `tracing`
385
+ [preview feature](https://www.prisma.io/docs/orm/prisma-client/observability-and-logging/opentelemetry-tracing)
386
+ in your schema's `generator` block — `previewFeatures = ["tracing"]` —
387
+ before any tracing spans are emitted. Later Prisma versions need no flag.
388
+
389
+ **Missing Prisma query spans?** On Prisma 4.2.0–6.1.0, first confirm the
390
+ `tracing` preview feature above is enabled. Otherwise, the usual cause is
391
+ a package manager that does not expose transitive copies of optional
392
+ peers. Under pnpm's
393
+ strict, isolated `node_modules`, `@prisma/instrumentation` can sit in
394
+ the virtual store (pulled in by another dependency) without being
395
+ linked into your app's `node_modules/@prisma/` — so the SDK's optional
396
+ import resolves to nothing and Prisma spans are silently skipped. Add it
397
+ as a **direct dependency** of your app:
398
+
399
+ ```bash
400
+ npm install @prisma/instrumentation
401
+ # pnpm add @prisma/instrumentation
402
+ ```
403
+
404
+ To confirm whether it was loaded, enable verbose mode
405
+ (`registerGlasstrace({ verbose: true })`): when
406
+ `@prisma/instrumentation` cannot be loaded, the SDK logs a diagnostic
407
+ noting that Prisma query spans will not be captured.
408
+
366
409
  ## Capturing error response bodies
367
410
 
368
411
  When debugging a 4xx or 5xx, the response body is often the most useful
@@ -3892,6 +3892,13 @@ async function tryImport(moduleId) {
3892
3892
  return null;
3893
3893
  }
3894
3894
  }
3895
+ function warnPrismaInstrumentationUnavailable(verbose, detail) {
3896
+ if (!verbose) return;
3897
+ sdkLog(
3898
+ "warn",
3899
+ `[glasstrace] @prisma/instrumentation ${detail}; Prisma query spans will not be captured. If you use Prisma and expect database spans, add @prisma/instrumentation as a direct dependency (some package managers, e.g. pnpm, do not expose transitive copies).`
3900
+ );
3901
+ }
3895
3902
  async function configureOtel(config, sessionManager) {
3896
3903
  setOtelState(OtelState.CONFIGURING);
3897
3904
  await new Promise((resolve2) => {
@@ -3999,7 +4006,14 @@ async function runRegistrationPath(config, sessionManager) {
3999
4006
  const PrismaInstrumentation = prismaModule2.PrismaInstrumentation;
4000
4007
  if (PrismaInstrumentation) {
4001
4008
  otelConfig.instrumentations = [new PrismaInstrumentation()];
4009
+ } else {
4010
+ warnPrismaInstrumentationUnavailable(
4011
+ config.verbose,
4012
+ "was loaded but did not export PrismaInstrumentation"
4013
+ );
4002
4014
  }
4015
+ } else {
4016
+ warnPrismaInstrumentationUnavailable(config.verbose, "could not be loaded");
4003
4017
  }
4004
4018
  vercelOtel.registerOTel(otelConfig);
4005
4019
  const vercelProxy = trace.getTracerProvider();
@@ -4054,9 +4068,22 @@ async function runRegistrationPath(config, sessionManager) {
4054
4068
  const inst = new PrismaInstrumentation();
4055
4069
  inst.setTracerProvider(provider);
4056
4070
  inst.enable();
4057
- } catch {
4071
+ } catch (err) {
4072
+ if (config.verbose) {
4073
+ sdkLog(
4074
+ "warn",
4075
+ `[glasstrace] @prisma/instrumentation failed to initialize: ${err instanceof Error ? err.message : String(err)}. Prisma query spans will not be captured.`
4076
+ );
4077
+ }
4058
4078
  }
4079
+ } else {
4080
+ warnPrismaInstrumentationUnavailable(
4081
+ config.verbose,
4082
+ "was loaded but did not export PrismaInstrumentation"
4083
+ );
4059
4084
  }
4085
+ } else {
4086
+ warnPrismaInstrumentationUnavailable(config.verbose, "could not be loaded");
4060
4087
  }
4061
4088
  setOtelState(OtelState.OWNS_PROVIDER);
4062
4089
  emitLifecycleEvent("otel:configured", { state: OtelState.OWNS_PROVIDER, scenario: "A" });
@@ -4969,11 +4996,11 @@ function registerGlasstrace(options) {
4969
4996
  setCoreState(CoreState.REGISTERING);
4970
4997
  maybeWarnStaleAgentInstructions({
4971
4998
  projectRoot: process.cwd(),
4972
- sdkVersion: "1.15.0"
4999
+ sdkVersion: "1.15.1"
4973
5000
  });
4974
5001
  startRuntimeStateWriter({
4975
5002
  projectRoot: process.cwd(),
4976
- sdkVersion: "1.15.0"
5003
+ sdkVersion: "1.15.1"
4977
5004
  });
4978
5005
  const config = resolveConfig(options);
4979
5006
  setSideEffectVerboseFlag(config.verbose);
@@ -5141,8 +5168,8 @@ async function backgroundInit(config, anonKeyForInit, generation) {
5141
5168
  if (config.verbose) {
5142
5169
  console.info("[glasstrace] Background init firing.");
5143
5170
  }
5144
- const healthReport = collectHealthReport("1.15.0");
5145
- const initResult = await performInit(config, anonKeyForInit, "1.15.0", healthReport);
5171
+ const healthReport = collectHealthReport("1.15.1");
5172
+ const initResult = await performInit(config, anonKeyForInit, "1.15.1", healthReport);
5146
5173
  if (generation !== registrationGeneration) return;
5147
5174
  const currentState = getCoreState();
5148
5175
  if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
@@ -5165,7 +5192,7 @@ async function backgroundInit(config, anonKeyForInit, generation) {
5165
5192
  }
5166
5193
  maybeInstallConsoleCapture();
5167
5194
  if (didLastInitSucceed()) {
5168
- startHeartbeat(config, anonKeyForInit, "1.15.0", generation, (newApiKey, accountId) => {
5195
+ startHeartbeat(config, anonKeyForInit, "1.15.1", generation, (newApiKey, accountId) => {
5169
5196
  setAuthState(AuthState.CLAIMING);
5170
5197
  emitLifecycleEvent("auth:claim_started", { accountId });
5171
5198
  setResolvedApiKey(newApiKey);
@@ -5563,4 +5590,4 @@ export {
5563
5590
  withGlasstraceConfig,
5564
5591
  captureError
5565
5592
  };
5566
- //# sourceMappingURL=chunk-PSMSSLQY.js.map
5593
+ //# sourceMappingURL=chunk-T4ETJJSK.js.map