Skip to content

Commit

Permalink
Merge branch 'develop' into sig/remove-transactionnaminscheme
Browse files Browse the repository at this point in the history
  • Loading branch information
s1gr1d authored Jan 2, 2025
2 parents bd2275e + 0a54f8f commit e37da93
Show file tree
Hide file tree
Showing 31 changed files with 633 additions and 176 deletions.
3 changes: 1 addition & 2 deletions dev-packages/browser-integration-tests/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,12 @@
"axios": "1.7.7",
"babel-loader": "^8.2.2",
"html-webpack-plugin": "^5.5.0",
"pako": "^2.1.0",
"fflate": "0.8.2",
"webpack": "^5.95.0"
},
"devDependencies": {
"@types/glob": "8.0.0",
"@types/node": "^18.19.1",
"@types/pako": "^2.0.0",
"glob": "8.0.3"
},
"volta": {
Expand Down
15 changes: 12 additions & 3 deletions dev-packages/browser-integration-tests/utils/replayHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import type { fullSnapshotEvent, incrementalSnapshotEvent } from '@sentry-intern
import { EventType } from '@sentry-internal/rrweb';
import type { ReplayEventWithTime } from '@sentry/browser';
import type { Breadcrumb, Event, ReplayEvent, ReplayRecordingMode } from '@sentry/core';
import pako from 'pako';
import { decompressSync, strFromU8 } from 'fflate';

import { envelopeRequestParser } from './helpers';

Expand Down Expand Up @@ -406,9 +406,9 @@ export const replayEnvelopeParser = (request: Request | null): unknown[] => {
if (envelopeBytes[i] === 0x78 && envelopeBytes[i + 1] === 0x9c) {
try {
// We found a zlib-compressed payload - let's decompress it
const payload = envelopeBytes.slice(i);
const payload = (envelopeBytes as Buffer).subarray(i);
// now we return the decompressed payload as JSON
const decompressedPayload = pako.inflate(payload as unknown as Uint8Array, { to: 'string' });
const decompressedPayload = decompress(payload);
return JSON.parse(decompressedPayload);
} catch {
// Let's log that something went wrong
Expand Down Expand Up @@ -488,3 +488,12 @@ function getRequest(resOrReq: Request | Response): Request {
// @ts-expect-error we check this
return typeof resOrReq.request === 'function' ? (resOrReq as Response).request() : (resOrReq as Request);
}

/** Decompress a compressed data payload. */
function decompress(data: Uint8Array): string {
if (!(data instanceof Uint8Array)) {
throw new Error(`Data passed to decompress is not a Uint8Array: ${data}`);
}
const decompressed = decompressSync(data);
return strFromU8(decompressed);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
dist
2 changes: 2 additions & 0 deletions dev-packages/e2e-tests/test-applications/node-otel/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
@sentry:registry=http://127.0.0.1:4873
@sentry-internal:registry=http://127.0.0.1:4873
31 changes: 31 additions & 0 deletions dev-packages/e2e-tests/test-applications/node-otel/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "node-otel",
"version": "1.0.0",
"private": true,
"scripts": {
"build": "tsc",
"start": "node dist/app.js",
"test": "playwright test",
"clean": "npx rimraf node_modules pnpm-lock.yaml",
"test:build": "pnpm install && pnpm build",
"test:assert": "pnpm test"
},
"dependencies": {
"@opentelemetry/sdk-node": "0.52.1",
"@opentelemetry/exporter-trace-otlp-http": "0.52.1",
"@sentry/core": "latest || *",
"@sentry/node": "latest || *",
"@sentry/opentelemetry": "latest || *",
"@types/express": "4.17.17",
"@types/node": "^18.19.1",
"express": "4.20.0",
"typescript": "~5.0.0"
},
"devDependencies": {
"@playwright/test": "^1.44.1",
"@sentry-internal/test-utils": "link:../../../test-utils"
},
"volta": {
"extends": "../../package.json"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { getPlaywrightConfig } from '@sentry-internal/test-utils';

const config = getPlaywrightConfig(
{
startCommand: `pnpm start`,
},
{
webServer: [
{
command: `node ./start-event-proxy.mjs`,
port: 3031,
stdout: 'pipe',
stderr: 'pipe',
},
{
command: `node ./start-otel-proxy.mjs`,
port: 3032,
stdout: 'pipe',
stderr: 'pipe',
},
{
command: 'pnpm start',
port: 3030,
stdout: 'pipe',
stderr: 'pipe',
env: {
PORT: 3030,
},
},
],
},
);

export default config;
53 changes: 53 additions & 0 deletions dev-packages/e2e-tests/test-applications/node-otel/src/app.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import './instrument';

// Other imports below
import * as Sentry from '@sentry/node';
import express from 'express';

const app = express();
const port = 3030;

app.get('/test-success', function (req, res) {
res.send({ version: 'v1' });
});

app.get('/test-param/:param', function (req, res) {
res.send({ paramWas: req.params.param });
});

app.get('/test-transaction', function (req, res) {
Sentry.withActiveSpan(null, async () => {
Sentry.startSpan({ name: 'test-transaction', op: 'e2e-test' }, () => {
Sentry.startSpan({ name: 'test-span' }, () => undefined);
});

await Sentry.flush();

res.send({});
});
});

app.get('/test-error', async function (req, res) {
const exceptionId = Sentry.captureException(new Error('This is an error'));

await Sentry.flush(2000);

res.send({ exceptionId });
});

app.get('/test-exception/:id', function (req, _res) {
throw new Error(`This is an exception with id ${req.params.id}`);
});

Sentry.setupExpressErrorHandler(app);

app.use(function onError(err: unknown, req: any, res: any, next: any) {
// The error id is attached to `res.sentry` to be returned
// and optionally displayed to the user for support.
res.statusCode = 500;
res.end(res.sentry + '\n');
});

app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const opentelemetry = require('@opentelemetry/sdk-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const Sentry = require('@sentry/node');

const sentryClient = Sentry.init({
environment: 'qa', // dynamic sampling bias to keep transactions
dsn:
process.env.E2E_TEST_DSN ||
'https://3b6c388182fb435097f41d181be2b2ba@o4504321058471936.ingest.sentry.io/4504321066008576',
debug: !!process.env.DEBUG,
tunnel: `http://localhost:3031/`, // proxy server
tracesSampleRate: 1,

// Additional OTEL options
openTelemetrySpanProcessors: [
new opentelemetry.node.BatchSpanProcessor(
new OTLPTraceExporter({
url: 'http://localhost:3032/',
}),
),
],
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { startEventProxyServer } from '@sentry-internal/test-utils';

startEventProxyServer({
port: 3031,
proxyServerName: 'node-otel',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { startProxyServer } from '@sentry-internal/test-utils';

startProxyServer({
port: 3032,
proxyServerName: 'node-otel-otel',
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { expect, test } from '@playwright/test';
import { waitForError } from '@sentry-internal/test-utils';

test('Sends correct error event', async ({ baseURL }) => {
const errorEventPromise = waitForError('node-otel', event => {
return !event.type && event.exception?.values?.[0]?.value === 'This is an exception with id 123';
});

await fetch(`${baseURL}/test-exception/123`);

const errorEvent = await errorEventPromise;

expect(errorEvent.exception?.values).toHaveLength(1);
expect(errorEvent.exception?.values?.[0]?.value).toBe('This is an exception with id 123');

expect(errorEvent.request).toEqual({
method: 'GET',
cookies: {},
headers: expect.any(Object),
url: 'http://localhost:3030/test-exception/123',
});

expect(errorEvent.transaction).toEqual('GET /test-exception/:id');

expect(errorEvent.contexts?.trace).toEqual({
trace_id: expect.stringMatching(/[a-f0-9]{32}/),
span_id: expect.stringMatching(/[a-f0-9]{16}/),
});
});
Loading

0 comments on commit e37da93

Please sign in to comment.