Skip to content

Commit 3d977bf

Browse files
author
Luca Forstner
committed
Merge remote-tracking branch 'origin/develop' into lforst-deprecate-aoti
2 parents 6cff022 + f93ccbe commit 3d977bf

File tree

16 files changed

+202
-87
lines changed

16 files changed

+202
-87
lines changed

docs/migration/draft-v9-migration-guide.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@
3535
- Deprecated `getNumberOfUrlSegments`. No replacements.
3636
- Deprecated `BAGGAGE_HEADER_NAME`. No replacements.
3737
- Deprecated `makeFifoCache`. No replacements.
38+
- Deprecated `dynamicRequire`. No replacements.
3839
- Deprecated `flatten`. No replacements.
40+
- Deprecated `_browserPerformanceTimeOriginMode`. No replacements.
3941

4042
## `@sentry/core`
4143

@@ -87,6 +89,18 @@
8789
});
8890
```
8991

92+
## `@sentry/astro`
93+
94+
- Deprecated passing `dsn`, `release`, `environment`, `sampleRate`, `tracesSampleRate`, `replaysSessionSampleRate` to the integration. Use the runtime-specific `Sentry.init()` calls for passing these options instead.
95+
96+
## `@sentry/remix`
97+
98+
- Deprecated `autoInstrumentRemix: false`. The next major version will default to behaving as if this option were `true` and the option itself will be removed.
99+
100+
## `@sentry/opentelemetry`
101+
102+
- Deprecated `generateSpanContextForPropagationContext` in favor of doing this manually - we do not need this export anymore.
103+
90104
## Server-side SDKs (`@sentry/node` and all dependents)
91105

92106
- Deprecated `processThreadBreadcrumbIntegration` in favor of `childProcessIntegration`. Functionally they are the same.

packages/astro/src/integration/snippets.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export function buildSdkInitFileImportSnippet(filePath: string): string {
1414
* default options.
1515
*/
1616
export function buildClientSnippet(options: SentryOptions): string {
17+
/* eslint-disable deprecation/deprecation */
1718
return `import * as Sentry from "@sentry/astro";
1819
1920
Sentry.init({
@@ -22,6 +23,7 @@ Sentry.init({
2223
replaysSessionSampleRate: ${options.replaysSessionSampleRate ?? 0.1},
2324
replaysOnErrorSampleRate: ${options.replaysOnErrorSampleRate ?? 1.0},
2425
});`;
26+
/* eslint-enable deprecation/deprecation */
2527
}
2628

2729
/**
@@ -36,6 +38,7 @@ Sentry.init({
3638
});`;
3739
}
3840

41+
/* eslint-disable deprecation/deprecation */
3942
const buildCommonInitOptions = (options: SentryOptions): string => `dsn: ${
4043
options.dsn ? JSON.stringify(options.dsn) : 'import.meta.env.PUBLIC_SENTRY_DSN'
4144
},
@@ -45,6 +48,7 @@ const buildCommonInitOptions = (options: SentryOptions): string => `dsn: ${
4548
tracesSampleRate: ${options.tracesSampleRate ?? 1.0},${
4649
options.sampleRate ? `\n sampleRate: ${options.sampleRate},` : ''
4750
}`;
51+
/* eslint-enable deprecation/deprecation */
4852

4953
/**
5054
* We don't include the `BrowserTracing` integration if `bundleSizeOptimizations.excludeTracing` is falsy.
@@ -61,9 +65,13 @@ const buildClientIntegrations = (options: SentryOptions): string => {
6165
}
6266

6367
if (
68+
// eslint-disable-next-line deprecation/deprecation
6469
options.replaysSessionSampleRate == null ||
70+
// eslint-disable-next-line deprecation/deprecation
6571
options.replaysSessionSampleRate ||
72+
// eslint-disable-next-line deprecation/deprecation
6673
options.replaysOnErrorSampleRate == null ||
74+
// eslint-disable-next-line deprecation/deprecation
6775
options.replaysOnErrorSampleRate
6876
) {
6977
integrations.push('Sentry.replayIntegration()');

packages/astro/src/integration/types.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ type SdkEnabledOptions = {
150150
* Sentry code will be added to your bundle.
151151
*
152152
* @default true - the SDK is enabled by default for both, client and server.
153+
*
153154
*/
154155
enabled?:
155156
| boolean
@@ -159,6 +160,41 @@ type SdkEnabledOptions = {
159160
};
160161
};
161162

163+
type DeprecatedRuntimeOptions = Pick<
164+
Options,
165+
'environment' | 'release' | 'dsn' | 'debug' | 'sampleRate' | 'tracesSampleRate'
166+
> &
167+
Pick<BrowserOptions, 'replaysSessionSampleRate' | 'replaysOnErrorSampleRate'> & {
168+
/**
169+
* @deprecated Use the `environment` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead.
170+
*/
171+
environment?: string;
172+
/**
173+
* @deprecated Use the `release` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead.
174+
*/
175+
release?: string;
176+
/**
177+
* @deprecated Use the `dsn` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead.
178+
*/
179+
dsn?: string;
180+
/**
181+
* @deprecated Use the `sampleRate` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead.
182+
*/
183+
sampleRate?: number;
184+
/**
185+
* @deprecated Use the `tracesSampleRate` option in your runtime-specific Sentry.init() call in sentry.client.config.(js|ts) or sentry.server.config.(js|ts) instead.
186+
*/
187+
tracesSampleRate?: number;
188+
/**
189+
* @deprecated Use the `replaysSessionSampleRate` option in your Sentry.init() call in sentry.client.config.(js|ts) instead.
190+
*/
191+
replaysSessionSampleRate?: number;
192+
/**
193+
* @deprecated Use the `replaysOnErrorSampleRate` option in your Sentry.init() call in sentry.client.config.(js|ts) instead.
194+
*/
195+
replaysOnErrorSampleRate?: number;
196+
};
197+
162198
/**
163199
* A subset of Sentry SDK options that can be set via the `sentryAstro` integration.
164200
* Some options (e.g. integrations) are set by default and cannot be changed here.
@@ -169,8 +205,7 @@ type SdkEnabledOptions = {
169205
* If you specify a dedicated init file, the SDK options passed to `sentryAstro` will be ignored.
170206
*/
171207
export type SentryOptions = SdkInitPaths &
172-
Pick<Options, 'dsn' | 'release' | 'environment' | 'sampleRate' | 'tracesSampleRate' | 'debug'> &
173-
Pick<BrowserOptions, 'replaysSessionSampleRate' | 'replaysOnErrorSampleRate'> &
208+
DeprecatedRuntimeOptions &
174209
InstrumentationOptions &
175210
SdkEnabledOptions & {
176211
/**
@@ -187,4 +222,8 @@ export type SentryOptions = SdkInitPaths &
187222
* Do not define them in the `sentry.client.config.(js|ts)` or `sentry.server.config.(js|ts)` files.
188223
*/
189224
bundleSizeOptimizations?: BundleSizeOptimizationOptions;
225+
/**
226+
* If enabled, prints debug logs during the build process.
227+
*/
228+
debug?: boolean;
190229
};

packages/core/src/utils-hoist/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export {
4949
parseSemver,
5050
uuid4,
5151
} from './misc';
52+
// eslint-disable-next-line deprecation/deprecation
5253
export { dynamicRequire, isNodeEnv, loadModule } from './node';
5354
export { normalize, normalizeToSize, normalizeUrlToBase } from './normalize';
5455
export {
@@ -113,6 +114,7 @@ export {
113114
} from './supports';
114115
export { SyncPromise, rejectedSyncPromise, resolvedSyncPromise } from './syncpromise';
115116
export {
117+
// eslint-disable-next-line deprecation/deprecation
116118
_browserPerformanceTimeOriginMode,
117119
browserPerformanceTimeOrigin,
118120
dateTimestampInSeconds,

packages/core/src/utils-hoist/node.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export function isNodeEnv(): boolean {
2323
* Requires a module which is protected against bundler minification.
2424
*
2525
* @param request The module path to resolve
26+
* @deprecated This function will be removed in the next major version.
2627
*/
2728
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2829
export function dynamicRequire(mod: any, request: string): any {
@@ -47,14 +48,17 @@ export function loadModule<T>(moduleName: string): T | undefined {
4748
let mod: T | undefined;
4849

4950
try {
51+
// eslint-disable-next-line deprecation/deprecation
5052
mod = dynamicRequire(module, moduleName);
5153
} catch (e) {
5254
// no-empty
5355
}
5456

5557
if (!mod) {
5658
try {
59+
// eslint-disable-next-line deprecation/deprecation
5760
const { cwd } = dynamicRequire(module, 'process');
61+
// eslint-disable-next-line deprecation/deprecation
5862
mod = dynamicRequire(module, `${cwd()}/node_modules/${moduleName}`) as T;
5963
} catch (e) {
6064
// no-empty

packages/core/src/utils-hoist/time.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ export const timestampInSeconds = createUnixTimestampInSecondsFunc();
7070

7171
/**
7272
* Internal helper to store what is the source of browserPerformanceTimeOrigin below. For debugging only.
73+
*
74+
* @deprecated This variable will be removed in the next major version.
7375
*/
7476
export let _browserPerformanceTimeOriginMode: string;
7577

@@ -84,6 +86,7 @@ export const browserPerformanceTimeOrigin = ((): number | undefined => {
8486

8587
const { performance } = GLOBAL_OBJ as typeof GLOBAL_OBJ & Window;
8688
if (!performance || !performance.now) {
89+
// eslint-disable-next-line deprecation/deprecation
8790
_browserPerformanceTimeOriginMode = 'none';
8891
return undefined;
8992
}
@@ -113,15 +116,18 @@ export const browserPerformanceTimeOrigin = ((): number | undefined => {
113116
if (timeOriginIsReliable || navigationStartIsReliable) {
114117
// Use the more reliable time origin
115118
if (timeOriginDelta <= navigationStartDelta) {
119+
// eslint-disable-next-line deprecation/deprecation
116120
_browserPerformanceTimeOriginMode = 'timeOrigin';
117121
return performance.timeOrigin;
118122
} else {
123+
// eslint-disable-next-line deprecation/deprecation
119124
_browserPerformanceTimeOriginMode = 'navigationStart';
120125
return navigationStart;
121126
}
122127
}
123128

124129
// Either both timeOrigin and navigationStart are skewed or neither is available, fallback to Date.
130+
// eslint-disable-next-line deprecation/deprecation
125131
_browserPerformanceTimeOriginMode = 'dateNow';
126132
return dateNow;
127133
})();

packages/node/src/integrations/node-fetch.ts

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,10 @@
1-
import { context, propagation, trace } from '@opentelemetry/api';
21
import { registerInstrumentations } from '@opentelemetry/instrumentation';
32
import type { UndiciRequest, UndiciResponse } from '@opentelemetry/instrumentation-undici';
43
import { UndiciInstrumentation } from '@opentelemetry/instrumentation-undici';
5-
import {
6-
SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
7-
addBreadcrumb,
8-
defineIntegration,
9-
getCurrentScope,
10-
hasTracingEnabled,
11-
} from '@sentry/core';
4+
import { LRUMap, getClient, getTraceData } from '@sentry/core';
5+
import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, addBreadcrumb, defineIntegration, hasTracingEnabled } from '@sentry/core';
126
import { getBreadcrumbLogLevelFromHttpStatusCode, getSanitizedUrlString, parseUrl } from '@sentry/core';
13-
import { generateSpanContextForPropagationContext, getPropagationContextFromSpan } from '@sentry/opentelemetry';
7+
import { shouldPropagateTraceForUrl } from '@sentry/opentelemetry';
148
import type { IntegrationFn, SanitizedRequestData } from '@sentry/types';
159

1610
interface NodeFetchOptions {
@@ -34,6 +28,8 @@ const _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => {
3428
return {
3529
name: 'NodeFetch',
3630
setupOnce() {
31+
const propagationDecisionMap = new LRUMap<string, boolean>(100);
32+
3733
const instrumentation = new UndiciInstrumentation({
3834
requireParentforSpans: false,
3935
ignoreRequestHook: request => {
@@ -47,22 +43,10 @@ const _nativeNodeFetchIntegration = ((options: NodeFetchOptions = {}) => {
4743
// If tracing is disabled, we still want to propagate traces
4844
// So we do that manually here, matching what the instrumentation does otherwise
4945
if (!hasTracingEnabled()) {
50-
const ctx = context.active();
51-
const addedHeaders: Record<string, string> = {};
52-
53-
// We generate a virtual span context from the active one,
54-
// Where we attach the URL to the trace state, so the propagator can pick it up
55-
const activeSpan = trace.getSpan(ctx);
56-
const propagationContext = activeSpan
57-
? getPropagationContextFromSpan(activeSpan)
58-
: getCurrentScope().getPropagationContext();
59-
60-
const spanContext = generateSpanContextForPropagationContext(propagationContext);
61-
// We know that in practice we'll _always_ haven a traceState here
62-
spanContext.traceState = spanContext.traceState?.set('sentry.url', url);
63-
const ctxWithUrlTraceState = trace.setSpanContext(ctx, spanContext);
64-
65-
propagation.inject(ctxWithUrlTraceState, addedHeaders);
46+
const tracePropagationTargets = getClient()?.getOptions().tracePropagationTargets;
47+
const addedHeaders = shouldPropagateTraceForUrl(url, tracePropagationTargets, propagationDecisionMap)
48+
? getTraceData()
49+
: {};
6650

6751
const requestHeaders = request.headers;
6852
if (Array.isArray(requestHeaders)) {

packages/nuxt/src/server/sdk.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import * as path from 'node:path';
12
import { applySdkMetadata, flush, getGlobalScope } from '@sentry/core';
23
import { logger, vercelWaitUntil } from '@sentry/core';
34
import {
@@ -33,23 +34,26 @@ export function init(options: SentryNuxtServerOptions): Client | undefined {
3334
}
3435

3536
/**
36-
* Filter out transactions for Nuxt build assets
37-
* This regex matches the default path to the nuxt-generated build assets (`_nuxt`).
37+
* Filter out transactions for resource requests which we don't want to send to Sentry
38+
* for quota reasons.
3839
*
3940
* Only exported for testing
4041
*/
4142
export function lowQualityTransactionsFilter(options: SentryNuxtServerOptions): EventProcessor {
4243
return Object.assign(
4344
(event => {
44-
if (event.type === 'transaction' && event.transaction?.match(/^GET \/_nuxt\//)) {
45-
// todo: the buildAssetDir could be changed in the nuxt config - change this to a more generic solution
45+
if (event.type !== 'transaction' || !event.transaction) {
46+
return event;
47+
}
48+
// We don't want to send transaction for file requests, so everything ending with a *.someExtension should be filtered out
49+
// path.extname will return an empty string for normal page requests
50+
if (path.extname(event.transaction)) {
4651
options.debug &&
4752
DEBUG_BUILD &&
4853
logger.log('NuxtLowQualityTransactionsFilter filtered transaction: ', event.transaction);
4954
return null;
50-
} else {
51-
return event;
5255
}
56+
return event;
5357
}) satisfies EventProcessor,
5458
{ id: 'NuxtLowQualityTransactionsFilter' },
5559
);

packages/nuxt/test/server/sdk.test.ts

Lines changed: 26 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -45,45 +45,39 @@ describe('Nuxt Server SDK', () => {
4545
expect(init({})).not.toBeUndefined();
4646
});
4747

48-
it('filters out low quality transactions', async () => {
48+
describe('low quality transactions filter (%s)', () => {
4949
const beforeSendEvent = vi.fn(event => event);
5050
const client = init({
5151
dsn: 'https://[email protected]/1337',
5252
}) as NodeClient;
5353
client.on('beforeSendEvent', beforeSendEvent);
5454

55-
client.captureEvent({ type: 'transaction', transaction: 'GET /' });
56-
client.captureEvent({ type: 'transaction', transaction: 'GET /_nuxt/some_asset.js' });
57-
// Although this has the name of the build asset directory (_nuxt), it should not be filtered out as it would not match the regex
58-
client.captureEvent({ type: 'transaction', transaction: 'GET _nuxt/some_asset.js' });
59-
client.captureEvent({ type: 'transaction', transaction: 'POST /_server' });
60-
61-
await client!.flush();
55+
it.each([
56+
[
57+
'GET /_nuxt/some_asset.js',
58+
'GET _nuxt/some_asset.js',
59+
'GET /icons/favicon.ico',
60+
'GET /assets/logo.png',
61+
'GET /icons/zones/forest.svg',
62+
],
63+
])('filters out low quality transactions', async transaction => {
64+
client.captureEvent({ type: 'transaction', transaction });
65+
await client!.flush();
66+
expect(beforeSendEvent).not.toHaveBeenCalled();
67+
});
6268

63-
expect(beforeSendEvent).toHaveBeenCalledTimes(3);
64-
expect(beforeSendEvent).toHaveBeenCalledWith(
65-
expect.objectContaining({
66-
transaction: 'GET /',
67-
}),
68-
expect.any(Object),
69-
);
70-
expect(beforeSendEvent).toHaveBeenCalledWith(
71-
expect.objectContaining({
72-
transaction: 'GET _nuxt/some_asset.js',
73-
}),
74-
expect.any(Object),
75-
);
76-
expect(beforeSendEvent).not.toHaveBeenCalledWith(
77-
expect.objectContaining({
78-
transaction: 'GET /_nuxt/some_asset.js',
79-
}),
80-
expect.any(Object),
81-
);
82-
expect(beforeSendEvent).toHaveBeenCalledWith(
83-
expect.objectContaining({
84-
transaction: 'POST /_server',
85-
}),
86-
expect.any(Object),
69+
it.each(['GET /', 'POST /_server'])(
70+
'does not filter out high quality or route transactions (%s)',
71+
async transaction => {
72+
client.captureEvent({ type: 'transaction', transaction });
73+
await client!.flush();
74+
expect(beforeSendEvent).toHaveBeenCalledWith(
75+
expect.objectContaining({
76+
transaction,
77+
}),
78+
expect.any(Object),
79+
);
80+
},
8781
);
8882
});
8983

0 commit comments

Comments
 (0)