Skip to content

Commit 95f0c87

Browse files
AbhiPrasadshashjar
authored andcommitted
feat(settings): Add vercel log drain endpoint to project key settings (#102155)
Cannot be merged before getsentry/sentry-docs#15322 merges in. This PR adds the vercel drain config to the dsn settings. This is for both traces (via OTLP) and logs (via the vercel log drain endpoint).
1 parent cad2f6d commit 95f0c87

File tree

10 files changed

+266
-130
lines changed

10 files changed

+266
-130
lines changed

static/app/types/project.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ export type ProjectKey = {
112112
cdn: string;
113113
crons: string;
114114
csp: string;
115+
integration: string;
115116
minidump: string;
116117
otlp_logs: string;
117118
otlp_traces: string;

static/app/views/settings/project/loaderScript.spec.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ describe('LoaderScript', () => {
109109
crons: '',
110110
playstation:
111111
'http://dev.getsentry.net:8000/api/1/playstation?sentry_key=188ee45a58094d939428d8585aa6f662',
112+
integration: 'http://dev.getsentry.net:8000/api/1/integration/',
112113
otlp_traces: 'http://dev.getsentry.net:8000/api/1/integration/otlp/v1/traces',
113114
otlp_logs: 'http://dev.getsentry.net:8000/api/1/integration/otlp/v1/logs',
114115
},
@@ -257,6 +258,7 @@ describe('LoaderScript', () => {
257258
crons: '',
258259
playstation:
259260
'http://dev.getsentry.net:8000/api/1/playstation?sentry_key=188ee45a58094d939428d8585aa6f662',
261+
integration: 'http://dev.getsentry.net:8000/api/1/integration/',
260262
otlp_traces: 'http://dev.getsentry.net:8000/api/1/integration/otlp/v1/traces',
261263
otlp_logs: 'http://dev.getsentry.net:8000/api/1/integration/otlp/v1/logs',
262264
},

static/app/views/settings/project/projectKeys/projectKeyCredentials.tsx renamed to static/app/views/settings/project/projectKeys/credentials/index.tsx

Lines changed: 21 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import {Fragment, useMemo} from 'react';
22
import styled from '@emotion/styled';
33

4-
import {CodeBlock} from 'sentry/components/core/code/codeBlock';
54
import {ExternalLink, Link} from 'sentry/components/core/link';
65
import {TabList, Tabs} from 'sentry/components/core/tabs';
76
import FieldGroup from 'sentry/components/forms/fieldGroup';
@@ -11,6 +10,8 @@ import type {ProjectKey} from 'sentry/types/project';
1110
import {decodeScalar} from 'sentry/utils/queryString';
1211
import {useLocation} from 'sentry/utils/useLocation';
1312
import {useNavigate} from 'sentry/utils/useNavigate';
13+
import {OtlpTab} from 'sentry/views/settings/project/projectKeys/credentials/otlp';
14+
import {VercelTab} from 'sentry/views/settings/project/projectKeys/credentials/vercel';
1415

1516
type Props = {
1617
data: ProjectKey;
@@ -25,142 +26,17 @@ type Props = {
2526
showSecretKey?: boolean;
2627
showSecurityEndpoint?: boolean;
2728
showUnreal?: boolean;
29+
showVercelLogDrainEndpoint?: boolean;
2830
};
2931

30-
type TabValue = 'otlp' | 'security' | 'minidump' | 'unreal' | 'credentials';
32+
type TabValue = 'otlp' | 'security' | 'minidump' | 'unreal' | 'vercel' | 'credentials';
3133

3234
interface TabConfig {
3335
key: TabValue;
3436
label: string;
3537
visible: boolean;
3638
}
3739

38-
interface OtlpTabProps {
39-
logsEndpoint: string;
40-
publicKey: string;
41-
showOtlpLogs: boolean;
42-
showOtlpTraces: boolean;
43-
tracesEndpoint: string;
44-
}
45-
46-
function OtlpTab({
47-
logsEndpoint,
48-
tracesEndpoint,
49-
publicKey,
50-
showOtlpLogs,
51-
showOtlpTraces,
52-
}: OtlpTabProps) {
53-
// Build the OTEL collector config example
54-
const buildCollectorConfig = useMemo(() => {
55-
const lines = ['exporters:', ' otlphttp:'];
56-
57-
if (showOtlpLogs) {
58-
lines.push(` logs_endpoint: ${logsEndpoint}`);
59-
}
60-
61-
if (showOtlpTraces) {
62-
lines.push(` traces_endpoint: ${tracesEndpoint}`);
63-
}
64-
65-
lines.push(
66-
' headers:',
67-
` x-sentry-auth: "sentry sentry_key=${publicKey}"`,
68-
' compression: gzip',
69-
' encoding: proto',
70-
' timeout: 30s'
71-
);
72-
73-
return lines.join('\n');
74-
}, [showOtlpLogs, showOtlpTraces, logsEndpoint, tracesEndpoint, publicKey]);
75-
76-
if (!showOtlpLogs && !showOtlpTraces) {
77-
return undefined;
78-
}
79-
80-
return (
81-
<Fragment>
82-
{showOtlpLogs && (
83-
<Fragment>
84-
<FieldGroup
85-
label={t('OTLP Logs Endpoint')}
86-
help={tct(
87-
`Set this URL as your OTLP exporter's log endpoint. [link:Learn more]`,
88-
{
89-
link: (
90-
<ExternalLink href="https://docs.sentry.io/concepts/otlp/#opentelemetry-logs" />
91-
),
92-
}
93-
)}
94-
inline={false}
95-
flexibleControlStateSize
96-
>
97-
<TextCopyInput aria-label={t('OTLP Logs Endpoint')}>
98-
{logsEndpoint}
99-
</TextCopyInput>
100-
</FieldGroup>
101-
102-
<FieldGroup
103-
label={t('OTLP Logs Endpoint Headers')}
104-
help={t(`Set these security headers when configuring your OTLP exporter.`)}
105-
inline={false}
106-
flexibleControlStateSize
107-
>
108-
<TextCopyInput aria-label={t('OTLP Logs Endpoint Headers')}>
109-
{`x-sentry-auth=sentry sentry_key=${publicKey}`}
110-
</TextCopyInput>
111-
</FieldGroup>
112-
</Fragment>
113-
)}
114-
115-
{showOtlpTraces && (
116-
<Fragment>
117-
<FieldGroup
118-
label={t('OTLP Traces Endpoint')}
119-
help={tct(
120-
`Set this URL as your OTLP exporter's trace endpoint. [link:Learn more]`,
121-
{
122-
link: (
123-
<ExternalLink href="https://docs.sentry.io/concepts/otlp/#opentelemetry-traces" />
124-
),
125-
}
126-
)}
127-
inline={false}
128-
flexibleControlStateSize
129-
>
130-
<TextCopyInput aria-label={t('OTLP Traces Endpoint')}>
131-
{tracesEndpoint}
132-
</TextCopyInput>
133-
</FieldGroup>
134-
135-
<FieldGroup
136-
label={t('OTLP Traces Endpoint Headers')}
137-
help={t(`Set these security headers when configuring your OTLP exporter.`)}
138-
inline={false}
139-
flexibleControlStateSize
140-
>
141-
<TextCopyInput aria-label={t('OTLP Traces Endpoint Headers')}>
142-
{`x-sentry-auth=sentry sentry_key=${publicKey}`}
143-
</TextCopyInput>
144-
</FieldGroup>
145-
</Fragment>
146-
)}
147-
148-
<FieldGroup
149-
label={t('OpenTelemetry Collector Exporter Configuration')}
150-
help={t(
151-
'Use this example configuration in your OpenTelemetry Collector config file to export OTLP data to Sentry.'
152-
)}
153-
inline={false}
154-
flexibleControlStateSize
155-
>
156-
<CodeBlock language="yaml" filename="config.yaml">
157-
{buildCollectorConfig}
158-
</CodeBlock>
159-
</FieldGroup>
160-
</Fragment>
161-
);
162-
}
163-
16440
interface SecurityTabProps {
16541
securityEndpoint: string;
16642
}
@@ -299,6 +175,7 @@ function ProjectKeyCredentials({
299175
showSecretKey = false,
300176
showOtlpTraces = false,
301177
showOtlpLogs = false,
178+
showVercelLogDrainEndpoint = false,
302179
showSecurityEndpoint = true,
303180
showUnreal = true,
304181
}: Props) {
@@ -333,12 +210,18 @@ function ProjectKeyCredentials({
333210
label: t('Unreal Engine'),
334211
visible: showUnreal,
335212
},
213+
{
214+
key: 'vercel',
215+
label: t('Vercel Drains'),
216+
visible: showVercelLogDrainEndpoint || showOtlpTraces,
217+
},
336218
];
337219
return tabs.filter(tab => tab.visible);
338220
}, [
339221
showOtlpTraces,
340222
showOtlpLogs,
341223
showSecurityEndpoint,
224+
showVercelLogDrainEndpoint,
342225
showMinidump,
343226
showUnreal,
344227
showPublicKey,
@@ -399,6 +282,16 @@ function ProjectKeyCredentials({
399282
showProjectId={showProjectId}
400283
/>
401284
);
285+
case 'vercel':
286+
return (
287+
<VercelTab
288+
showVercelLogDrainEndpoint={showVercelLogDrainEndpoint}
289+
integrationEndpoint={data.dsn.integration}
290+
publicKey={data.public}
291+
showOtlpTraces={showOtlpTraces}
292+
tracesEndpoint={data.dsn.otlp_traces}
293+
/>
294+
);
402295
default:
403296
return undefined;
404297
}
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import {Fragment, useMemo} from 'react';
2+
3+
import {CodeBlock} from '@sentry/scraps/code';
4+
5+
import {ExternalLink} from 'sentry/components/core/link';
6+
import FieldGroup from 'sentry/components/forms/fieldGroup';
7+
import TextCopyInput from 'sentry/components/textCopyInput';
8+
import {t, tct} from 'sentry/locale';
9+
10+
interface OtlpTabProps {
11+
logsEndpoint: string;
12+
publicKey: string;
13+
showOtlpLogs: boolean;
14+
showOtlpTraces: boolean;
15+
tracesEndpoint: string;
16+
}
17+
18+
export function OtlpTab({
19+
logsEndpoint,
20+
tracesEndpoint,
21+
publicKey,
22+
showOtlpLogs,
23+
showOtlpTraces,
24+
}: OtlpTabProps) {
25+
// Build the OTEL collector config example
26+
const buildCollectorConfig = useMemo(() => {
27+
const lines = ['exporters:', ' otlphttp:'];
28+
29+
if (showOtlpLogs) {
30+
lines.push(` logs_endpoint: ${logsEndpoint}`);
31+
}
32+
33+
if (showOtlpTraces) {
34+
lines.push(` traces_endpoint: ${tracesEndpoint}`);
35+
}
36+
37+
lines.push(
38+
' headers:',
39+
` x-sentry-auth: "sentry sentry_key=${publicKey}"`,
40+
' compression: gzip',
41+
' encoding: proto',
42+
' timeout: 30s'
43+
);
44+
45+
return lines.join('\n');
46+
}, [showOtlpLogs, showOtlpTraces, logsEndpoint, tracesEndpoint, publicKey]);
47+
48+
if (!showOtlpLogs && !showOtlpTraces) {
49+
return undefined;
50+
}
51+
52+
return (
53+
<Fragment>
54+
{showOtlpLogs && (
55+
<Fragment>
56+
<FieldGroup
57+
label={t('OTLP Logs Endpoint')}
58+
help={tct(
59+
`Set this URL as your OTLP exporter's log endpoint. [link:Learn more]`,
60+
{
61+
link: (
62+
<ExternalLink href="https://docs.sentry.io/concepts/otlp/#opentelemetry-logs" />
63+
),
64+
}
65+
)}
66+
inline={false}
67+
flexibleControlStateSize
68+
>
69+
<TextCopyInput aria-label={t('OTLP Logs Endpoint')}>
70+
{logsEndpoint}
71+
</TextCopyInput>
72+
</FieldGroup>
73+
74+
<FieldGroup
75+
label={t('OTLP Logs Endpoint Headers')}
76+
help={t(`Set these security headers when configuring your OTLP exporter.`)}
77+
inline={false}
78+
flexibleControlStateSize
79+
>
80+
<TextCopyInput aria-label={t('OTLP Logs Endpoint Headers')}>
81+
{`x-sentry-auth=sentry sentry_key=${publicKey}`}
82+
</TextCopyInput>
83+
</FieldGroup>
84+
</Fragment>
85+
)}
86+
87+
{showOtlpTraces && (
88+
<Fragment>
89+
<FieldGroup
90+
label={t('OTLP Traces Endpoint')}
91+
help={tct(
92+
`Set this URL as your OTLP exporter's trace endpoint. [link:Learn more]`,
93+
{
94+
link: (
95+
<ExternalLink href="https://docs.sentry.io/concepts/otlp/#opentelemetry-traces" />
96+
),
97+
}
98+
)}
99+
inline={false}
100+
flexibleControlStateSize
101+
>
102+
<TextCopyInput aria-label={t('OTLP Traces Endpoint')}>
103+
{tracesEndpoint}
104+
</TextCopyInput>
105+
</FieldGroup>
106+
107+
<FieldGroup
108+
label={t('OTLP Traces Endpoint Headers')}
109+
help={t(`Set these security headers when configuring your OTLP exporter.`)}
110+
inline={false}
111+
flexibleControlStateSize
112+
>
113+
<TextCopyInput aria-label={t('OTLP Traces Endpoint Headers')}>
114+
{`x-sentry-auth=sentry sentry_key=${publicKey}`}
115+
</TextCopyInput>
116+
</FieldGroup>
117+
</Fragment>
118+
)}
119+
120+
<FieldGroup
121+
label={t('OpenTelemetry Collector Exporter Configuration')}
122+
help={t(
123+
'Use this example configuration in your OpenTelemetry Collector config file to export OTLP data to Sentry.'
124+
)}
125+
inline={false}
126+
flexibleControlStateSize
127+
>
128+
<CodeBlock language="yaml" filename="config.yaml">
129+
{buildCollectorConfig}
130+
</CodeBlock>
131+
</FieldGroup>
132+
</Fragment>
133+
);
134+
}

0 commit comments

Comments
 (0)