Skip to content

Commit a858a07

Browse files
mydeaLms24
andauthored
feat(node-experimental): Add @sentry/node-experimental package as MVP for POTEL (#8609)
This introduces a new package `@sentry/node-experimental`, which is an MVP implementation for Performance powered by OTEL (POTEL). This package provides a wrapper over `@sentry/node` (also using `@sentry/opentelemetry-node`) which uses opentelemetry for performance instrumentation under the hood. This is all abstracted away from the user, they only need to do: ```js import * as Sentry from '@sentry/node-experimental'; Sentry.init({ dsn: 'my-dsn', tracesSampleRate: 0.1 }); ``` And it will set up all the necessary integrations etc. for the user, including the default integrations + any applying performance integrations. For this, I added all performance integrations that exist for node, minus undici (which will take some more work to get going), plus some new stuff: mysql, fastify, nest. Also, mongoose is it's own integration now, not handled via mongo anymore. Note that I've only manually tested express & http so far. All others still need to be verified etc. But this is really a POC, which may go somewhere or not - by publishing this, it becomes super easy to try this in various scenarios. I have tweaked the Http integration to create more or less the same output as we're used to for Sentry. I also made small tweaks to `@sentry/opentelemetry-node` to allow us to communicate with this a bit better. There are two main use cases I've identified there: * Tell the span processor to drop a span (=not send it to Sentry). For this, I added dedicated hooks. * Add some specific data/context/tags/metadata to an otel span, that should be added to the resulting sentry span. For this, I added utils which keep a map of data to be added in `spanEnd`. --------- Co-authored-by: Lukas Stracke <[email protected]>
1 parent 540adac commit a858a07

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1729
-107
lines changed

.craft.yml

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,102 +6,107 @@ targets:
66
## 1. Base Packages, node or browser SDKs depend on
77
## 1.1 Types
88
- name: npm
9-
id: "@sentry/types"
9+
id: '@sentry/types'
1010
includeNames: /^sentry-types-\d.*\.tgz$/
1111
## 1.2 Utils
1212
- name: npm
13-
id: "@sentry/utils"
13+
id: '@sentry/utils'
1414
includeNames: /^sentry-utils-\d.*\.tgz$/
1515
## 1.3 Core SDK
1616
- name: npm
17-
id: "@sentry/core"
17+
id: '@sentry/core'
1818
includeNames: /^sentry-core-\d.*\.tgz$/
1919
## 1.4 Tracing package
2020
- name: npm
21-
id: "@sentry-internal/tracing"
21+
id: '@sentry-internal/tracing'
2222
includeNames: /^sentry-internal-tracing-\d.*\.tgz$/
2323
## 1.5 Replay package (browser only)
2424
- name: npm
25-
id: "@sentry/replay"
25+
id: '@sentry/replay'
2626
includeNames: /^sentry-replay-\d.*\.tgz$/
2727

2828
## 2. Browser & Node SDKs
2929
- name: npm
30-
id: "@sentry/browser"
30+
id: '@sentry/browser'
3131
includeNames: /^sentry-browser-\d.*\.tgz$/
3232
- name: npm
33-
id: "@sentry/node"
33+
id: '@sentry/node'
3434
includeNames: /^sentry-node-\d.*\.tgz$/
3535

3636
## 3 Browser-based Packages
3737
- name: npm
38-
id: "@sentry/angular-ivy"
38+
id: '@sentry/angular-ivy'
3939
includeNames: /^sentry-angular-ivy-\d.*\.tgz$/
4040
- name: npm
41-
id: "@sentry/angular"
41+
id: '@sentry/angular'
4242
includeNames: /^sentry-angular-\d.*\.tgz$/
4343
- name: npm
44-
id: "@sentry/ember"
44+
id: '@sentry/ember'
4545
includeNames: /^sentry-ember-\d.*\.tgz$/
4646
- name: npm
47-
id: "@sentry/react"
47+
id: '@sentry/react'
4848
includeNames: /^sentry-react-\d.*\.tgz$/
4949
- name: npm
50-
id: "@sentry/svelte"
50+
id: '@sentry/svelte'
5151
includeNames: /^sentry-svelte-\d.*\.tgz$/
5252
- name: npm
53-
id: "@sentry/vue"
53+
id: '@sentry/vue'
5454
includeNames: /^sentry-vue-\d.*\.tgz$/
5555
- name: npm
56-
id: "@sentry/wasm"
56+
id: '@sentry/wasm'
5757
includeNames: /^sentry-wasm-\d.*\.tgz$/
5858
- name: npm
59-
id: "@sentry/integrations"
59+
id: '@sentry/integrations'
6060
includeNames: /^sentry-integrations-\d.*\.tgz$/
6161

6262
## 4. Node-based Packages
6363
- name: npm
64-
id: "@sentry/serverless"
64+
id: '@sentry/serverless'
6565
includeNames: /^sentry-serverless-\d.*\.tgz$/
6666
- name: npm
67-
id: "@sentry/opentelemetry-node"
67+
id: '@sentry/opentelemetry-node'
6868
includeNames: /^sentry-opentelemetry-node-\d.*\.tgz$/
6969

7070
## 5. Fullstack/Meta Frameworks (depending on Node and Browser or Framework SDKs)
7171
- name: npm
72-
id: "@sentry/nextjs"
72+
id: '@sentry/nextjs'
7373
includeNames: /^sentry-nextjs-\d.*\.tgz$/
7474
- name: npm
75-
id: "@sentry/remix"
75+
id: '@sentry/remix'
7676
includeNames: /^sentry-remix-\d.*\.tgz$/
7777
- name: npm
78-
id: "@sentry/sveltekit"
78+
id: '@sentry/sveltekit'
7979
includeNames: /^sentry-sveltekit-\d.*\.tgz$/
8080
- name: npm
81-
id: "@sentry/gatsby"
81+
id: '@sentry/gatsby'
8282
includeNames: /^sentry-gatsby-\d.*\.tgz$/
8383

8484
## 6. Other Packages
8585
## 6.1
8686
- name: npm
87-
id: "@sentry-internal/typescript"
87+
id: '@sentry-internal/typescript'
8888
includeNames: /^sentry-internal-typescript-\d.*\.tgz$/
8989
- name: npm
90-
id: "@sentry-internal/eslint-plugin-sdk"
90+
id: '@sentry-internal/eslint-plugin-sdk'
9191
includeNames: /^sentry-internal-eslint-plugin-sdk-\d.*\.tgz$/
9292
## 6.2
9393
- name: npm
94-
id: "@sentry-internal/eslint-config-sdk"
94+
id: '@sentry-internal/eslint-config-sdk'
9595
includeNames: /^sentry-internal-eslint-config-sdk-\d.*\.tgz$/
9696

9797
## 7. Deprecated packages we still release (but no packages depend on them anymore)
9898
- name: npm
99-
id: "@sentry/hub"
99+
id: '@sentry/hub'
100100
includeNames: /^sentry-hub-\d.*\.tgz$/
101101
- name: npm
102-
id: "@sentry/tracing"
102+
id: '@sentry/tracing'
103103
includeNames: /^sentry-tracing-\d.*\.tgz$/
104104

105+
## 8. Experimental packages
106+
- name: npm
107+
id: '@sentry/node-experimental'
108+
includeNames: /^sentry-node-experimental-\d.*\.tgz$/
109+
105110
# AWS Lambda Layer target
106111
- name: aws-lambda-layer
107112
includeNames: /^sentry-node-serverless-\d+.\d+.\d+(-(beta|alpha)\.\d+)?\.zip$/
@@ -118,7 +123,7 @@ targets:
118123

119124
# CDN Bundle Target
120125
- name: gcs
121-
id: "browser-cdn-bundles"
126+
id: 'browser-cdn-bundles'
122127
includeNames: /.*\.js.*$/
123128
bucket: sentry-js-sdk
124129
paths:

docs/new-sdk-release-checklist.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ When you’re ready to make the first release, there are a couple of steps that
6161
- [ ] 3) Add an `npm` target in `craft.yml` for the new package. Make sure to insert it in the right place, after all the Sentry dependencies of your package but before packages that depend on your new package (if applicable).
6262
```yml
6363
- name: npm
64-
id: npm:@sentry/[yourPackage]
64+
id: '@sentry/[yourPackage]'
6565
includeNames: /^sentry-[yourPackage]-\d.*\.tgz$/
6666
```
6767
- [ ] 4) Cut a new release (as usual, see [Publishing Release](https://github.com/getsentry/sentry-javascript/blob/develop/docs/publishing-a-release.md))

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"postpublish": "lerna run --stream --concurrency 1 postpublish",
2828
"test": "lerna run --ignore \"@sentry-internal/{browser-integration-tests,e2e-tests,integration-shims,node-integration-tests,overhead-metrics}\" test",
2929
"test:unit": "lerna run --ignore \"@sentry-internal/{browser-integration-tests,e2e-tests,integration-shims,node-integration-tests,overhead-metrics}\" test:unit",
30-
"test-ci-browser": "lerna run test --ignore \"@sentry/{node,opentelemetry-node,serverless,nextjs,remix,gatsby,sveltekit}\" --ignore \"@sentry-internal/{browser-integration-tests,e2e-tests,integration-shims,node-integration-tests,overhead-metrics}\"",
30+
"test-ci-browser": "lerna run test --ignore \"@sentry/{node,node-experimental,opentelemetry-node,serverless,nextjs,remix,gatsby,sveltekit}\" --ignore \"@sentry-internal/{browser-integration-tests,e2e-tests,integration-shims,node-integration-tests,overhead-metrics}\"",
3131
"test-ci-node": "ts-node ./scripts/node-unit-tests.ts",
3232
"test:update-snapshots": "lerna run test:update-snapshots",
3333
"yalc:publish": "lerna run yalc:publish"
@@ -54,6 +54,7 @@
5454
"packages/nextjs",
5555
"packages/node",
5656
"packages/node-integration-tests",
57+
"packages/node-experimental",
5758
"packages/opentelemetry-node",
5859
"packages/react",
5960
"packages/remix",

packages/core/src/baseclient.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,9 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
388388
/** @inheritdoc */
389389
public on(hook: 'createDsc', callback: (dsc: DynamicSamplingContext) => void): void;
390390

391+
/** @inheritdoc */
392+
public on(hook: 'otelSpanEnd', callback: (otelSpan: unknown, mutableOptions: { drop: boolean }) => void): void;
393+
391394
/** @inheritdoc */
392395
public on(hook: string, callback: unknown): void {
393396
if (!this._hooks[hook]) {
@@ -413,6 +416,9 @@ export abstract class BaseClient<O extends ClientOptions> implements Client<O> {
413416
/** @inheritdoc */
414417
public emit(hook: 'createDsc', dsc: DynamicSamplingContext): void;
415418

419+
/** @inheritdoc */
420+
public emit(hook: 'otelSpanEnd', otelSpan: unknown, mutableOptions: { drop: boolean }): void;
421+
416422
/** @inheritdoc */
417423
public emit(hook: string, ...rest: unknown[]): void {
418424
if (this._hooks[hook]) {

packages/e2e-tests/verdaccio-config/config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,12 @@ packages:
9292
unpublish: $all
9393
# proxy: npmjs # Don't proxy for E2E tests!
9494

95+
'@sentry/node-experimental':
96+
access: $all
97+
publish: $all
98+
unpublish: $all
99+
# proxy: npmjs # Don't proxy for E2E tests!
100+
95101
'@sentry/opentelemetry-node':
96102
access: $all
97103
publish: $all
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module.exports = {
2+
env: {
3+
node: true,
4+
},
5+
extends: ['../../.eslintrc.js'],
6+
rules: {
7+
'@sentry-internal/sdk/no-optional-chaining': 'off',
8+
},
9+
};

packages/node-experimental/LICENSE

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
Copyright (c) 2023 Sentry (https://sentry.io) and individual contributors. All rights reserved.
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
4+
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
5+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
6+
persons to whom the Software is furnished to do so, subject to the following conditions:
7+
8+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
9+
Software.
10+
11+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
12+
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
13+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
14+
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

packages/node-experimental/README.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<p align="center">
2+
<a href="https://sentry.io/?utm_source=github&utm_medium=logo" target="_blank">
3+
<img src="https://sentry-brand.storage.googleapis.com/sentry-wordmark-dark-280x84.png" alt="Sentry" width="280" height="84">
4+
</a>
5+
</p>
6+
7+
# Official Sentry SDK for Node (EXPERIMENTAL)
8+
9+
[![npm version](https://img.shields.io/npm/v/@sentry/node-experimental.svg)](https://www.npmjs.com/package/@sentry/node-experimental)
10+
[![npm dm](https://img.shields.io/npm/dm/@sentry/node-experimental.svg)](https://www.npmjs.com/package/@sentry/node-experimental)
11+
[![npm dt](https://img.shields.io/npm/dt/@sentry/node-experimental.svg)](https://www.npmjs.com/package/@sentry/node-experimental)
12+
13+
This is a WIP, proof of concept implementation of a Node SDK that uses OpenTelemetry for performance instrumentation under the hood.
14+
15+
THIS MAY/WILL BREAK IN MANY UNEXPECTED WAYS. We may remove, add, change any of the integrations, add/remove any exports, etc.
16+
This package is **NOT READY TO USE IN ANY FORM OF PRODUCTION ENVIRONMENT**!
17+
18+
This SDK is **considered experimental and in an alpha state**. It may experience breaking changes, and may be discontinued at any time. Please reach out on
19+
[GitHub](https://github.com/getsentry/sentry-javascript/issues/new/choose) if you have any feedback/concerns.
20+
21+
## Installation
22+
23+
```bash
24+
npm install @sentry/node-experimental
25+
26+
# Or yarn
27+
yarn add @sentry/node-experimental
28+
```
29+
30+
## Usage
31+
32+
```js
33+
// ES5 Syntax
34+
const Sentry = require('@sentry/node-experimental');
35+
// ES6 Syntax
36+
import * as Sentry from '@sentry/node-experimental';
37+
38+
Sentry.init({
39+
dsn: '__DSN__',
40+
// ...
41+
});
42+
```
43+
44+
Note that it is necessary to initialize Sentry **before you import any package that may be instrumented by us**.
45+
46+
## Available (Performance) Integrations
47+
48+
* Http
49+
* Express
50+
* Fastify
51+
* Nest
52+
* Mysql
53+
* Mysql2
54+
* GraphQL
55+
* Mongo
56+
* Mongoose
57+
* Postgres
58+
* Prisma
59+
60+
All of these are auto-discovered, you don't need to configure anything for performance.
61+
You still need to register middlewares etc. for error capturing.
62+
Other, non-performance integrations from `@sentry/node` are also available (except for Undici).
63+
64+
## Links
65+
66+
- [Official SDK Docs](https://docs.sentry.io/quickstart/)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('../../jest/jest.config.js');
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
{
2+
"name": "@sentry/node-experimental",
3+
"version": "7.60.0",
4+
"description": "Experimental version of a Node SDK using OpenTelemetry for performance instrumentation",
5+
"repository": "git://github.com/getsentry/sentry-javascript.git",
6+
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/node-experimental",
7+
"author": "Sentry",
8+
"license": "MIT",
9+
"engines": {
10+
"node": ">=14"
11+
},
12+
"main": "build/cjs/index.js",
13+
"module": "build/esm/index.js",
14+
"types": "build/types/index.d.ts",
15+
"typesVersions": {
16+
"<4.9": {
17+
"build/types/index.d.ts": [
18+
"build/types-ts3.8/index.d.ts"
19+
]
20+
}
21+
},
22+
"publishConfig": {
23+
"access": "public"
24+
},
25+
"dependencies": {
26+
"@opentelemetry/api": "~1.4.1",
27+
"@opentelemetry/instrumentation": "~0.41.0",
28+
"@opentelemetry/instrumentation-fastify": "~0.32.0",
29+
"@opentelemetry/instrumentation-http": "~0.41.0",
30+
"@opentelemetry/instrumentation-express": "~0.33.0",
31+
"@opentelemetry/instrumentation-graphql": "~0.35.0",
32+
"@opentelemetry/instrumentation-mongodb": "~0.36.0",
33+
"@opentelemetry/instrumentation-mongoose": "~0.33.0",
34+
"@opentelemetry/instrumentation-mysql": "~0.34.0",
35+
"@opentelemetry/instrumentation-mysql2": "~0.34.0",
36+
"@opentelemetry/instrumentation-pg": "~0.36.0",
37+
"@opentelemetry/instrumentation-nestjs-core": "~0.33.0",
38+
"@opentelemetry/semantic-conventions": "~1.15.0",
39+
"@opentelemetry/sdk-trace-node": "~1.15.0",
40+
"@prisma/instrumentation": "~5.0.0",
41+
"@sentry/core": "7.60.0",
42+
"@sentry/node": "7.60.0",
43+
"@sentry/opentelemetry-node": "7.60.0",
44+
"@sentry/types": "7.60.0",
45+
"@sentry/utils": "7.60.0"
46+
},
47+
"scripts": {
48+
"build": "run-p build:transpile build:types",
49+
"build:dev": "yarn build",
50+
"build:transpile": "rollup -c rollup.npm.config.js",
51+
"build:types": "run-s build:types:core build:types:downlevel",
52+
"build:types:core": "tsc -p tsconfig.types.json",
53+
"build:types:downlevel": "yarn downlevel-dts build/types build/types-ts3.8 --to ts3.8",
54+
"build:watch": "run-p build:transpile:watch build:types:watch",
55+
"build:dev:watch": "yarn build:watch",
56+
"build:transpile:watch": "rollup -c rollup.npm.config.js --watch",
57+
"build:types:watch": "tsc -p tsconfig.types.json --watch",
58+
"build:tarball": "ts-node ../../scripts/prepack.ts && npm pack ./build",
59+
"circularDepCheck": "madge --circular src/index.ts",
60+
"clean": "rimraf build coverage sentry-node-experimental-*.tgz",
61+
"fix": "run-s fix:eslint fix:prettier",
62+
"fix:eslint": "eslint . --format stylish --fix",
63+
"fix:prettier": "prettier --write \"{src,test,scripts}/**/**.ts\"",
64+
"lint": "run-s lint:prettier lint:eslint",
65+
"lint:eslint": "eslint . --format stylish",
66+
"lint:prettier": "prettier --check \"{src,test,scripts}/**/**.ts\"",
67+
"test": "yarn test:jest",
68+
"test:jest": "jest",
69+
"test:watch": "jest --watch",
70+
"yalc:publish": "ts-node ../../scripts/prepack.ts && yalc publish build --push"
71+
},
72+
"volta": {
73+
"extends": "../../package.json"
74+
},
75+
"sideEffects": false
76+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { makeBaseNPMConfig, makeNPMConfigVariants } from '../../rollup/index.js';
2+
3+
export default makeNPMConfigVariants(makeBaseNPMConfig());
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { Integrations as CoreIntegrations } from '@sentry/core';
2+
3+
import * as NodeExperimentalIntegrations from './integrations';
4+
5+
const INTEGRATIONS = {
6+
...CoreIntegrations,
7+
...NodeExperimentalIntegrations,
8+
};
9+
10+
export { init } from './sdk/init';
11+
export { INTEGRATIONS as Integrations };
12+
export { getAutoPerformanceIntegrations } from './integrations/getAutoPerformanceIntegrations';
13+
export * as Handlers from './sdk/handlers';

0 commit comments

Comments
 (0)