@sentry/node 9.9.0 → 9.10.0
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/build/cjs/index.js +2 -0
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/integrations/anr/index.js +1 -1
- package/build/cjs/integrations/console.js +1 -1
- package/build/cjs/integrations/console.js.map +1 -1
- package/build/cjs/integrations/local-variables/local-variables-async.js +1 -1
- package/build/cjs/integrations/tracing/connect.js +1 -1
- package/build/cjs/integrations/tracing/connect.js.map +1 -1
- package/build/cjs/integrations/tracing/dataloader.js +24 -18
- package/build/cjs/integrations/tracing/dataloader.js.map +1 -1
- package/build/cjs/integrations/tracing/genericPool.js +16 -11
- package/build/cjs/integrations/tracing/genericPool.js.map +1 -1
- package/build/cjs/integrations/tracing/knex.js +14 -9
- package/build/cjs/integrations/tracing/knex.js.map +1 -1
- package/build/cjs/integrations/tracing/prisma.js +19 -7
- package/build/cjs/integrations/tracing/prisma.js.map +1 -1
- package/build/cjs/integrations/tracing/tedious.js +18 -13
- package/build/cjs/integrations/tracing/tedious.js.map +1 -1
- package/build/cjs/integrations/tracing/vercelai/index.js +135 -134
- package/build/cjs/integrations/tracing/vercelai/index.js.map +1 -1
- package/build/cjs/integrations/tracing/vercelai/instrumentation.js +20 -5
- package/build/cjs/integrations/tracing/vercelai/instrumentation.js.map +1 -1
- package/build/cjs/log.js +200 -0
- package/build/cjs/log.js.map +1 -0
- package/build/cjs/otel/instrument.js +54 -3
- package/build/cjs/otel/instrument.js.map +1 -1
- package/build/cjs/sdk/index.js +15 -33
- package/build/cjs/sdk/index.js.map +1 -1
- package/build/esm/index.js +2 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/integrations/anr/index.js +1 -1
- package/build/esm/integrations/anr/worker-script.js +2 -2
- package/build/esm/integrations/console.js +2 -2
- package/build/esm/integrations/console.js.map +1 -1
- package/build/esm/integrations/local-variables/local-variables-async.js +1 -1
- package/build/esm/integrations/local-variables/worker-script.js +2 -2
- package/build/esm/integrations/tracing/connect.js +1 -1
- package/build/esm/integrations/tracing/connect.js.map +1 -1
- package/build/esm/integrations/tracing/dataloader.js +26 -20
- package/build/esm/integrations/tracing/dataloader.js.map +1 -1
- package/build/esm/integrations/tracing/genericPool.js +17 -12
- package/build/esm/integrations/tracing/genericPool.js.map +1 -1
- package/build/esm/integrations/tracing/knex.js +15 -10
- package/build/esm/integrations/tracing/knex.js.map +1 -1
- package/build/esm/integrations/tracing/prisma.js +19 -7
- package/build/esm/integrations/tracing/prisma.js.map +1 -1
- package/build/esm/integrations/tracing/tedious.js +19 -14
- package/build/esm/integrations/tracing/tedious.js.map +1 -1
- package/build/esm/integrations/tracing/vercelai/index.js +136 -135
- package/build/esm/integrations/tracing/vercelai/index.js.map +1 -1
- package/build/esm/integrations/tracing/vercelai/instrumentation.js +21 -6
- package/build/esm/integrations/tracing/vercelai/instrumentation.js.map +1 -1
- package/build/esm/log.js +193 -0
- package/build/esm/log.js.map +1 -0
- package/build/esm/otel/instrument.js +54 -4
- package/build/esm/otel/instrument.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/sdk/index.js +16 -34
- package/build/esm/sdk/index.js.map +1 -1
- package/build/types/index.d.ts +2 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/integrations/console.d.ts.map +1 -1
- package/build/types/integrations/http/index.d.ts +1 -1
- package/build/types/integrations/tracing/amqplib.d.ts +2 -1
- package/build/types/integrations/tracing/amqplib.d.ts.map +1 -1
- package/build/types/integrations/tracing/connect.d.ts +2 -1
- package/build/types/integrations/tracing/connect.d.ts.map +1 -1
- package/build/types/integrations/tracing/dataloader.d.ts +2 -1
- package/build/types/integrations/tracing/dataloader.d.ts.map +1 -1
- package/build/types/integrations/tracing/express.d.ts +4 -2
- package/build/types/integrations/tracing/express.d.ts.map +1 -1
- package/build/types/integrations/tracing/fastify.d.ts +2 -1
- package/build/types/integrations/tracing/fastify.d.ts.map +1 -1
- package/build/types/integrations/tracing/genericPool.d.ts +2 -1
- package/build/types/integrations/tracing/genericPool.d.ts.map +1 -1
- package/build/types/integrations/tracing/graphql.d.ts +1 -1
- package/build/types/integrations/tracing/hapi/index.d.ts +2 -1
- package/build/types/integrations/tracing/hapi/index.d.ts.map +1 -1
- package/build/types/integrations/tracing/kafka.d.ts +2 -1
- package/build/types/integrations/tracing/kafka.d.ts.map +1 -1
- package/build/types/integrations/tracing/knex.d.ts +2 -1
- package/build/types/integrations/tracing/knex.d.ts.map +1 -1
- package/build/types/integrations/tracing/koa.d.ts +2 -1
- package/build/types/integrations/tracing/koa.d.ts.map +1 -1
- package/build/types/integrations/tracing/lrumemoizer.d.ts +2 -1
- package/build/types/integrations/tracing/lrumemoizer.d.ts.map +1 -1
- package/build/types/integrations/tracing/mongo.d.ts +2 -1
- package/build/types/integrations/tracing/mongo.d.ts.map +1 -1
- package/build/types/integrations/tracing/mongoose.d.ts +2 -1
- package/build/types/integrations/tracing/mongoose.d.ts.map +1 -1
- package/build/types/integrations/tracing/mysql.d.ts +2 -1
- package/build/types/integrations/tracing/mysql.d.ts.map +1 -1
- package/build/types/integrations/tracing/mysql2.d.ts +2 -1
- package/build/types/integrations/tracing/mysql2.d.ts.map +1 -1
- package/build/types/integrations/tracing/postgres.d.ts +2 -1
- package/build/types/integrations/tracing/postgres.d.ts.map +1 -1
- package/build/types/integrations/tracing/prisma.d.ts +1 -1
- package/build/types/integrations/tracing/prisma.d.ts.map +1 -1
- package/build/types/integrations/tracing/tedious.d.ts +2 -1
- package/build/types/integrations/tracing/tedious.d.ts.map +1 -1
- package/build/types/integrations/tracing/vercelai/index.d.ts +2 -1
- package/build/types/integrations/tracing/vercelai/index.d.ts.map +1 -1
- package/build/types/integrations/tracing/vercelai/instrumentation.d.ts +7 -1
- package/build/types/integrations/tracing/vercelai/instrumentation.d.ts.map +1 -1
- package/build/types/log.d.ts +151 -0
- package/build/types/log.d.ts.map +1 -0
- package/build/types/otel/instrument.d.ts +14 -1
- package/build/types/otel/instrument.d.ts.map +1 -1
- package/build/types/sdk/index.d.ts.map +1 -1
- package/build/types-ts3.8/index.d.ts +2 -0
- package/build/types-ts3.8/integrations/http/index.d.ts +1 -1
- package/build/types-ts3.8/integrations/tracing/amqplib.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/connect.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/dataloader.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/express.d.ts +4 -2
- package/build/types-ts3.8/integrations/tracing/fastify.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/genericPool.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/graphql.d.ts +1 -1
- package/build/types-ts3.8/integrations/tracing/hapi/index.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/kafka.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/knex.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/koa.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/lrumemoizer.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/mongo.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/mongoose.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/mysql.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/mysql2.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/postgres.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/prisma.d.ts +1 -1
- package/build/types-ts3.8/integrations/tracing/tedious.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/vercelai/index.d.ts +2 -1
- package/build/types-ts3.8/integrations/tracing/vercelai/instrumentation.d.ts +7 -1
- package/build/types-ts3.8/log.d.ts +158 -0
- package/build/types-ts3.8/otel/instrument.d.ts +14 -1
- package/package.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataloader.js","sources":["../../../../src/integrations/tracing/dataloader.ts"],"sourcesContent":["import { DataloaderInstrumentation } from '@opentelemetry/instrumentation-dataloader';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n defineIntegration,\n spanToJSON,\n} from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/core';\nimport { generateInstrumentOnce } from '../../otel/instrument';\n\nconst INTEGRATION_NAME = 'Dataloader';\n\nexport const instrumentDataloader = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new DataloaderInstrumentation({\n requireParentSpan: true,\n }),\n);\n\nconst _dataloaderIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentDataloader();\n },\n\n setup(client) {\n client.on('spanStart', span => {\n
|
|
1
|
+
{"version":3,"file":"dataloader.js","sources":["../../../../src/integrations/tracing/dataloader.ts"],"sourcesContent":["import { DataloaderInstrumentation } from '@opentelemetry/instrumentation-dataloader';\nimport {\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n defineIntegration,\n spanToJSON,\n} from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/core';\nimport { instrumentWhenWrapped, generateInstrumentOnce } from '../../otel/instrument';\n\nconst INTEGRATION_NAME = 'Dataloader';\n\nexport const instrumentDataloader = generateInstrumentOnce(\n INTEGRATION_NAME,\n () =>\n new DataloaderInstrumentation({\n requireParentSpan: true,\n }),\n);\n\nconst _dataloaderIntegration = (() => {\n let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n const instrumentation = instrumentDataloader();\n instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);\n },\n\n setup(client) {\n // This is called either immediately or when the instrumentation is wrapped\n instrumentationWrappedCallback?.(() => {\n client.on('spanStart', span => {\n const spanJSON = spanToJSON(span);\n if (spanJSON.description?.startsWith('dataloader')) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.dataloader');\n }\n\n // These are all possible dataloader span descriptions\n // Still checking for the future versions\n // in case they add support for `clear` and `prime`\n if (\n spanJSON.description === 'dataloader.load' ||\n spanJSON.description === 'dataloader.loadMany' ||\n spanJSON.description === 'dataloader.batch'\n ) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'cache.get');\n // TODO: We can try adding `key` to the `data` attribute upstream.\n // Or alternatively, we can add `requestHook` to the dataloader instrumentation.\n }\n });\n });\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [dataloader](https://www.npmjs.com/package/dataloader) library.\n *\n * For more information, see the [`dataloaderIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/dataloader/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.dataloaderIntegration()],\n * });\n * ```\n */\nexport const dataloaderIntegration = defineIntegration(_dataloaderIntegration);\n"],"names":[],"mappings":";;;;AAUA,MAAM,gBAAA,GAAmB,YAAY;;AAE9B,MAAM,oBAAqB,GAAE,sBAAsB;AAC1D,EAAE,gBAAgB;AAClB,EAAE;AACF,IAAI,IAAI,yBAAyB,CAAC;AAClC,MAAM,iBAAiB,EAAE,IAAI;AAC7B,KAAK,CAAC;AACN;;AAEA,MAAM,sBAAuB,IAAG,MAAM;AACtC,EAAE,IAAI,8BAA8B;;AAEpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,MAAM,eAAA,GAAkB,oBAAoB,EAAE;AACpD,MAAM,8BAA+B,GAAE,qBAAqB,CAAC,eAAe,CAAC;AAC7E,KAAK;;AAEL,IAAI,KAAK,CAAC,MAAM,EAAE;AAClB;AACA,MAAM,8BAA8B,GAAG,MAAM;AAC7C,QAAQ,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ;AACvC,UAAU,MAAM,QAAS,GAAE,UAAU,CAAC,IAAI,CAAC;AAC3C,UAAU,IAAI,QAAQ,CAAC,WAAW,EAAE,UAAU,CAAC,YAAY,CAAC,EAAE;AAC9D,YAAY,IAAI,CAAC,YAAY,CAAC,gCAAgC,EAAE,yBAAyB,CAAC;AAC1F;;AAEA;AACA;AACA;AACA,UAAU;AACV,YAAY,QAAQ,CAAC,WAAY,KAAI,iBAAkB;AACvD,YAAY,QAAQ,CAAC,WAAY,KAAI,qBAAsB;AAC3D,YAAY,QAAQ,CAAC,WAAA,KAAgB;AACrC,YAAY;AACZ,YAAY,IAAI,CAAC,YAAY,CAAC,4BAA4B,EAAE,WAAW,CAAC;AACxE;AACA;AACA;AACA,SAAS,CAAC;AACV,OAAO,CAAC;AACR,KAAK;AACL,GAAG;AACH,CAAC,CAAE;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,qBAAsB,GAAE,iBAAiB,CAAC,sBAAsB;;;;"}
|
|
@@ -1,32 +1,37 @@
|
|
|
1
1
|
import { GenericPoolInstrumentation } from '@opentelemetry/instrumentation-generic-pool';
|
|
2
2
|
import { defineIntegration, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';
|
|
3
|
-
import { generateInstrumentOnce } from '../../otel/instrument.js';
|
|
3
|
+
import { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument.js';
|
|
4
4
|
|
|
5
5
|
const INTEGRATION_NAME = 'GenericPool';
|
|
6
6
|
|
|
7
7
|
const instrumentGenericPool = generateInstrumentOnce(INTEGRATION_NAME, () => new GenericPoolInstrumentation({}));
|
|
8
8
|
|
|
9
9
|
const _genericPoolIntegration = (() => {
|
|
10
|
+
let instrumentationWrappedCallback;
|
|
11
|
+
|
|
10
12
|
return {
|
|
11
13
|
name: INTEGRATION_NAME,
|
|
12
14
|
setupOnce() {
|
|
13
|
-
instrumentGenericPool();
|
|
15
|
+
const instrumentation = instrumentGenericPool();
|
|
16
|
+
instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);
|
|
14
17
|
},
|
|
15
18
|
|
|
16
19
|
setup(client) {
|
|
17
|
-
|
|
18
|
-
|
|
20
|
+
instrumentationWrappedCallback?.(() =>
|
|
21
|
+
client.on('spanStart', span => {
|
|
22
|
+
const spanJSON = spanToJSON(span);
|
|
19
23
|
|
|
20
|
-
|
|
24
|
+
const spanDescription = spanJSON.description;
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
26
|
+
// typo in emitted span for version <= 0.38.0 of @opentelemetry/instrumentation-generic-pool
|
|
27
|
+
const isGenericPoolSpan =
|
|
28
|
+
spanDescription === 'generic-pool.aquire' || spanDescription === 'generic-pool.acquire';
|
|
25
29
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
if (isGenericPoolSpan) {
|
|
31
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.generic_pool');
|
|
32
|
+
}
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
30
35
|
},
|
|
31
36
|
};
|
|
32
37
|
}) ;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"genericPool.js","sources":["../../../../src/integrations/tracing/genericPool.ts"],"sourcesContent":["import { GenericPoolInstrumentation } from '@opentelemetry/instrumentation-generic-pool';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/core';\nimport { generateInstrumentOnce } from '../../otel/instrument';\n\nconst INTEGRATION_NAME = 'GenericPool';\n\nexport const instrumentGenericPool = generateInstrumentOnce(INTEGRATION_NAME, () => new GenericPoolInstrumentation({}));\n\nconst _genericPoolIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentGenericPool();\n },\n\n setup(client) {\n client.on('spanStart', span => {\n
|
|
1
|
+
{"version":3,"file":"genericPool.js","sources":["../../../../src/integrations/tracing/genericPool.ts"],"sourcesContent":["import { GenericPoolInstrumentation } from '@opentelemetry/instrumentation-generic-pool';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/core';\nimport { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument';\n\nconst INTEGRATION_NAME = 'GenericPool';\n\nexport const instrumentGenericPool = generateInstrumentOnce(INTEGRATION_NAME, () => new GenericPoolInstrumentation({}));\n\nconst _genericPoolIntegration = (() => {\n let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n const instrumentation = instrumentGenericPool();\n instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);\n },\n\n setup(client) {\n instrumentationWrappedCallback?.(() =>\n client.on('spanStart', span => {\n const spanJSON = spanToJSON(span);\n\n const spanDescription = spanJSON.description;\n\n // typo in emitted span for version <= 0.38.0 of @opentelemetry/instrumentation-generic-pool\n const isGenericPoolSpan =\n spanDescription === 'generic-pool.aquire' || spanDescription === 'generic-pool.acquire';\n\n if (isGenericPoolSpan) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.generic_pool');\n }\n }),\n );\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [generic-pool](https://www.npmjs.com/package/generic-pool) library.\n *\n * For more information, see the [`genericPoolIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/genericpool/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.genericPoolIntegration()],\n * });\n * ```\n */\nexport const genericPoolIntegration = defineIntegration(_genericPoolIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,aAAa;;MAEzB,qBAAsB,GAAE,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,0BAA0B,CAAC,EAAE,CAAC;;AAEtH,MAAM,uBAAwB,IAAG,MAAM;AACvC,EAAE,IAAI,8BAA8B;;AAEpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,MAAM,eAAA,GAAkB,qBAAqB,EAAE;AACrD,MAAM,8BAA+B,GAAE,qBAAqB,CAAC,eAAe,CAAC;AAC7E,KAAK;;AAEL,IAAI,KAAK,CAAC,MAAM,EAAE;AAClB,MAAM,8BAA8B,GAAG;AACvC,QAAQ,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ;AACvC,UAAU,MAAM,QAAS,GAAE,UAAU,CAAC,IAAI,CAAC;;AAE3C,UAAU,MAAM,eAAA,GAAkB,QAAQ,CAAC,WAAW;;AAEtD;AACA,UAAU,MAAM,iBAAkB;AAClC,YAAY,oBAAoB,qBAAA,IAAyB,eAAA,KAAoB,sBAAsB;;AAEnG,UAAU,IAAI,iBAAiB,EAAE;AACjC,YAAY,IAAI,CAAC,YAAY,CAAC,gCAAgC,EAAE,2BAA2B,CAAC;AAC5F;AACA,SAAS,CAAC;AACV,OAAO;AACP,KAAK;AACL,GAAG;AACH,CAAC,CAAE;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,sBAAuB,GAAE,iBAAiB,CAAC,uBAAuB;;;;"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { KnexInstrumentation } from '@opentelemetry/instrumentation-knex';
|
|
2
2
|
import { defineIntegration, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';
|
|
3
|
-
import { generateInstrumentOnce } from '../../otel/instrument.js';
|
|
3
|
+
import { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument.js';
|
|
4
4
|
|
|
5
5
|
const INTEGRATION_NAME = 'Knex';
|
|
6
6
|
|
|
@@ -10,21 +10,26 @@ const instrumentKnex = generateInstrumentOnce(
|
|
|
10
10
|
);
|
|
11
11
|
|
|
12
12
|
const _knexIntegration = (() => {
|
|
13
|
+
let instrumentationWrappedCallback;
|
|
14
|
+
|
|
13
15
|
return {
|
|
14
16
|
name: INTEGRATION_NAME,
|
|
15
17
|
setupOnce() {
|
|
16
|
-
instrumentKnex();
|
|
18
|
+
const instrumentation = instrumentKnex();
|
|
19
|
+
instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);
|
|
17
20
|
},
|
|
18
21
|
|
|
19
22
|
setup(client) {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
instrumentationWrappedCallback?.(() =>
|
|
24
|
+
client.on('spanStart', span => {
|
|
25
|
+
const { data } = spanToJSON(span);
|
|
26
|
+
// knex.version is always set in the span data
|
|
27
|
+
// https://github.com/open-telemetry/opentelemetry-js-contrib/blob/0309caeafc44ac9cb13a3345b790b01b76d0497d/plugins/node/opentelemetry-instrumentation-knex/src/instrumentation.ts#L138
|
|
28
|
+
if ('knex.version' in data) {
|
|
29
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.knex');
|
|
30
|
+
}
|
|
31
|
+
}),
|
|
32
|
+
);
|
|
28
33
|
},
|
|
29
34
|
};
|
|
30
35
|
}) ;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knex.js","sources":["../../../../src/integrations/tracing/knex.ts"],"sourcesContent":["import { KnexInstrumentation } from '@opentelemetry/instrumentation-knex';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/core';\nimport { generateInstrumentOnce } from '../../otel/instrument';\n\nconst INTEGRATION_NAME = 'Knex';\n\nexport const instrumentKnex = generateInstrumentOnce(\n INTEGRATION_NAME,\n () => new KnexInstrumentation({ requireParentSpan: true }),\n);\n\nconst _knexIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentKnex();\n },\n\n setup(client) {\n client.on('spanStart', span => {\n
|
|
1
|
+
{"version":3,"file":"knex.js","sources":["../../../../src/integrations/tracing/knex.ts"],"sourcesContent":["import { KnexInstrumentation } from '@opentelemetry/instrumentation-knex';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/core';\nimport { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument';\n\nconst INTEGRATION_NAME = 'Knex';\n\nexport const instrumentKnex = generateInstrumentOnce(\n INTEGRATION_NAME,\n () => new KnexInstrumentation({ requireParentSpan: true }),\n);\n\nconst _knexIntegration = (() => {\n let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n const instrumentation = instrumentKnex();\n instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);\n },\n\n setup(client) {\n instrumentationWrappedCallback?.(() =>\n client.on('spanStart', span => {\n const { data } = spanToJSON(span);\n // knex.version is always set in the span data\n // https://github.com/open-telemetry/opentelemetry-js-contrib/blob/0309caeafc44ac9cb13a3345b790b01b76d0497d/plugins/node/opentelemetry-instrumentation-knex/src/instrumentation.ts#L138\n if ('knex.version' in data) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.knex');\n }\n }),\n );\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Knex integration\n *\n * Capture tracing data for [Knex](https://knexjs.org/).\n *\n * @example\n * ```javascript\n * import * as Sentry from '@sentry/node';\n *\n * Sentry.init({\n * integrations: [Sentry.knexIntegration()],\n * });\n * ```\n */\nexport const knexIntegration = defineIntegration(_knexIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,gBAAA,GAAmB,MAAM;;AAExB,MAAM,cAAe,GAAE,sBAAsB;AACpD,EAAE,gBAAgB;AAClB,EAAE,MAAM,IAAI,mBAAmB,CAAC,EAAE,iBAAiB,EAAE,IAAK,EAAC,CAAC;AAC5D;;AAEA,MAAM,gBAAiB,IAAG,MAAM;AAChC,EAAE,IAAI,8BAA8B;;AAEpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,MAAM,eAAA,GAAkB,cAAc,EAAE;AAC9C,MAAM,8BAA+B,GAAE,qBAAqB,CAAC,eAAe,CAAC;AAC7E,KAAK;;AAEL,IAAI,KAAK,CAAC,MAAM,EAAE;AAClB,MAAM,8BAA8B,GAAG;AACvC,QAAQ,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ;AACvC,UAAU,MAAM,EAAE,IAAK,EAAA,GAAI,UAAU,CAAC,IAAI,CAAC;AAC3C;AACA;AACA,UAAU,IAAI,cAAe,IAAG,IAAI,EAAE;AACtC,YAAY,IAAI,CAAC,YAAY,CAAC,gCAAgC,EAAE,mBAAmB,CAAC;AACpF;AACA,SAAS,CAAC;AACV,OAAO;AACP,KAAK;AACL,GAAG;AACH,CAAC,CAAE;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,eAAgB,GAAE,iBAAiB,CAAC,gBAAgB;;;;"}
|
|
@@ -13,6 +13,18 @@ function isPrismaV6TracingHelper(helper) {
|
|
|
13
13
|
return !!helper && typeof helper === 'object' && 'dispatchEngineSpans' in helper;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
function getPrismaTracingHelper() {
|
|
17
|
+
const prismaInstrumentationObject = (globalThis ).PRISMA_INSTRUMENTATION;
|
|
18
|
+
const prismaTracingHelper =
|
|
19
|
+
prismaInstrumentationObject &&
|
|
20
|
+
typeof prismaInstrumentationObject === 'object' &&
|
|
21
|
+
'helper' in prismaInstrumentationObject
|
|
22
|
+
? prismaInstrumentationObject.helper
|
|
23
|
+
: undefined;
|
|
24
|
+
|
|
25
|
+
return prismaTracingHelper;
|
|
26
|
+
}
|
|
27
|
+
|
|
16
28
|
class SentryPrismaInteropInstrumentation extends EsmInteropPrismaInstrumentation {
|
|
17
29
|
constructor() {
|
|
18
30
|
super();
|
|
@@ -24,13 +36,7 @@ class SentryPrismaInteropInstrumentation extends EsmInteropPrismaInstrumentation
|
|
|
24
36
|
// The PrismaIntegration (super class) defines a global variable `global["PRISMA_INSTRUMENTATION"]` when `enable()` is called. This global variable holds a "TracingHelper" which Prisma uses internally to create tracing data. It's their way of not depending on OTEL with their main package. The sucky thing is, prisma broke the interface of the tracing helper with the v6 major update. This means that if you use Prisma 5 with the v6 instrumentation (or vice versa) Prisma just blows up, because tries to call methods on the helper that no longer exist.
|
|
25
37
|
// Because we actually want to use the v6 instrumentation and not blow up in Prisma 5 user's faces, what we're doing here is backfilling the v5 method (`createEngineSpan`) with a noop so that no longer crashes when it attempts to call that function.
|
|
26
38
|
// We still won't fully emit all the spans, but this could potentially be implemented in the future.
|
|
27
|
-
const
|
|
28
|
-
const prismaTracingHelper =
|
|
29
|
-
prismaInstrumentationObject &&
|
|
30
|
-
typeof prismaInstrumentationObject === 'object' &&
|
|
31
|
-
'helper' in prismaInstrumentationObject
|
|
32
|
-
? prismaInstrumentationObject.helper
|
|
33
|
-
: undefined;
|
|
39
|
+
const prismaTracingHelper = getPrismaTracingHelper();
|
|
34
40
|
|
|
35
41
|
let emittedWarning = false;
|
|
36
42
|
|
|
@@ -106,6 +112,12 @@ const prismaIntegration = defineIntegration(
|
|
|
106
112
|
instrumentPrisma({ prismaInstrumentation });
|
|
107
113
|
},
|
|
108
114
|
setup(client) {
|
|
115
|
+
// If no tracing helper exists, we skip any work here
|
|
116
|
+
// this means that prisma is not being used
|
|
117
|
+
if (!getPrismaTracingHelper()) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
109
121
|
client.on('spanStart', span => {
|
|
110
122
|
const spanJSON = spanToJSON(span);
|
|
111
123
|
if (spanJSON.description?.startsWith('prisma:')) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prisma.js","sources":["../../../../src/integrations/tracing/prisma.ts"],"sourcesContent":["import type { Instrumentation } from '@opentelemetry/instrumentation';\n// When importing CJS modules into an ESM module, we cannot import the named exports directly.\nimport * as prismaInstrumentation from '@prisma/instrumentation';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, consoleSandbox, defineIntegration, spanToJSON } from '@sentry/core';\nimport { generateInstrumentOnce } from '../../otel/instrument';\nimport type { PrismaV5TracingHelper } from './prisma/vendor/v5-tracing-helper';\nimport type { PrismaV6TracingHelper } from './prisma/vendor/v6-tracing-helper';\n\nconst INTEGRATION_NAME = 'Prisma';\n\nconst EsmInteropPrismaInstrumentation: typeof prismaInstrumentation.PrismaInstrumentation =\n // @ts-expect-error We need to do the following for interop reasons\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n prismaInstrumentation.default?.PrismaInstrumentation || prismaInstrumentation.PrismaInstrumentation;\n\ntype CompatibilityLayerTraceHelper = PrismaV5TracingHelper & PrismaV6TracingHelper;\n\nfunction isPrismaV6TracingHelper(helper: unknown): helper is PrismaV6TracingHelper {\n return !!helper && typeof helper === 'object' && 'dispatchEngineSpans' in helper;\n}\n\nclass SentryPrismaInteropInstrumentation extends EsmInteropPrismaInstrumentation {\n public constructor() {\n super();\n }\n\n public enable(): void {\n super.enable();\n\n // The PrismaIntegration (super class) defines a global variable `global[\"PRISMA_INSTRUMENTATION\"]` when `enable()` is called. This global variable holds a \"TracingHelper\" which Prisma uses internally to create tracing data. It's their way of not depending on OTEL with their main package. The sucky thing is, prisma broke the interface of the tracing helper with the v6 major update. This means that if you use Prisma 5 with the v6 instrumentation (or vice versa) Prisma just blows up, because tries to call methods on the helper that no longer exist.\n // Because we actually want to use the v6 instrumentation and not blow up in Prisma 5 user's faces, what we're doing here is backfilling the v5 method (`createEngineSpan`) with a noop so that no longer crashes when it attempts to call that function.\n // We still won't fully emit all the spans, but this could potentially be implemented in the future.\n const
|
|
1
|
+
{"version":3,"file":"prisma.js","sources":["../../../../src/integrations/tracing/prisma.ts"],"sourcesContent":["import type { Instrumentation } from '@opentelemetry/instrumentation';\n// When importing CJS modules into an ESM module, we cannot import the named exports directly.\nimport * as prismaInstrumentation from '@prisma/instrumentation';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, consoleSandbox, defineIntegration, spanToJSON } from '@sentry/core';\nimport { generateInstrumentOnce } from '../../otel/instrument';\nimport type { PrismaV5TracingHelper } from './prisma/vendor/v5-tracing-helper';\nimport type { PrismaV6TracingHelper } from './prisma/vendor/v6-tracing-helper';\n\nconst INTEGRATION_NAME = 'Prisma';\n\nconst EsmInteropPrismaInstrumentation: typeof prismaInstrumentation.PrismaInstrumentation =\n // @ts-expect-error We need to do the following for interop reasons\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n prismaInstrumentation.default?.PrismaInstrumentation || prismaInstrumentation.PrismaInstrumentation;\n\ntype CompatibilityLayerTraceHelper = PrismaV5TracingHelper & PrismaV6TracingHelper;\n\nfunction isPrismaV6TracingHelper(helper: unknown): helper is PrismaV6TracingHelper {\n return !!helper && typeof helper === 'object' && 'dispatchEngineSpans' in helper;\n}\n\nfunction getPrismaTracingHelper(): unknown | undefined {\n const prismaInstrumentationObject = (globalThis as Record<string, unknown>).PRISMA_INSTRUMENTATION;\n const prismaTracingHelper =\n prismaInstrumentationObject &&\n typeof prismaInstrumentationObject === 'object' &&\n 'helper' in prismaInstrumentationObject\n ? prismaInstrumentationObject.helper\n : undefined;\n\n return prismaTracingHelper;\n}\n\nclass SentryPrismaInteropInstrumentation extends EsmInteropPrismaInstrumentation {\n public constructor() {\n super();\n }\n\n public enable(): void {\n super.enable();\n\n // The PrismaIntegration (super class) defines a global variable `global[\"PRISMA_INSTRUMENTATION\"]` when `enable()` is called. This global variable holds a \"TracingHelper\" which Prisma uses internally to create tracing data. It's their way of not depending on OTEL with their main package. The sucky thing is, prisma broke the interface of the tracing helper with the v6 major update. This means that if you use Prisma 5 with the v6 instrumentation (or vice versa) Prisma just blows up, because tries to call methods on the helper that no longer exist.\n // Because we actually want to use the v6 instrumentation and not blow up in Prisma 5 user's faces, what we're doing here is backfilling the v5 method (`createEngineSpan`) with a noop so that no longer crashes when it attempts to call that function.\n // We still won't fully emit all the spans, but this could potentially be implemented in the future.\n const prismaTracingHelper = getPrismaTracingHelper();\n\n let emittedWarning = false;\n\n if (isPrismaV6TracingHelper(prismaTracingHelper)) {\n (prismaTracingHelper as CompatibilityLayerTraceHelper).createEngineSpan = () => {\n consoleSandbox(() => {\n if (!emittedWarning) {\n emittedWarning = true;\n // eslint-disable-next-line no-console\n console.warn(\n '[Sentry] The Sentry SDK supports tracing with Prisma version 5 only with limited capabilities. For full tracing capabilities pass `prismaInstrumentation` for version 5 to the Sentry `prismaIntegration`. Read more: https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/prisma/',\n );\n }\n });\n };\n }\n }\n}\n\nexport const instrumentPrisma = generateInstrumentOnce<{ prismaInstrumentation?: Instrumentation }>(\n INTEGRATION_NAME,\n options => {\n // Use a passed instrumentation instance to support older Prisma versions\n if (options?.prismaInstrumentation) {\n return options.prismaInstrumentation;\n }\n\n return new SentryPrismaInteropInstrumentation();\n },\n);\n\n/**\n * Adds Sentry tracing instrumentation for the [prisma](https://www.npmjs.com/package/prisma) library.\n * For more information, see the [`prismaIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/prisma/).\n *\n * NOTE: By default, this integration works with Prisma version 6.\n * To get performance instrumentation for other Prisma versions,\n * 1. Install the `@prisma/instrumentation` package with the desired version.\n * 1. Pass a `new PrismaInstrumentation()` instance as exported from `@prisma/instrumentation` to the `prismaInstrumentation` option of this integration:\n *\n * ```js\n * import { PrismaInstrumentation } from '@prisma/instrumentation'\n *\n * Sentry.init({\n * integrations: [\n * prismaIntegration({\n * // Override the default instrumentation that Sentry uses\n * prismaInstrumentation: new PrismaInstrumentation()\n * })\n * ]\n * })\n * ```\n *\n * The passed instrumentation instance will override the default instrumentation instance the integration would use, while the `prismaIntegration` will still ensure data compatibility for the various Prisma versions.\n * 1. Depending on your Prisma version (prior to version 6), add `previewFeatures = [\"tracing\"]` to the client generator block of your Prisma schema:\n *\n * ```\n * generator client {\n * provider = \"prisma-client-js\"\n * previewFeatures = [\"tracing\"]\n * }\n * ```\n */\nexport const prismaIntegration = defineIntegration(\n ({\n prismaInstrumentation,\n }: {\n /**\n * Overrides the instrumentation used by the Sentry SDK with the passed in instrumentation instance.\n *\n * NOTE: By default, the Sentry SDK uses the Prisma v6 instrumentation. Use this option if you need performance instrumentation different Prisma versions.\n *\n * For more information refer to the documentation of `prismaIntegration()` or see https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/prisma/\n */\n prismaInstrumentation?: Instrumentation;\n } = {}) => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentPrisma({ prismaInstrumentation });\n },\n setup(client) {\n // If no tracing helper exists, we skip any work here\n // this means that prisma is not being used\n if (!getPrismaTracingHelper()) {\n return;\n }\n\n client.on('spanStart', span => {\n const spanJSON = spanToJSON(span);\n if (spanJSON.description?.startsWith('prisma:')) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.prisma');\n }\n\n // Make sure we use the query text as the span name, for ex. SELECT * FROM \"User\" WHERE \"id\" = $1\n if (spanJSON.description === 'prisma:engine:db_query' && spanJSON.data['db.query.text']) {\n span.updateName(spanJSON.data['db.query.text'] as string);\n }\n\n // In Prisma v5.22+, the `db.system` attribute is automatically set\n // On older versions, this is missing, so we add it here\n if (spanJSON.description === 'prisma:engine:db_query' && !spanJSON.data['db.system']) {\n span.setAttribute('db.system', 'prisma');\n }\n });\n },\n };\n },\n);\n"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { TediousInstrumentation } from '@opentelemetry/instrumentation-tedious';
|
|
2
2
|
import { defineIntegration, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/core';
|
|
3
|
-
import { generateInstrumentOnce } from '../../otel/instrument.js';
|
|
3
|
+
import { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument.js';
|
|
4
4
|
|
|
5
5
|
const TEDIUS_INSTRUMENTED_METHODS = new Set([
|
|
6
6
|
'callProcedure',
|
|
@@ -16,25 +16,30 @@ const INTEGRATION_NAME = 'Tedious';
|
|
|
16
16
|
const instrumentTedious = generateInstrumentOnce(INTEGRATION_NAME, () => new TediousInstrumentation({}));
|
|
17
17
|
|
|
18
18
|
const _tediousIntegration = (() => {
|
|
19
|
+
let instrumentationWrappedCallback;
|
|
20
|
+
|
|
19
21
|
return {
|
|
20
22
|
name: INTEGRATION_NAME,
|
|
21
23
|
setupOnce() {
|
|
22
|
-
instrumentTedious();
|
|
24
|
+
const instrumentation = instrumentTedious();
|
|
25
|
+
instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);
|
|
23
26
|
},
|
|
24
27
|
|
|
25
28
|
setup(client) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
instrumentationWrappedCallback?.(() =>
|
|
30
|
+
client.on('spanStart', span => {
|
|
31
|
+
const { description, data } = spanToJSON(span);
|
|
32
|
+
// Tedius integration always set a span name and `db.system` attribute to `mssql`.
|
|
33
|
+
if (!description || data['db.system'] !== 'mssql') {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const operation = description.split(' ')[0] || '';
|
|
38
|
+
if (TEDIUS_INSTRUMENTED_METHODS.has(operation)) {
|
|
39
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.tedious');
|
|
40
|
+
}
|
|
41
|
+
}),
|
|
42
|
+
);
|
|
38
43
|
},
|
|
39
44
|
};
|
|
40
45
|
}) ;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tedious.js","sources":["../../../../src/integrations/tracing/tedious.ts"],"sourcesContent":["import { TediousInstrumentation } from '@opentelemetry/instrumentation-tedious';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/core';\nimport { generateInstrumentOnce } from '../../otel/instrument';\n\nconst TEDIUS_INSTRUMENTED_METHODS = new Set([\n 'callProcedure',\n 'execSql',\n 'execSqlBatch',\n 'execBulkLoad',\n 'prepare',\n 'execute',\n]);\n\nconst INTEGRATION_NAME = 'Tedious';\n\nexport const instrumentTedious = generateInstrumentOnce(INTEGRATION_NAME, () => new TediousInstrumentation({}));\n\nconst _tediousIntegration = (() => {\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n instrumentTedious();\n },\n\n setup(client) {\n client.on('spanStart', span => {\n
|
|
1
|
+
{"version":3,"file":"tedious.js","sources":["../../../../src/integrations/tracing/tedious.ts"],"sourcesContent":["import { TediousInstrumentation } from '@opentelemetry/instrumentation-tedious';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration, spanToJSON } from '@sentry/core';\nimport type { IntegrationFn } from '@sentry/core';\nimport { generateInstrumentOnce, instrumentWhenWrapped } from '../../otel/instrument';\n\nconst TEDIUS_INSTRUMENTED_METHODS = new Set([\n 'callProcedure',\n 'execSql',\n 'execSqlBatch',\n 'execBulkLoad',\n 'prepare',\n 'execute',\n]);\n\nconst INTEGRATION_NAME = 'Tedious';\n\nexport const instrumentTedious = generateInstrumentOnce(INTEGRATION_NAME, () => new TediousInstrumentation({}));\n\nconst _tediousIntegration = (() => {\n let instrumentationWrappedCallback: undefined | ((callback: () => void) => void);\n\n return {\n name: INTEGRATION_NAME,\n setupOnce() {\n const instrumentation = instrumentTedious();\n instrumentationWrappedCallback = instrumentWhenWrapped(instrumentation);\n },\n\n setup(client) {\n instrumentationWrappedCallback?.(() =>\n client.on('spanStart', span => {\n const { description, data } = spanToJSON(span);\n // Tedius integration always set a span name and `db.system` attribute to `mssql`.\n if (!description || data['db.system'] !== 'mssql') {\n return;\n }\n\n const operation = description.split(' ')[0] || '';\n if (TEDIUS_INSTRUMENTED_METHODS.has(operation)) {\n span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, 'auto.db.otel.tedious');\n }\n }),\n );\n },\n };\n}) satisfies IntegrationFn;\n\n/**\n * Adds Sentry tracing instrumentation for the [tedious](https://www.npmjs.com/package/tedious) library.\n *\n * For more information, see the [`tediousIntegration` documentation](https://docs.sentry.io/platforms/javascript/guides/node/configuration/integrations/tedious/).\n *\n * @example\n * ```javascript\n * const Sentry = require('@sentry/node');\n *\n * Sentry.init({\n * integrations: [Sentry.tediousIntegration()],\n * });\n * ```\n */\nexport const tediousIntegration = defineIntegration(_tediousIntegration);\n"],"names":[],"mappings":";;;;AAKA,MAAM,2BAA4B,GAAE,IAAI,GAAG,CAAC;AAC5C,EAAE,eAAe;AACjB,EAAE,SAAS;AACX,EAAE,cAAc;AAChB,EAAE,cAAc;AAChB,EAAE,SAAS;AACX,EAAE,SAAS;AACX,CAAC,CAAC;;AAEF,MAAM,gBAAA,GAAmB,SAAS;;MAErB,iBAAkB,GAAE,sBAAsB,CAAC,gBAAgB,EAAE,MAAM,IAAI,sBAAsB,CAAC,EAAE,CAAC;;AAE9G,MAAM,mBAAoB,IAAG,MAAM;AACnC,EAAE,IAAI,8BAA8B;;AAEpC,EAAE,OAAO;AACT,IAAI,IAAI,EAAE,gBAAgB;AAC1B,IAAI,SAAS,GAAG;AAChB,MAAM,MAAM,eAAA,GAAkB,iBAAiB,EAAE;AACjD,MAAM,8BAA+B,GAAE,qBAAqB,CAAC,eAAe,CAAC;AAC7E,KAAK;;AAEL,IAAI,KAAK,CAAC,MAAM,EAAE;AAClB,MAAM,8BAA8B,GAAG;AACvC,QAAQ,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ;AACvC,UAAU,MAAM,EAAE,WAAW,EAAE,IAAA,KAAS,UAAU,CAAC,IAAI,CAAC;AACxD;AACA,UAAU,IAAI,CAAC,WAAY,IAAG,IAAI,CAAC,WAAW,CAAA,KAAM,OAAO,EAAE;AAC7D,YAAY;AACZ;;AAEA,UAAU,MAAM,SAAA,GAAY,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA,IAAK,EAAE;AAC3D,UAAU,IAAI,2BAA2B,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;AAC1D,YAAY,IAAI,CAAC,YAAY,CAAC,gCAAgC,EAAE,sBAAsB,CAAC;AACvF;AACA,SAAS,CAAC;AACV,OAAO;AACP,KAAK;AACL,GAAG;AACH,CAAC,CAAE;;AAEH;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;MACa,kBAAmB,GAAE,iBAAiB,CAAC,mBAAmB;;;;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { defineIntegration, spanToJSON, SEMANTIC_ATTRIBUTE_SENTRY_OP } from '@sentry/core';
|
|
2
2
|
import { generateInstrumentOnce } from '../../../otel/instrument.js';
|
|
3
3
|
import { addOriginToSpan } from '../../../utils/addOriginToSpan.js';
|
|
4
|
-
import { SentryVercelAiInstrumentation
|
|
4
|
+
import { SentryVercelAiInstrumentation } from './instrumentation.js';
|
|
5
5
|
|
|
6
6
|
/* eslint-disable complexity */
|
|
7
7
|
|
|
@@ -10,145 +10,146 @@ const INTEGRATION_NAME = 'VercelAI';
|
|
|
10
10
|
const instrumentVercelAi = generateInstrumentOnce(INTEGRATION_NAME, () => new SentryVercelAiInstrumentation({}));
|
|
11
11
|
|
|
12
12
|
const _vercelAIIntegration = (() => {
|
|
13
|
+
let instrumentation;
|
|
14
|
+
|
|
13
15
|
return {
|
|
14
16
|
name: INTEGRATION_NAME,
|
|
15
17
|
setupOnce() {
|
|
16
|
-
instrumentVercelAi();
|
|
17
|
-
},
|
|
18
|
-
processEvent(event) {
|
|
19
|
-
if (event.type === 'transaction' && event.spans?.length) {
|
|
20
|
-
for (const span of event.spans) {
|
|
21
|
-
const { data: attributes, description: name } = span;
|
|
22
|
-
|
|
23
|
-
if (!name || span.origin !== 'auto.vercelai.otel') {
|
|
24
|
-
continue;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (attributes['ai.usage.completionTokens'] != undefined) {
|
|
28
|
-
attributes['ai.completion_tokens.used'] = attributes['ai.usage.completionTokens'];
|
|
29
|
-
}
|
|
30
|
-
if (attributes['ai.usage.promptTokens'] != undefined) {
|
|
31
|
-
attributes['ai.prompt_tokens.used'] = attributes['ai.usage.promptTokens'];
|
|
32
|
-
}
|
|
33
|
-
if (
|
|
34
|
-
typeof attributes['ai.usage.completionTokens'] == 'number' &&
|
|
35
|
-
typeof attributes['ai.usage.promptTokens'] == 'number'
|
|
36
|
-
) {
|
|
37
|
-
attributes['ai.total_tokens.used'] =
|
|
38
|
-
attributes['ai.usage.completionTokens'] + attributes['ai.usage.promptTokens'];
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return event;
|
|
18
|
+
instrumentation = instrumentVercelAi();
|
|
44
19
|
},
|
|
45
20
|
setup(client) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
21
|
+
instrumentation?.callWhenPatched(() => {
|
|
22
|
+
client.on('spanStart', span => {
|
|
23
|
+
const { data: attributes, description: name } = spanToJSON(span);
|
|
24
|
+
|
|
25
|
+
if (!name) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// The id of the model
|
|
30
|
+
const aiModelId = attributes['ai.model.id'];
|
|
31
|
+
|
|
32
|
+
// the provider of the model
|
|
33
|
+
const aiModelProvider = attributes['ai.model.provider'];
|
|
34
|
+
|
|
35
|
+
// both of these must be defined for the integration to work
|
|
36
|
+
if (typeof aiModelId !== 'string' || typeof aiModelProvider !== 'string' || !aiModelId || !aiModelProvider) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let isPipelineSpan = false;
|
|
41
|
+
|
|
42
|
+
switch (name) {
|
|
43
|
+
case 'ai.generateText': {
|
|
44
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.pipeline.generateText');
|
|
45
|
+
isPipelineSpan = true;
|
|
46
|
+
break;
|
|
47
|
+
}
|
|
48
|
+
case 'ai.generateText.doGenerate': {
|
|
49
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.run.doGenerate');
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
case 'ai.streamText': {
|
|
53
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.pipeline.streamText');
|
|
54
|
+
isPipelineSpan = true;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
case 'ai.streamText.doStream': {
|
|
58
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.run.doStream');
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
case 'ai.generateObject': {
|
|
62
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.pipeline.generateObject');
|
|
63
|
+
isPipelineSpan = true;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
case 'ai.generateObject.doGenerate': {
|
|
67
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.run.doGenerate');
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
case 'ai.streamObject': {
|
|
71
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.pipeline.streamObject');
|
|
72
|
+
isPipelineSpan = true;
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
case 'ai.streamObject.doStream': {
|
|
76
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.run.doStream');
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case 'ai.embed': {
|
|
80
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.pipeline.embed');
|
|
81
|
+
isPipelineSpan = true;
|
|
82
|
+
break;
|
|
83
|
+
}
|
|
84
|
+
case 'ai.embed.doEmbed': {
|
|
85
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.embeddings');
|
|
86
|
+
break;
|
|
87
|
+
}
|
|
88
|
+
case 'ai.embedMany': {
|
|
89
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.pipeline.embedMany');
|
|
90
|
+
isPipelineSpan = true;
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
case 'ai.embedMany.doEmbed': {
|
|
94
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.embeddings');
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
case 'ai.toolCall':
|
|
98
|
+
case 'ai.stream.firstChunk':
|
|
99
|
+
case 'ai.stream.finish':
|
|
100
|
+
span.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_OP, 'ai.run');
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
addOriginToSpan(span, 'auto.vercelai.otel');
|
|
105
|
+
|
|
106
|
+
const nameWthoutAi = name.replace('ai.', '');
|
|
107
|
+
span.setAttribute('ai.pipeline.name', nameWthoutAi);
|
|
108
|
+
span.updateName(nameWthoutAi);
|
|
109
|
+
|
|
110
|
+
// If a Telemetry name is set and it is a pipeline span, use that as the operation name
|
|
111
|
+
const functionId = attributes['ai.telemetry.functionId'];
|
|
112
|
+
if (functionId && typeof functionId === 'string' && isPipelineSpan) {
|
|
113
|
+
span.updateName(functionId);
|
|
114
|
+
span.setAttribute('ai.pipeline.name', functionId);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (attributes['ai.prompt']) {
|
|
118
|
+
span.setAttribute('ai.input_messages', attributes['ai.prompt']);
|
|
119
|
+
}
|
|
120
|
+
if (attributes['ai.model.id']) {
|
|
121
|
+
span.setAttribute('ai.model_id', attributes['ai.model.id']);
|
|
122
|
+
}
|
|
123
|
+
span.setAttribute('ai.streaming', name.includes('stream'));
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
client.addEventProcessor(event => {
|
|
127
|
+
if (event.type === 'transaction' && event.spans?.length) {
|
|
128
|
+
for (const span of event.spans) {
|
|
129
|
+
const { data: attributes, description: name } = span;
|
|
130
|
+
|
|
131
|
+
if (!name || span.origin !== 'auto.vercelai.otel') {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (attributes['ai.usage.completionTokens'] != undefined) {
|
|
136
|
+
attributes['ai.completion_tokens.used'] = attributes['ai.usage.completionTokens'];
|
|
137
|
+
}
|
|
138
|
+
if (attributes['ai.usage.promptTokens'] != undefined) {
|
|
139
|
+
attributes['ai.prompt_tokens.used'] = attributes['ai.usage.promptTokens'];
|
|
140
|
+
}
|
|
141
|
+
if (
|
|
142
|
+
typeof attributes['ai.usage.completionTokens'] == 'number' &&
|
|
143
|
+
typeof attributes['ai.usage.promptTokens'] == 'number'
|
|
144
|
+
) {
|
|
145
|
+
attributes['ai.total_tokens.used'] =
|
|
146
|
+
attributes['ai.usage.completionTokens'] + attributes['ai.usage.promptTokens'];
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
return event;
|
|
152
|
+
});
|
|
152
153
|
});
|
|
153
154
|
},
|
|
154
155
|
};
|