Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
1 change: 1 addition & 0 deletions static/app/types/project.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ export type ProjectKey = {
cdn: string;
crons: string;
csp: string;
integration: string;
minidump: string;
otlp_logs: string;
otlp_traces: string;
Expand Down
2 changes: 2 additions & 0 deletions static/app/views/settings/project/loaderScript.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ describe('LoaderScript', () => {
crons: '',
playstation:
'http://dev.getsentry.net:8000/api/1/playstation?sentry_key=188ee45a58094d939428d8585aa6f662',
integration: 'http://dev.getsentry.net:8000/api/1/integration/',
otlp_traces: 'http://dev.getsentry.net:8000/api/1/integration/otlp/v1/traces',
otlp_logs: 'http://dev.getsentry.net:8000/api/1/integration/otlp/v1/logs',
},
Expand Down Expand Up @@ -242,6 +243,7 @@ describe('LoaderScript', () => {
crons: '',
playstation:
'http://dev.getsentry.net:8000/api/1/playstation?sentry_key=188ee45a58094d939428d8585aa6f662',
integration: 'http://dev.getsentry.net:8000/api/1/integration/',
otlp_traces: 'http://dev.getsentry.net:8000/api/1/integration/otlp/v1/traces',
otlp_logs: 'http://dev.getsentry.net:8000/api/1/integration/otlp/v1/logs',
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {Fragment, useMemo} from 'react';
import styled from '@emotion/styled';

import {CodeBlock} from 'sentry/components/core/code/codeBlock';
import {ExternalLink, Link} from 'sentry/components/core/link';
import {TabList, Tabs} from 'sentry/components/core/tabs';
import FieldGroup from 'sentry/components/forms/fieldGroup';
Expand All @@ -11,6 +10,8 @@ import type {ProjectKey} from 'sentry/types/project';
import {decodeScalar} from 'sentry/utils/queryString';
import {useLocation} from 'sentry/utils/useLocation';
import {useNavigate} from 'sentry/utils/useNavigate';
import {OtlpTab} from 'sentry/views/settings/project/projectKeys/credentials/otlp';
import {VercelTab} from 'sentry/views/settings/project/projectKeys/credentials/vercel';

type Props = {
data: ProjectKey;
Expand All @@ -25,142 +26,17 @@ type Props = {
showSecretKey?: boolean;
showSecurityEndpoint?: boolean;
showUnreal?: boolean;
showVercelLogDrainEndpoint?: boolean;
};

type TabValue = 'otlp' | 'security' | 'minidump' | 'unreal' | 'credentials';
type TabValue = 'otlp' | 'security' | 'minidump' | 'unreal' | 'vercel' | 'credentials';

interface TabConfig {
key: TabValue;
label: string;
visible: boolean;
}

interface OtlpTabProps {
logsEndpoint: string;
publicKey: string;
showOtlpLogs: boolean;
showOtlpTraces: boolean;
tracesEndpoint: string;
}

function OtlpTab({
logsEndpoint,
tracesEndpoint,
publicKey,
showOtlpLogs,
showOtlpTraces,
}: OtlpTabProps) {
// Build the OTEL collector config example
const buildCollectorConfig = useMemo(() => {
const lines = ['exporters:', ' otlphttp:'];

if (showOtlpLogs) {
lines.push(` logs_endpoint: ${logsEndpoint}`);
}

if (showOtlpTraces) {
lines.push(` traces_endpoint: ${tracesEndpoint}`);
}

lines.push(
' headers:',
` x-sentry-auth: "sentry sentry_key=${publicKey}"`,
' compression: gzip',
' encoding: proto',
' timeout: 30s'
);

return lines.join('\n');
}, [showOtlpLogs, showOtlpTraces, logsEndpoint, tracesEndpoint, publicKey]);

if (!showOtlpLogs && !showOtlpTraces) {
return undefined;
}

return (
<Fragment>
{showOtlpLogs && (
<Fragment>
<FieldGroup
label={t('OTLP Logs Endpoint')}
help={tct(
`Set this URL as your OTLP exporter's log endpoint. [link:Learn more]`,
{
link: (
<ExternalLink href="https://docs.sentry.io/concepts/otlp/#opentelemetry-logs" />
),
}
)}
inline={false}
flexibleControlStateSize
>
<TextCopyInput aria-label={t('OTLP Logs Endpoint')}>
{logsEndpoint}
</TextCopyInput>
</FieldGroup>

<FieldGroup
label={t('OTLP Logs Endpoint Headers')}
help={t(`Set these security headers when configuring your OTLP exporter.`)}
inline={false}
flexibleControlStateSize
>
<TextCopyInput aria-label={t('OTLP Logs Endpoint Headers')}>
{`x-sentry-auth=sentry sentry_key=${publicKey}`}
</TextCopyInput>
</FieldGroup>
</Fragment>
)}

{showOtlpTraces && (
<Fragment>
<FieldGroup
label={t('OTLP Traces Endpoint')}
help={tct(
`Set this URL as your OTLP exporter's trace endpoint. [link:Learn more]`,
{
link: (
<ExternalLink href="https://docs.sentry.io/concepts/otlp/#opentelemetry-traces" />
),
}
)}
inline={false}
flexibleControlStateSize
>
<TextCopyInput aria-label={t('OTLP Traces Endpoint')}>
{tracesEndpoint}
</TextCopyInput>
</FieldGroup>

<FieldGroup
label={t('OTLP Traces Endpoint Headers')}
help={t(`Set these security headers when configuring your OTLP exporter.`)}
inline={false}
flexibleControlStateSize
>
<TextCopyInput aria-label={t('OTLP Traces Endpoint Headers')}>
{`x-sentry-auth=sentry sentry_key=${publicKey}`}
</TextCopyInput>
</FieldGroup>
</Fragment>
)}

<FieldGroup
label={t('OpenTelemetry Collector Exporter Configuration')}
help={t(
'Use this example configuration in your OpenTelemetry Collector config file to export OTLP data to Sentry.'
)}
inline={false}
flexibleControlStateSize
>
<CodeBlock language="yaml" filename="config.yaml">
{buildCollectorConfig}
</CodeBlock>
</FieldGroup>
</Fragment>
);
}

interface SecurityTabProps {
securityEndpoint: string;
}
Expand Down Expand Up @@ -299,6 +175,7 @@ function ProjectKeyCredentials({
showSecretKey = false,
showOtlpTraces = false,
showOtlpLogs = false,
showVercelLogDrainEndpoint = false,
showSecurityEndpoint = true,
showUnreal = true,
}: Props) {
Expand Down Expand Up @@ -333,12 +210,18 @@ function ProjectKeyCredentials({
label: t('Unreal Engine'),
visible: showUnreal,
},
{
key: 'vercel',
label: t('Vercel Log Drain'),
visible: showVercelLogDrainEndpoint || showOtlpTraces,
},
];
return tabs.filter(tab => tab.visible);
}, [
showOtlpTraces,
showOtlpLogs,
showSecurityEndpoint,
showVercelLogDrainEndpoint,
showMinidump,
showUnreal,
showPublicKey,
Expand Down Expand Up @@ -399,6 +282,16 @@ function ProjectKeyCredentials({
showProjectId={showProjectId}
/>
);
case 'vercel':
return (
<VercelTab
showVercelLogDrainEndpoint={showVercelLogDrainEndpoint}
integrationEndpoint={data.dsn.integration}
publicKey={data.public}
showOtlpTraces={showOtlpTraces}
tracesEndpoint={data.dsn.otlp_traces}
/>
);
default:
return undefined;
}
Expand Down
134 changes: 134 additions & 0 deletions static/app/views/settings/project/projectKeys/credentials/otlp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import {Fragment, useMemo} from 'react';

import {CodeBlock} from '@sentry/scraps/code';

import {ExternalLink} from 'sentry/components/core/link';
import FieldGroup from 'sentry/components/forms/fieldGroup';
import TextCopyInput from 'sentry/components/textCopyInput';
import {t, tct} from 'sentry/locale';

interface OtlpTabProps {
logsEndpoint: string;
publicKey: string;
showOtlpLogs: boolean;
showOtlpTraces: boolean;
tracesEndpoint: string;
}

export function OtlpTab({
logsEndpoint,
tracesEndpoint,
publicKey,
showOtlpLogs,
showOtlpTraces,
}: OtlpTabProps) {
// Build the OTEL collector config example
const buildCollectorConfig = useMemo(() => {
const lines = ['exporters:', ' otlphttp:'];

if (showOtlpLogs) {
lines.push(` logs_endpoint: ${logsEndpoint}`);
}

if (showOtlpTraces) {
lines.push(` traces_endpoint: ${tracesEndpoint}`);
}

lines.push(
' headers:',
` x-sentry-auth: "sentry sentry_key=${publicKey}"`,
' compression: gzip',
' encoding: proto',
' timeout: 30s'
);

return lines.join('\n');
}, [showOtlpLogs, showOtlpTraces, logsEndpoint, tracesEndpoint, publicKey]);

if (!showOtlpLogs && !showOtlpTraces) {
return undefined;
}

return (
<Fragment>
{showOtlpLogs && (
<Fragment>
<FieldGroup
label={t('OTLP Logs Endpoint')}
help={tct(
`Set this URL as your OTLP exporter's log endpoint. [link:Learn more]`,
{
link: (
<ExternalLink href="https://docs.sentry.io/concepts/otlp/#opentelemetry-logs" />
),
}
)}
inline={false}
flexibleControlStateSize
>
<TextCopyInput aria-label={t('OTLP Logs Endpoint')}>
{logsEndpoint}
</TextCopyInput>
</FieldGroup>

<FieldGroup
label={t('OTLP Logs Endpoint Headers')}
help={t(`Set these security headers when configuring your OTLP exporter.`)}
inline={false}
flexibleControlStateSize
>
<TextCopyInput aria-label={t('OTLP Logs Endpoint Headers')}>
{`x-sentry-auth=sentry sentry_key=${publicKey}`}
</TextCopyInput>
</FieldGroup>
</Fragment>
)}

{showOtlpTraces && (
<Fragment>
<FieldGroup
label={t('OTLP Traces Endpoint')}
help={tct(
`Set this URL as your OTLP exporter's trace endpoint. [link:Learn more]`,
{
link: (
<ExternalLink href="https://docs.sentry.io/concepts/otlp/#opentelemetry-traces" />
),
}
)}
inline={false}
flexibleControlStateSize
>
<TextCopyInput aria-label={t('OTLP Traces Endpoint')}>
{tracesEndpoint}
</TextCopyInput>
</FieldGroup>

<FieldGroup
label={t('OTLP Traces Endpoint Headers')}
help={t(`Set these security headers when configuring your OTLP exporter.`)}
inline={false}
flexibleControlStateSize
>
<TextCopyInput aria-label={t('OTLP Traces Endpoint Headers')}>
{`x-sentry-auth=sentry sentry_key=${publicKey}`}
</TextCopyInput>
</FieldGroup>
</Fragment>
)}

<FieldGroup
label={t('OpenTelemetry Collector Exporter Configuration')}
help={t(
'Use this example configuration in your OpenTelemetry Collector config file to export OTLP data to Sentry.'
)}
inline={false}
flexibleControlStateSize
>
<CodeBlock language="yaml" filename="config.yaml">
{buildCollectorConfig}
</CodeBlock>
</FieldGroup>
</Fragment>
);
}
Loading
Loading