Skip to content

meta: Update changelog for 7.54.0 #8271

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
Jun 1, 2023
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
bd80a6e
Merge pull request #8210 from getsentry/master
github-actions[bot] May 24, 2023
b9a9390
ci: Increase playwright test timeout (#8209)
lforst May 25, 2023
3f31b3d
feat(replay): Remove unused debug statements (#8167)
billyvg May 25, 2023
41fef4b
fix(sveltekit): Avoid capturing redirects and 4xx Http errors in requ…
Lms24 May 25, 2023
f359ef3
feat(replay): Throttle breadcrumbs to max 300/5s (#8086)
mydea May 26, 2023
8df6a29
fix(replay): Guard against missing key (#8246)
mydea May 30, 2023
557e84a
ci: Improve canary issue creation (#8253)
mydea May 30, 2023
e95e574
test(replay): Skip firefox for flakey tests (#8222)
billyvg May 30, 2023
252c9e9
fix(sveltekit): Bump `magicast` to support `satisfied` keyword (#8254)
Lms24 May 30, 2023
3bbc1a5
fix(node): Strip query and fragment from request URLs without route p…
richardsimko May 30, 2023
ec094db
feat(sveltekit): Add option to control handling of unknown server rou…
Lms24 May 30, 2023
8482c0a
feat(sveltekit): Auto-detect SvelteKit adapters (#8193)
Lms24 May 30, 2023
78454aa
fix(wasm): Avoid throwing an error when WASM modules are loaded from …
Lms24 May 31, 2023
df5c84a
feat(replay): Promote `mutationBreadcrumbLimit` and `mutationLimit` t…
billyvg May 31, 2023
d5551aa
ref(replay): Capture parametrized route (#8095)
mydea Jun 1, 2023
05cf332
feat(sveltekit): Add source maps support for Vercel (lambda) (#8256)
Lms24 Jun 1, 2023
6208e57
feat(core): Add default ignoreTransactions for Healthchecks (#8191)
HazAT Jun 1, 2023
c368bc8
fix(remix): Pass `loadContext` through wrapped document request funct…
dawnmist Jun 1, 2023
8c6ad15
fix(remix): Don't log missing parameters warning on server-side. (#8269)
onurtemizkan Jun 1, 2023
95f8756
meta: Update changelog for 7.54.0
Lms24 Jun 1, 2023
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/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ jobs:
needs: [job_get_metadata, job_build]
if: needs.job_get_metadata.outputs.changed_browser_integration == 'true' || github.event_name != 'pull_request'
runs-on: ubuntu-20.04
timeout-minutes: 18
timeout-minutes: 25
strategy:
fail-fast: false
matrix:
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,14 @@ jobs:
cd packages/e2e-tests
yarn test:e2e
- name: Create Issue
if: failure()
if: failure() && github.event_name == 'schedule'
uses: JasonEtco/create-an-issue@e27dddc79c92bc6e4562f268fffa5ed752639abd
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUN_LINK: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
with:
filename: .github/CANARY_FAILURE_TEMPLATE.md
update_existing: true

job_ember_canary_test:
name: Ember Canary Tests
Expand Down Expand Up @@ -92,10 +93,12 @@ jobs:
yarn ember try:one ${{ matrix.scenario }} --skip-cleanup=true

- name: Create Issue
if: failure()
if: failure() && github.event_name == 'schedule'
uses: JasonEtco/create-an-issue@e27dddc79c92bc6e4562f268fffa5ed752639abd
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RUN_LINK: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
with:
filename: .github/CANARY_FAILURE_TEMPLATE.md
update_existing: true
title: 'Ember Canary tests failed'
63 changes: 63 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,69 @@

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

## 7.54.0

### Important Changes

- **feat(core): Add default entries to `ignoreTransactions` for Healthchecks #8191**

All SDKs now filter out health check transactions by default.
These are transactions where the transaction name matches typical API health check calls, such as `/^.*healthy.*$/` or `/^. *heartbeat.*$/`. Take a look at [this list](https://github.com/getsentry/sentry-javascript/blob/8c6ad156829f7c4eec34e4a67e6dd866ba482d5d/packages/core/src/integrations/inboundfilters.ts#L8C2-L16) to learn which regexes we currently use to match transaction names.
We believe that these transactions do not provide value in most cases and we want to save you some of your quota by filtering them out by default.
These filters are implemented as default values for the top level `ignoreTransactions` option.

You can disable this filtering by manually specifiying the `InboundFilters` integration and setting the `disableTransactionDefaults` option:
```js
Sentry.init({
//...
integrations: [new InboundFilters({ disableTransactionDefaults: true })],
})
```

- **feat(replay): Add `mutationBreadcrumbLimit` and `mutationLimit` to Replay Options (#8228)**

The previously experimental options `mutationBreadcumbLimit` and `mutationLimit` have been promoted to regular Replay integration options.

A high number of DOM mutations (in a single event loop) can cause performance regressions in end-users' browsers.
Use `mutationBreadcrumbLimit` to send a breadcrumb along with your recording if the mutation limit was reached.
Use `mutationLimit` to stop recording if the mutation limit was reached.

- **feat(sveltekit): Add source maps support for Vercel (lambda) (#8256)**
- feat(sveltekit): Auto-detect SvelteKit adapters (#8193)

The SvelteKit SDK can now be used if you deploy your SvelteKit app to Vercel.
By default, the SDK's Vite plugin will detect the used adapter and adjust the source map uploading config as necessary.
If you want to override the default adapter detection, you can specify the `adapter` option in the `sentrySvelteKit` options:

```js
// vite.config.js
export default defineConfig({
plugins: [
sentrySvelteKit({
adapter: 'vercel',
}),
sveltekit(),
],
});
```

Currently, the Vite plugin will configure itself correctly for `@sveltejs/adapter-auto`, `@sveltejs/adapter-vercel` and `@sveltejs/adapter-node`.

**Important:** The SvelteKit SDK is not yet compatible with Vercel's edge runtime.
It will only work for lambda functions.

### Other Changes

- feat(replay): Throttle breadcrumbs to max 300/5s (#8086)
- feat(sveltekit): Add option to control handling of unknown server routes (#8201)
- fix(node): Strip query and fragment from request URLs without route parameters (#8213)
- fix(remix): Don't log missing parameters warning on server-side. (#8269)
- fix(remix): Pass `loadContext` through wrapped document request function (#8268)
- fix(replay): Guard against missing key (#8246)
- fix(sveltekit): Avoid capturing redirects and 4xx Http errors in request Handlers (#8215)
- fix(sveltekit): Bump `magicast` to support `satisfied` keyword (#8254)
- fix(wasm): Avoid throwing an error when WASM modules are loaded from blobs (#8263)

## 7.53.1

- chore(deps): bump socket.io-parser from 4.2.1 to 4.2.3 (#8196)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,7 @@ window.Sentry = Sentry;
window.Replay = new Sentry.Replay({
flushMinDelay: 500,
flushMaxDelay: 500,
_experiments: {
mutationLimit: 250,
},
mutationLimit: 250,
});

Sentry.init({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../../utils/fixtures';
import { getReplayRecordingContent, shouldSkipReplayTest, waitForReplayRequest } from '../../../../utils/replayHelpers';
import {
getReplayRecordingContent,
getReplaySnapshot,
shouldSkipReplayTest,
waitForReplayRequest,
} from '../../../../utils/replayHelpers';

sentryTest(
'handles large mutations with _experiments.mutationLimit configured',
'handles large mutations by stopping replay when `mutationLimit` configured',
async ({ getLocalTestPath, page, forceFlushReplay, browserName }) => {
if (shouldSkipReplayTest() || ['webkit', 'firefox'].includes(browserName)) {
sentryTest.skip();
Expand Down Expand Up @@ -34,36 +39,29 @@ sentryTest(
await forceFlushReplay();
const res1 = await reqPromise1;

const reqPromise2 = waitForReplayRequest(page);
// replay should be stopped due to mutation limit
let replay = await getReplaySnapshot(page);
expect(replay.session).toBe(undefined);
expect(replay._isEnabled).toBe(false);

void page.click('#button-modify');
await forceFlushReplay();
const res2 = await reqPromise2;

const reqPromise3 = waitForReplayRequest(page);

void page.click('#button-remove');
await page.click('#button-remove');
await forceFlushReplay();
const res3 = await reqPromise3;

const replayData0 = getReplayRecordingContent(res0);
const replayData1 = getReplayRecordingContent(res1);
const replayData2 = getReplayRecordingContent(res2);
const replayData3 = getReplayRecordingContent(res3);

expect(replayData0.fullSnapshots.length).toBe(1);
expect(replayData0.incrementalSnapshots.length).toBe(0);

// This includes both a full snapshot as well as some incremental snapshots
expect(replayData1.fullSnapshots.length).toBe(1);
// Breadcrumbs (click and mutation);
const replayData1 = getReplayRecordingContent(res1);
expect(replayData1.fullSnapshots.length).toBe(0);
expect(replayData1.incrementalSnapshots.length).toBeGreaterThan(0);
expect(replayData1.breadcrumbs.map(({ category }) => category).sort()).toEqual(['replay.mutations', 'ui.click']);

// This does not trigger mutations, for whatever reason - so no full snapshot either!
expect(replayData2.fullSnapshots.length).toBe(0);
expect(replayData2.incrementalSnapshots.length).toBeGreaterThan(0);

// This includes both a full snapshot as well as some incremental snapshots
expect(replayData3.fullSnapshots.length).toBe(1);
expect(replayData3.incrementalSnapshots.length).toBeGreaterThan(0);
replay = await getReplaySnapshot(page);
expect(replay.session).toBe(undefined);
expect(replay._isEnabled).toBe(false);
},
);
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import {
// Session should expire after 2s - keep in sync with init.js
const SESSION_TIMEOUT = 2000;

sentryTest('handles an expired session', async ({ getLocalTestPath, page }) => {
if (shouldSkipReplayTest()) {
sentryTest('handles an expired session', async ({ browserName, getLocalTestPath, page }) => {
// This test seems to only be flakey on firefox
if (shouldSkipReplayTest() || ['firefox'].includes(browserName)) {
sentryTest.skip();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,9 @@ sentryTest('mutation after threshold results in slow click', async ({ getLocalTe
expect(slowClickBreadcrumbs[0]?.data?.timeAfterClickMs).toBeLessThan(2000);
});

sentryTest('immediate mutation does not trigger slow click', async ({ getLocalTestUrl, page }) => {
if (shouldSkipReplayTest()) {
sentryTest('immediate mutation does not trigger slow click', async ({ browserName, getLocalTestUrl, page }) => {
// This test seems to only be flakey on firefox
if (shouldSkipReplayTest() || ['firefox'].includes(browserName)) {
sentryTest.skip();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import * as Sentry from '@sentry/browser';

window.Sentry = Sentry;
window.Replay = new Sentry.Replay({
flushMinDelay: 5000,
flushMaxDelay: 5000,
useCompression: false,
});

Sentry.init({
dsn: 'https://public@dsn.ingest.sentry.io/1337',
sampleRate: 0,
replaysSessionSampleRate: 1.0,
replaysOnErrorSampleRate: 0.0,

integrations: [window.Replay],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
const COUNT = 400;

document.querySelector('[data-console]').addEventListener('click', () => {
// Call console.log() many times
for (let i = 0; i < COUNT; i++) {
console.log(`testing ${i}`);
}
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
</head>
<body>
<button data-console>Trigger console.log</button>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { expect } from '@playwright/test';

import { sentryTest } from '../../../utils/fixtures';
import { getCustomRecordingEvents, shouldSkipReplayTest, waitForReplayRequest } from '../../../utils/replayHelpers';

const THROTTLE_LIMIT = 300;

sentryTest(
'throttles breadcrumbs when many `console.log` are made at the same time',
async ({ getLocalTestUrl, page, forceFlushReplay, browserName }) => {
if (shouldSkipReplayTest() || browserName !== 'chromium') {
sentryTest.skip();
}

const reqPromise0 = waitForReplayRequest(page, 0);
const reqPromise1 = waitForReplayRequest(page, 1);

await page.route('https://dsn.ingest.sentry.io/**/*', route => {
return route.fulfill({
status: 200,
contentType: 'application/json',
body: JSON.stringify({ id: 'test-id' }),
});
});

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

await page.goto(url);
await reqPromise0;

await page.click('[data-console]');
await forceFlushReplay();

const { breadcrumbs } = getCustomRecordingEvents(await reqPromise1);

// 1 click breadcrumb + 1 throttled breadcrumb is why console logs are less
// than throttle limit
expect(breadcrumbs.length).toBe(THROTTLE_LIMIT);
expect(breadcrumbs.filter(breadcrumb => breadcrumb.category === 'replay.throttled').length).toBe(1);
},
);
30 changes: 22 additions & 8 deletions packages/browser-integration-tests/utils/replayHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ export type IncrementalRecordingSnapshot = eventWithTime & {

export type RecordingSnapshot = FullRecordingSnapshot | IncrementalRecordingSnapshot;

/** Returns the replay event from the given request, or undefined if this is not a replay request. */
export function getReplayEventFromRequest(req: Request): ReplayEvent | undefined {
const postData = req.postData();
if (!postData) {
return undefined;
}

try {
const event = envelopeRequestParser(req);

if (!isReplayEvent(event)) {
return undefined;
}

return event;
} catch {
return undefined;
}
}
/**
* Waits for a replay request to be sent by the page and returns it.
*
Expand All @@ -58,18 +77,13 @@ export function waitForReplayRequest(
res => {
const req = res.request();

const postData = req.postData();
if (!postData) {
const event = getReplayEventFromRequest(req);

if (!event) {
return false;
}

try {
const event = envelopeRequestParser(req);

if (!isReplayEvent(event)) {
return false;
}

if (callback) {
return callback(event, res);
}
Expand Down
20 changes: 18 additions & 2 deletions packages/core/src/integrations/inboundfilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,25 @@ import { getEventDescription, logger, stringMatchesSomePattern } from '@sentry/u
// this is the result of a script being pulled in from an external domain and CORS.
const DEFAULT_IGNORE_ERRORS = [/^Script error\.?$/, /^Javascript error: Script error\.? on line 0$/];

const DEFAULT_IGNORE_TRANSACTIONS = [
/^.*healthcheck.*$/,
/^.*healthy.*$/,
/^.*live.*$/,
/^.*ready.*$/,
/^.*heartbeat.*$/,
/^.*\/health$/,
/^.*\/healthz$/,
];

/** Options for the InboundFilters integration */
export interface InboundFiltersOptions {
allowUrls: Array<string | RegExp>;
denyUrls: Array<string | RegExp>;
ignoreErrors: Array<string | RegExp>;
ignoreTransactions: Array<string | RegExp>;
ignoreInternal: boolean;
disableErrorDefaults: boolean;
disableTransactionDefaults: boolean;
}

/** Inbound filters configurable by the user */
Expand Down Expand Up @@ -62,9 +74,13 @@ export function _mergeOptions(
ignoreErrors: [
...(internalOptions.ignoreErrors || []),
...(clientOptions.ignoreErrors || []),
...DEFAULT_IGNORE_ERRORS,
...(internalOptions.disableErrorDefaults ? [] : DEFAULT_IGNORE_ERRORS),
],
ignoreTransactions: [
...(internalOptions.ignoreTransactions || []),
...(clientOptions.ignoreTransactions || []),
...(internalOptions.disableTransactionDefaults ? [] : DEFAULT_IGNORE_TRANSACTIONS),
],
ignoreTransactions: [...(internalOptions.ignoreTransactions || []), ...(clientOptions.ignoreTransactions || [])],
ignoreInternal: internalOptions.ignoreInternal !== undefined ? internalOptions.ignoreInternal : true,
};
}
Expand Down
Loading