Skip to content

meta: Prepare prelease of 8.35.0-beta.0 #13988

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
4a2da31
Merge pull request #13946 from getsentry/master
github-actions[bot] Oct 11, 2024
1d87cec
fix: Ensure type for `init` is correct in meta frameworks (#13938)
mydea Oct 11, 2024
5d5e2f4
feat(node): Implement Sentry-specific http instrumentation (#13763)
mydea Oct 11, 2024
10533fe
fix(module): keep version for node ESM package (#13922)
ZakrepaShe Oct 11, 2024
26ec075
ci: Ensure we check correctly for bot users (#13955)
mydea Oct 11, 2024
9af0d84
ref: Add external contributor to CHANGELOG.md (#13956)
HazAT Oct 11, 2024
81df165
feat(core): Make stream instrumentation opt-in (#13951)
chargome Oct 11, 2024
8dd854f
feat(node): Expose `suppressTracing` API (#13875)
zhiyan114 Oct 11, 2024
e1d7a9d
test(loader): Update Loader Script & test error in `sentryOnLoad` (#1…
mydea Oct 14, 2024
eb40643
dev(e2e): Fix nestjs version constraint (#13964)
billyvg Oct 14, 2024
0ccf8ce
ref: Add external contributor to CHANGELOG.md (#13959)
HazAT Oct 14, 2024
50ab948
test(browser): Add test for current DSC transaction name updating beh…
Lms24 Oct 14, 2024
8249a5e
feat(nuxt): Add Rollup plugin to wrap server entry with `import()` (#…
s1gr1d Oct 14, 2024
5f68d4d
fix(replay): Fix onError sampling when loading an expired buffered se…
billyvg Oct 15, 2024
b8d0f2f
chore(node): Bump `@opentelemetry/instrumentation-express` to `0.43.0…
onurtemizkan Oct 15, 2024
ecf84e0
feat(vue): Add Pinia plugin (#13841)
onurtemizkan Oct 15, 2024
4c0c25c
test(node): Add tests for current DSC transaction name updating behav…
Lms24 Oct 15, 2024
b86c182
feat(replay): Do not log "timeout while trying to read resp body" as …
billyvg Oct 15, 2024
214cdf0
meta: Prepare prelease of 8.35.0-beta.0
billyvg Oct 15, 2024
97aff96
prettier
billyvg Oct 15, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/external-contributors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
&& github.event.pull_request.author_association != 'COLLABORATOR'
&& github.event.pull_request.author_association != 'MEMBER'
&& github.event.pull_request.author_association != 'OWNER'
&& endsWith(github.actor, '[bot]') == false
&& endsWith(github.event.pull_request.user.login, '[bot]') == false
steps:
- uses: actions/checkout@v4
- name: Set up Node
Expand Down
2 changes: 1 addition & 1 deletion .size-limit.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ module.exports = [
path: 'packages/browser/build/npm/esm/index.js',
import: createImport('init', 'browserTracingIntegration', 'replayIntegration', 'feedbackIntegration'),
gzip: true,
limit: '91 KB',
limit: '95 KB',
},
{
name: '@sentry/browser (incl. Tracing, Replay, Feedback, metrics)',
Expand Down
40 changes: 40 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,46 @@

- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott

## 8.35.0-beta.0

### Important Changes

- **feat(core): Make stream instrumentation opt-in
([#13951](https://github.com/getsentry/sentry-javascript/pull/13951))**

This change adds a new option `trackFetchStreamPerformance` to the browser tracing integration. Only when set to `true`,
Sentry will instrument streams via fetch.

Work in this release was contributed by @ZakrepaShe and @zhiyan114. Thank you for your contributions!

### Other Changes

- chore(node): Bump `@opentelemetry/instrumentation-express` to `0.43.0`
([#13948](https://github.com/getsentry/sentry-javascript/pull/13948))
- ci: Ensure we check correctly for bot users ([#13955](https://github.com/getsentry/sentry-javascript/pull/13955))
- dev(e2e): Fix nestjs version constraint ([#13964](https://github.com/getsentry/sentry-javascript/pull/13964))
- feat(node): Expose `suppressTracing` API ([#13875](https://github.com/getsentry/sentry-javascript/pull/13875))
- feat(node): Implement Sentry-specific http instrumentation
([#13763](https://github.com/getsentry/sentry-javascript/pull/13763))
- feat(nuxt): Add Rollup plugin to wrap server entry with `import()`
([#13945](https://github.com/getsentry/sentry-javascript/pull/13945))
- feat(replay): Do not log "timeout while trying to read resp body" as exception
([#13965](https://github.com/getsentry/sentry-javascript/pull/13965))
- feat(vue): Add Pinia plugin ([#13841](https://github.com/getsentry/sentry-javascript/pull/13841))
- fix: Ensure type for `init` is correct in meta frameworks
([#13938](https://github.com/getsentry/sentry-javascript/pull/13938))
- fix(module): keep version for node ESM package ([#13922](https://github.com/getsentry/sentry-javascript/pull/13922))
- fix(replay): Fix onError sampling when loading an expired buffered session
([#13962](https://github.com/getsentry/sentry-javascript/pull/13962))
- ref: Add external contributor to CHANGELOG.md ([#13956](https://github.com/getsentry/sentry-javascript/pull/13956))
- ref: Add external contributor to CHANGELOG.md ([#13959](https://github.com/getsentry/sentry-javascript/pull/13959))
- test(browser): Add test for current DSC transaction name updating behavior
([#13953](https://github.com/getsentry/sentry-javascript/pull/13953))
- test(loader): Update Loader Script & test error in `sentryOnLoad`
([#13952](https://github.com/getsentry/sentry-javascript/pull/13952))
- test(node): Add tests for current DSC transaction name updating behavior
([#13961](https://github.com/getsentry/sentry-javascript/pull/13961))

## 8.34.0

### Important Changes
Expand Down
2 changes: 1 addition & 1 deletion dev-packages/browser-integration-tests/fixtures/loader.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// we define sentryOnLoad in template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Sentry.captureException('Test exception');
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script>
window.sentryOnLoad = function () {
Sentry.init({
tracesSampleRate: 0.123,
});

throw new Error('sentryOnLoad error');
};
</script>
</head>
<body></body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../../utils/fixtures';
import { envelopeRequestParser, waitForErrorRequestOnUrl } from '../../../../utils/helpers';

sentryTest(
'sentryOnLoad callback is called before Sentry.onLoad() and handles errors in handler',
async ({ getLocalTestUrl, page }) => {
const errors: string[] = [];

page.on('console', msg => {
if (msg.type() === 'error') {
errors.push(msg.text());
}
});

const url = await getLocalTestUrl({ testDir: __dirname });
const req = await waitForErrorRequestOnUrl(page, url);

const eventData = envelopeRequestParser(req);

expect(eventData.message).toBe('Test exception');

expect(await page.evaluate('Sentry.getClient().getOptions().tracesSampleRate')).toEqual(0.123);

expect(errors).toEqual([
'Error while calling `sentryOnLoad` handler:',
expect.stringContaining('Error: sentryOnLoad error'),
]);
},
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
integrations: [Sentry.browserTracingIntegration({ instrumentNavigation: false, instrumentPageLoad: false })],
tracesSampleRate: 1,
tracePropagationTargets: ['example.com'],
release: '1.1.1',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
const btnStartSpan = document.getElementById('btnStartSpan');
const btnUpdateName = document.getElementById('btnUpdateName');
const btnMakeRequest = document.getElementById('btnMakeRequest');
const btnCaptureError = document.getElementById('btnCaptureError');
const btnEndSpan = document.getElementById('btnEndSpan');

btnStartSpan.addEventListener('click', () => {
Sentry.startSpanManual(
{ name: 'test-root-span', attributes: { [Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'url' } },
async span => {
window.__traceId = span.spanContext().traceId;
await new Promise(resolve => {
btnEndSpan.addEventListener('click', resolve);
});
span.end();
},
);
});

let updateCnt = 0;
btnUpdateName.addEventListener('click', () => {
const span = Sentry.getActiveSpan();
const rootSpan = Sentry.getRootSpan(span);
rootSpan.updateName(`updated-root-span-${++updateCnt}`);
rootSpan.setAttribute(Sentry.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');
});

btnMakeRequest.addEventListener('click', () => {
fetch('https://example.com/api');
});

btnCaptureError.addEventListener('click', () => {
Sentry.captureException(new Error('test-error'));
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<button id="btnStartSpan">Start Span</button>
<button id="btnUpdateName">Update Name</button>
<button id="btnMakeRequest">Make Request</button>
<button id="btnCaptureError">Capture Error</button>
<button id="btnEndSpan">End Span</button>
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import { expect } from '@playwright/test';
import type { Page } from '@playwright/test';
import type { DynamicSamplingContext } from '@sentry/types';
import { sentryTest } from '../../../utils/fixtures';
import type { EventAndTraceHeader } from '../../../utils/helpers';
import {
eventAndTraceHeaderRequestParser,
getMultipleSentryEnvelopeRequests,
shouldSkipTracingTest,
} from '../../../utils/helpers';

sentryTest('updates the DSC when the txn name is updated and high-quality', async ({ getLocalTestUrl, page }) => {
if (shouldSkipTracingTest()) {
sentryTest.skip();
}

const url = await getLocalTestUrl({ testDir: __dirname });

await page.goto(url);

/*
Test Steps:
1. Start new span with LQ txn name (source: url)
2. Make request and check that baggage has no transaction name
3. Capture error and check that envelope trace header has no transaction name
4. Update span name and source to HQ (source: route)
5. Make request and check that baggage has HQ txn name
6. Capture error and check that envelope trace header has HQ txn name
7. Update span name again with HQ name (source: route)
8. Make request and check that baggage has updated HQ txn name
9. Capture error and check that envelope trace header has updated HQ txn name
10. End span and check that envelope trace header has updated HQ txn name
11. Make another request and check that there's no span information in baggage
12. Capture an error and check that envelope trace header has no span information
*/

// 1
await page.locator('#btnStartSpan').click();
const traceId = await page.evaluate(() => {
return (window as any).__traceId;
});

expect(traceId).toMatch(/^[0-9a-f]{32}$/);

// 2
const baggageItems = await makeRequestAndGetBaggageItems(page);
expect(baggageItems).toEqual([
'sentry-environment=production',
'sentry-public_key=public',
'sentry-release=1.1.1',
'sentry-sample_rate=1',
'sentry-sampled=true',
`sentry-trace_id=${traceId}`,
]);

// 3
const errorEnvelopeTraceHeader = await captureErrorAndGetEnvelopeTraceHeader(page);
expect(errorEnvelopeTraceHeader).toEqual({
environment: 'production',
public_key: 'public',
release: '1.1.1',
sample_rate: '1',
sampled: 'true',
trace_id: traceId,
});

// 4
await page.locator('#btnUpdateName').click();

// 5
const baggageItemsAfterUpdate = await makeRequestAndGetBaggageItems(page);
expect(baggageItemsAfterUpdate).toEqual([
'sentry-environment=production',
'sentry-public_key=public',
'sentry-release=1.1.1',
'sentry-sample_rate=1',
'sentry-sampled=true',
`sentry-trace_id=${traceId}`,
'sentry-transaction=updated-root-span-1',
]);

// 6
const errorEnvelopeTraceHeaderAfterUpdate = await captureErrorAndGetEnvelopeTraceHeader(page);
expect(errorEnvelopeTraceHeaderAfterUpdate).toEqual({
environment: 'production',
public_key: 'public',
release: '1.1.1',
sample_rate: '1',
sampled: 'true',
trace_id: traceId,
transaction: 'updated-root-span-1',
});

// 7
await page.locator('#btnUpdateName').click();

// 8
const baggageItemsAfterSecondUpdate = await makeRequestAndGetBaggageItems(page);
expect(baggageItemsAfterSecondUpdate).toEqual([
'sentry-environment=production',
'sentry-public_key=public',
'sentry-release=1.1.1',
'sentry-sample_rate=1',
'sentry-sampled=true',
`sentry-trace_id=${traceId}`,
'sentry-transaction=updated-root-span-2',
]);

// 9
const errorEnvelopeTraceHeaderAfterSecondUpdate = await captureErrorAndGetEnvelopeTraceHeader(page);
expect(errorEnvelopeTraceHeaderAfterSecondUpdate).toEqual({
environment: 'production',
public_key: 'public',
release: '1.1.1',
sample_rate: '1',
sampled: 'true',
trace_id: traceId,
transaction: 'updated-root-span-2',
});

// 10
const txnEventPromise = getMultipleSentryEnvelopeRequests<EventAndTraceHeader>(
page,
1,
{ envelopeType: 'transaction' },
eventAndTraceHeaderRequestParser,
);

await page.locator('#btnEndSpan').click();

const [txnEvent, txnEnvelopeTraceHeader] = (await txnEventPromise)[0];
expect(txnEnvelopeTraceHeader).toEqual({
environment: 'production',
public_key: 'public',
release: '1.1.1',
sample_rate: '1',
sampled: 'true',
trace_id: traceId,
transaction: 'updated-root-span-2',
});

expect(txnEvent.transaction).toEqual('updated-root-span-2');

// 11
const baggageItemsAfterEnd = await makeRequestAndGetBaggageItems(page);
expect(baggageItemsAfterEnd).toEqual([
'sentry-environment=production',
'sentry-public_key=public',
'sentry-release=1.1.1',
`sentry-trace_id=${traceId}`,
]);

// 12
const errorEnvelopeTraceHeaderAfterEnd = await captureErrorAndGetEnvelopeTraceHeader(page);
expect(errorEnvelopeTraceHeaderAfterEnd).toEqual({
environment: 'production',
public_key: 'public',
release: '1.1.1',
trace_id: traceId,
});
});

async function makeRequestAndGetBaggageItems(page: Page): Promise<string[]> {
const requestPromise = page.waitForRequest('https://example.com/*');
await page.locator('#btnMakeRequest').click();
const request = await requestPromise;

const baggage = await request.headerValue('baggage');

return baggage?.split(',').sort() ?? [];
}

async function captureErrorAndGetEnvelopeTraceHeader(page: Page): Promise<DynamicSamplingContext | undefined> {
const errorEventPromise = getMultipleSentryEnvelopeRequests<EventAndTraceHeader>(
page,
1,
{ envelopeType: 'event' },
eventAndTraceHeaderRequestParser,
);

await page.locator('#btnCaptureError').click();

const [, errorEnvelopeTraceHeader] = (await errorEventPromise)[0];
return errorEnvelopeTraceHeader;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
const errorBtn = document.getElementById('errorBtn');
errorBtn.addEventListener('click', () => {
throw new Error(`Sentry Test Error ${Math.random()}`);
});

const fetchBtn = document.getElementById('fetchBtn');
fetchBtn.addEventListener('click', async () => {
await fetch('http://example.com');
});

const xhrBtn = document.getElementById('xhrBtn');
xhrBtn.addEventListener('click', () => {
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com');
xhr.send();
});
Loading
Loading