Skip to content

Commit

Permalink
feat(node): Implement Sentry-specific http instrumentation
Browse files Browse the repository at this point in the history
  • Loading branch information
mydea committed Sep 24, 2024
1 parent a9750be commit 97c18d3
Show file tree
Hide file tree
Showing 9 changed files with 543 additions and 325 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"@opentelemetry/sdk-trace-node": "1.26.0",
"@opentelemetry/exporter-trace-otlp-http": "0.53.0",
"@opentelemetry/instrumentation-undici": "0.6.0",
"@opentelemetry/instrumentation-http": "0.53.0",
"@opentelemetry/instrumentation": "0.53.0",
"@sentry/core": "latest || *",
"@sentry/node": "latest || *",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import express from 'express';
const app = express();
const port = 3030;

Sentry.setTag('root-level-tag', 'yes');

app.get('/test-success', function (req, res) {
res.send({ version: 'v1' });
});
Expand All @@ -23,8 +25,6 @@ app.get('/test-transaction', function (req, res) {

await fetch('http://localhost:3030/test-success');

await Sentry.flush();

res.send({});
});
});
Expand All @@ -38,7 +38,10 @@ app.get('/test-error', async function (req, res) {
});

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

throw new Error(`This is an exception with id ${id}`);
});

Sentry.setupExpressErrorHandler(app);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { HttpInstrumentation } = require('@opentelemetry/instrumentation-http');
const { NodeTracerProvider, BatchSpanProcessor } = require('@opentelemetry/sdk-trace-node');
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
const Sentry = require('@sentry/node');
const { SentrySpanProcessor, SentryPropagator } = require('@sentry/opentelemetry');
const { SentryPropagator } = require('@sentry/opentelemetry');
const { UndiciInstrumentation } = require('@opentelemetry/instrumentation-undici');
const { registerInstrumentations } = require('@opentelemetry/instrumentation');

Expand All @@ -15,6 +16,8 @@ Sentry.init({
tunnel: `http://localhost:3031/`, // proxy server
// Tracing is completely disabled

integrations: [Sentry.httpIntegration({ spans: true })],

// Custom OTEL setup
skipOpenTelemetrySetup: true,
});
Expand All @@ -37,5 +40,5 @@ provider.register({
});

registerInstrumentations({
instrumentations: [new UndiciInstrumentation()],
instrumentations: [new UndiciInstrumentation(), new HttpInstrumentation()],
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,24 @@ test('Sends correct error event', async ({ baseURL }) => {
span_id: expect.any(String),
});
});

test('Isolates requests correctly', async ({ baseURL }) => {
const errorEventPromise1 = waitForError('node-otel-without-tracing', event => {
return !event.type && event.exception?.values?.[0]?.value === 'This is an exception with id 555-a';
});
const errorEventPromise2 = waitForError('node-otel-without-tracing', event => {
return !event.type && event.exception?.values?.[0]?.value === 'This is an exception with id 555-b';
});

fetch(`${baseURL}/test-exception/555-a`);
fetch(`${baseURL}/test-exception/555-b`);

const errorEvent1 = await errorEventPromise1;
const errorEvent2 = await errorEventPromise2;

expect(errorEvent1.transaction).toEqual('GET /test-exception/555-a');
expect(errorEvent1.tags).toEqual({ 'root-level-tag': 'yes', 'param-555-a': '555-a' });

expect(errorEvent2.transaction).toEqual('GET /test-exception/555-b');
expect(errorEvent2.tags).toEqual({ 'root-level-tag': 'yes', 'param-555-b': '555-b' });
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@ test('Sends an API route transaction to OTLP', async ({ baseURL }) => {

const scopeSpans = json.resourceSpans?.[0]?.scopeSpans;

const httpScope = scopeSpans?.find(
scopeSpan => scopeSpan.scope.name === '@opentelemetry_sentry-patched/instrumentation-http',
);
const httpScope = scopeSpans?.find(scopeSpan => scopeSpan.scope.name === '@opentelemetry/instrumentation-http');

return (
httpScope &&
Expand All @@ -40,9 +38,7 @@ test('Sends an API route transaction to OTLP', async ({ baseURL }) => {
// But our default node-fetch spans are not emitted
expect(scopeSpans.length).toEqual(2);

const httpScopes = scopeSpans?.filter(
scopeSpan => scopeSpan.scope.name === '@opentelemetry_sentry-patched/instrumentation-http',
);
const httpScopes = scopeSpans?.filter(scopeSpan => scopeSpan.scope.name === '@opentelemetry/instrumentation-http');
const undiciScopes = scopeSpans?.filter(
scopeSpan => scopeSpan.scope.name === '@opentelemetry/instrumentation-undici',
);
Expand Down Expand Up @@ -114,7 +110,6 @@ test('Sends an API route transaction to OTLP', async ({ baseURL }) => {
{ key: 'net.peer.port', value: { intValue: expect.any(Number) } },
{ key: 'http.status_code', value: { intValue: 200 } },
{ key: 'http.status_text', value: { stringValue: 'OK' } },
{ key: 'sentry.origin', value: { stringValue: 'auto.http.otel.http' } },
]),
droppedAttributesCount: 0,
events: [],
Expand Down
Loading

0 comments on commit 97c18d3

Please sign in to comment.