Skip to content

Commit e8d71aa

Browse files
committed
feat(core): Add getTracingMetaTags function
1 parent 5f3f531 commit e8d71aa

File tree

6 files changed

+114
-0
lines changed

6 files changed

+114
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const { loggingTransport } = require('@sentry-internal/node-integration-tests');
2+
const Sentry = require('@sentry/node');
3+
4+
Sentry.init({
5+
dsn: 'https://public@dsn.ingest.sentry.io/1337',
6+
tracesSampleRate: 1.0,
7+
transport: loggingTransport,
8+
});
9+
10+
// express must be required after Sentry is initialized
11+
const express = require('express');
12+
const { startExpressServerAndSendPortToRunner } = require('@sentry-internal/node-integration-tests');
13+
14+
const app = express();
15+
16+
app.get('/test', (_req, res) => {
17+
res.send({
18+
response: `
19+
<html>
20+
<head>
21+
${Sentry.getTracingMetaTags()}
22+
</head>
23+
<body>
24+
Hi :)
25+
</body>
26+
</html>
27+
`,
28+
});
29+
});
30+
31+
Sentry.setupExpressErrorHandler(app);
32+
33+
startExpressServerAndSendPortToRunner(app);
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { cleanupChildProcesses, createRunner } from '../../../utils/runner';
2+
3+
describe('getTracingMetaTags', () => {
4+
afterAll(() => {
5+
cleanupChildProcesses();
6+
});
7+
8+
test('injects sentry tracing <meta> tags', async () => {
9+
const traceId = 'cd7ee7a6fe3ebe7ab9c3271559bc203c';
10+
const parentSpanId = '100ff0980e7a4ead';
11+
12+
const runner = createRunner(__dirname, 'server.js').start();
13+
14+
const response = await runner.makeRequest('get', '/test', {
15+
'sentry-trace': `${traceId}-${parentSpanId}-1`,
16+
baggage: 'sentry-environment=production',
17+
});
18+
19+
// @ts-expect-error - this is a string, types just don't work well
20+
const html = response?.response as string;
21+
22+
expect(html).toMatch(/<meta name="sentry-trace" content="cd7ee7a6fe3ebe7ab9c3271559bc203c-[a-z0-9]{16}-1"\/>/);
23+
expect(html).toContain('<meta name="baggage" content="sentry-environment=production"/>');
24+
});
25+
});

packages/core/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ export {
8383
export { parseSampleRate } from './utils/parseSampleRate';
8484
export { applySdkMetadata } from './utils/sdkMetadata';
8585
export { getTraceData } from './utils/traceData';
86+
export { getTracingMetaTags } from './utils/meta';
8687
export { DEFAULT_ENVIRONMENT } from './constants';
8788
export { addBreadcrumb } from './breadcrumbs';
8889
export { functionToStringIntegration } from './integrations/functiontostring';

packages/core/src/utils/meta.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { Client, Scope, Span } from '@sentry/types';
2+
import { getTraceData } from './traceData'; /**
3+
* Returns a string of meta tags that represent the tracing data.
4+
*
5+
* You can use this to propagate a trace from your server-side rendered Html to the browser.
6+
* Usage example:
7+
*
8+
* ```js
9+
* function renderHtml() {
10+
* return `
11+
* <head>
12+
* ${getTracingMetaTags()}
13+
* </head>
14+
* `;
15+
* }
16+
* ```
17+
*
18+
* @returns
19+
*/
20+
export function getTracingMetaTags(span?: Span, scope?: Scope, client?: Client): string {
21+
return Object.entries(getTraceData(span, scope, client))
22+
.map(([key, value]) => `<meta name="${key}" content="${value}"/>`)
23+
.join('\n');
24+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { getTracingMetaTags } from '../../../src/utils/meta';
2+
import * as TraceDataModule from '../../../src/utils/traceData';
3+
4+
describe('getTracingMetaTags', () => {
5+
it('renders baggage and sentry-trace values to stringified Html meta tags', () => {
6+
jest.spyOn(TraceDataModule, 'getTraceData').mockReturnValueOnce({
7+
'sentry-trace': '12345678901234567890123456789012-1234567890123456-1',
8+
baggage: 'sentry-environment=production',
9+
});
10+
11+
expect(getTracingMetaTags()).toBe(`<meta name="sentry-trace" content="12345678901234567890123456789012-1234567890123456-1"/>
12+
<meta name="baggage" content="sentry-environment=production"/>`);
13+
});
14+
15+
it('renders just sentry-trace values to stringified Html meta tags', () => {
16+
jest.spyOn(TraceDataModule, 'getTraceData').mockReturnValueOnce({
17+
'sentry-trace': '12345678901234567890123456789012-1234567890123456-1',
18+
});
19+
20+
expect(getTracingMetaTags()).toBe(
21+
'<meta name="sentry-trace" content="12345678901234567890123456789012-1234567890123456-1"/>',
22+
);
23+
});
24+
25+
it('returns an empty string if neither sentry-trace nor baggage values are available', () => {
26+
jest.spyOn(TraceDataModule, 'getTraceData').mockReturnValueOnce({});
27+
28+
expect(getTracingMetaTags()).toBe('');
29+
});
30+
});

packages/node/src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ export {
9696
getCurrentScope,
9797
getIsolationScope,
9898
getTraceData,
99+
getTracingMetaTags,
99100
withScope,
100101
withIsolationScope,
101102
captureException,

0 commit comments

Comments
 (0)