Skip to content
13 changes: 13 additions & 0 deletions static/app/components/onboarding/productSelection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ export const platformProductAvailability = {
],
'dotnet-xamarin': [ProductSolution.PERFORMANCE_MONITORING],
dart: [ProductSolution.PERFORMANCE_MONITORING, ProductSolution.LOGS],
elixir: [
ProductSolution.PERFORMANCE_MONITORING,
ProductSolution.LOGS,
ProductSolution.METRICS,
],
kotlin: [ProductSolution.PERFORMANCE_MONITORING],
go: [
ProductSolution.PERFORMANCE_MONITORING,
Expand Down Expand Up @@ -489,16 +494,24 @@ export const platformProductAvailability = {
ProductSolution.PERFORMANCE_MONITORING,
ProductSolution.PROFILING,
ProductSolution.LOGS,
ProductSolution.METRICS,
],
'ruby-rack': [
ProductSolution.PERFORMANCE_MONITORING,
ProductSolution.PROFILING,
ProductSolution.LOGS,
ProductSolution.METRICS,
],
'ruby-rails': [
ProductSolution.PERFORMANCE_MONITORING,
ProductSolution.PROFILING,
ProductSolution.LOGS,
ProductSolution.METRICS,
],
rust: [
ProductSolution.PERFORMANCE_MONITORING,
ProductSolution.LOGS,
ProductSolution.METRICS,
],
unity: [ProductSolution.LOGS, ProductSolution.METRICS],
unreal: [ProductSolution.LOGS],
Expand Down
3 changes: 2 additions & 1 deletion static/app/data/platformCategories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,6 @@ export const withPerformanceOnboarding = new Set<PlatformKey>([
// List of platforms that do not have performance support. We make use of this list in the product to not provide any Performance
// views such as Performance onboarding checklist.
export const withoutPerformanceSupport = new Set<PlatformKey>([
'elixir',
'minidump',
'nintendo-switch',
'playstation',
Expand Down Expand Up @@ -495,6 +494,8 @@ export const withMetricsOnboarding = new Set<PlatformKey>([
'ruby',
'ruby-rack',
'ruby-rails',
'rust',
'elixir',
'unity',
]);

Expand Down
2 changes: 2 additions & 0 deletions static/app/gettingStartedDocs/elixir/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types';
import {crashReport} from 'sentry/gettingStartedDocs/elixir/crashReport';
import {logs} from 'sentry/gettingStartedDocs/elixir/logs';
import {metrics} from 'sentry/gettingStartedDocs/elixir/metrics';
import {onboarding} from 'sentry/gettingStartedDocs/elixir/onboarding';
import {
feedbackOnboardingJsLoader,
Expand All @@ -13,4 +14,5 @@ export const docs: Docs = {
crashReportOnboarding: crashReport,
feedbackOnboardingJsLoader,
logsOnboarding: logs,
metricsOnboarding: metrics,
};
28 changes: 28 additions & 0 deletions static/app/gettingStartedDocs/elixir/metrics.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const {metrics: elixirMetrics} = jest.requireActual(
'sentry/gettingStartedDocs/elixir/metrics'
);

describe('metrics', () => {
const mockParams = {
dsn: {
public: 'https://test@example.com/123',
},
};

it('generates metrics onboarding config', () => {
const installSteps = elixirMetrics.install();
expect(installSteps).toHaveLength(1);
expect(installSteps[0].type).toBe('install');

const verifySteps = elixirMetrics.verify(mockParams);
expect(verifySteps).toHaveLength(1);
expect(verifySteps[0].type).toBe('verify');

const codeSnippet = verifySteps[0].content[1].code;
expect(codeSnippet).toContain('Sentry.init');
expect(codeSnippet).toContain(mockParams.dsn.public);
expect(codeSnippet).toContain('Sentry.Metrics.count');
expect(codeSnippet).toContain('Sentry.Metrics.gauge');
expect(codeSnippet).toContain('Sentry.Metrics.distribution');
});
});
106 changes: 106 additions & 0 deletions static/app/gettingStartedDocs/elixir/metrics.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import {ExternalLink} from '@sentry/scraps/link';

import type {
DocsParams,
OnboardingConfig,
} from 'sentry/components/onboarding/gettingStartedDoc/types';
import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/types';
import {tct} from 'sentry/locale';

const getInstallSnippet = () => `
defp deps do
[
# ...
{:sentry, "~> 13.0"},
{:jason, "~> 1.2"},
{:hackney, "~> 1.8"}
]
end`;

const getVerifySnippet = (params: DocsParams) => `
Sentry.init(
dsn: "${params.dsn.public}",
environment_name: Mix.env()
)

# Counter metric
Sentry.Metrics.count(
"button_click",
5,
attributes: %{browser: "Firefox", app_version: "1.0.0"}
)

# Gauge metric
Sentry.Metrics.gauge(
"page_load",
15.0,
unit: "millisecond",
attributes: %{page: "/home"}
)

# Distribution metric
Sentry.Metrics.distribution(
"page_load",
15.0,
unit: "millisecond",
attributes: %{page: "/home"}
)`;

export const metrics: OnboardingConfig = {
install: () => [
{
type: StepType.INSTALL,
content: [
{
type: 'text',
text: tct(
'Metrics are supported in Sentry Elixir SDK version [code:13.0.0] and above. Make sure your [code:mix.exs] specifies at least this version:',
{code: <code />}
),
},
{
type: 'code',
language: 'elixir',
code: getInstallSnippet(),
},
{
type: 'text',
text: tct('Then fetch the updated dependency: [code:mix deps.get]', {
code: <code />,
}),
},
],
},
],
configure: () => [],
verify: params => [
{
type: StepType.VERIFY,
content: [
{
type: 'text',
text: tct(
'Metrics are automatically enabled. You can emit metrics using the [code:Sentry.Metrics] module.',
{code: <code />}
),
},
{
type: 'code',
language: 'elixir',
code: getVerifySnippet(params),
},
{
type: 'text',
text: tct(
'For more detailed information, see the [link:metrics documentation].',
{
link: (
<ExternalLink href="https://docs.sentry.io/platforms/elixir/metrics/" />
),
}
),
},
],
},
],
};
15 changes: 14 additions & 1 deletion static/app/gettingStartedDocs/elixir/onboarding.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,20 @@ const getConfigureSnippet = (params: DocsParams) => `
dsn: "${params.dsn.public}",
environment_name: Mix.env(),
enable_source_code_context: true,
root_source_code_paths: [File.cwd!()]`;
root_source_code_paths: [File.cwd!()]${
params.isPerformanceSelected
? `,
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for tracing.
traces_sample_rate: 1.0`
: ''
}${
params.isLogsSelected
? `,
# Enable sending logs to Sentry
enable_logs: true`
: ''
}`;

const getPlugSnippet = () => `
defmodule MyAppWeb.Endpoint
Expand Down
30 changes: 30 additions & 0 deletions static/app/gettingStartedDocs/ruby/metrics.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
const {metrics: rubyMetrics} = jest.requireActual(
'sentry/gettingStartedDocs/ruby/metrics'
);

describe('metrics', () => {
const mockParams = {
dsn: {
public: 'https://test@example.com/123',
},
};

it('generates metrics onboarding config', () => {
const config = rubyMetrics({docsPlatform: 'ruby'});

const installSteps = config.install();
expect(installSteps).toHaveLength(1);
expect(installSteps[0].type).toBe('install');

const verifySteps = config.verify(mockParams);
expect(verifySteps).toHaveLength(1);
expect(verifySteps[0].type).toBe('verify');

const codeSnippet = verifySteps[0].content[1].code;
expect(codeSnippet).toContain('Sentry.init');
expect(codeSnippet).toContain(mockParams.dsn.public);
expect(codeSnippet).toContain('Sentry.metrics.count');
expect(codeSnippet).toContain('Sentry.metrics.gauge');
expect(codeSnippet).toContain('Sentry.metrics.distribution');
});
});
23 changes: 20 additions & 3 deletions static/app/gettingStartedDocs/ruby/metrics.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,30 @@ export const metrics = <
end

# Counter metric
Sentry::Metrics.count('test-counter', value: 10, attributes: { my_attribute: 'foo'})
Sentry.metrics.count('button_click', value: 5, attributes: { browser: 'Firefox', app_version: '1.0.0' })

# Gauge metric
Sentry::Metrics.gauge('test-gauge', 50.0, unit: 'millisecond', attributes: { my_attribute: 'foo' })
Sentry.metrics.gauge('page_load', 15.0, unit: 'millisecond', attributes: { page: '/home' })

# Distribution metric
Sentry::Metrics.distribution('test-distribution', 20.0, unit: 'kilobyte', attributes: { my_attribute: 'foo' })`,
Sentry.metrics.distribution('page_load', 15.0, unit: 'millisecond', attributes: { page: '/home' })`,
},
{
type: 'text',
text: tct(
'For more detailed information, see the [link:metrics documentation].',
{
link: (
<ExternalLink
href={
docsPlatform === 'ruby'
? 'https://docs.sentry.io/platforms/ruby/metrics/'
: `https://docs.sentry.io/platforms/ruby/guides/${docsPlatform}/metrics/`
}
/>
),
}
),
},
],
},
Expand Down
2 changes: 2 additions & 0 deletions static/app/gettingStartedDocs/rust/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import type {Docs} from 'sentry/components/onboarding/gettingStartedDoc/types';

import {crashReport} from './crashReport';
import {logs} from './logs';
import {metrics} from './metrics';
import {onboarding} from './onboarding';

export const docs: Docs = {
onboarding,
crashReportOnboarding: crashReport,
logsOnboarding: logs,
metricsOnboarding: metrics,
};
28 changes: 28 additions & 0 deletions static/app/gettingStartedDocs/rust/metrics.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const {metrics: rustMetrics} = jest.requireActual(
'sentry/gettingStartedDocs/rust/metrics'
);

describe('metrics', () => {
const mockParams = {
dsn: {
public: 'https://test@example.com/123',
},
};

it('generates metrics onboarding config', () => {
const installSteps = rustMetrics.install();
expect(installSteps).toHaveLength(1);
expect(installSteps[0].type).toBe('install');

const verifySteps = rustMetrics.verify(mockParams);
expect(verifySteps).toHaveLength(1);
expect(verifySteps[0].type).toBe('verify');

const codeSnippet = verifySteps[0].content[1].code;
expect(codeSnippet).toContain('sentry::init');
expect(codeSnippet).toContain(mockParams.dsn.public);
expect(codeSnippet).toContain('metrics::counter');
expect(codeSnippet).toContain('metrics::gauge');
expect(codeSnippet).toContain('metrics::distribution');
});
});
Loading
Loading