Browse Source

feat(ddm): Add rust onboarding (#62075)

Refactor rust docs to new structure.
Add metrics onboarding docs for all rust platform.

- part of https://github.com/getsentry/sentry/issues/60250
ArthurKnaus 1 year ago
parent
commit
0fe5f92ca5

+ 1 - 2
static/app/data/platformCategories.tsx

@@ -437,7 +437,6 @@ export const customMetricOnboardingPlatforms = new Set(
       ) &&
       // TODO: Remove this once we have onboarding instructions for these platforms
       !p.includes('php') &&
-      !p.includes('python') &&
-      p !== 'rust'
+      !p.includes('python')
   )
 );

+ 21 - 12
static/app/gettingStartedDocs/rust/rust.spec.tsx

@@ -1,18 +1,27 @@
-import {render, screen} from 'sentry-test/reactTestingLibrary';
+import {renderWithOnboardingLayout} from 'sentry-test/onboarding/renderWithOnboardingLayout';
+import {screen} from 'sentry-test/reactTestingLibrary';
+import {textWithMarkupMatcher} from 'sentry-test/utils';
 
-import {StepTitle} from 'sentry/components/onboarding/gettingStartedDoc/step';
+import docs from './rust';
 
-import {GettingStartedWithRust, steps} from './rust';
+describe('rust onboarding docs', function () {
+  it('renders onboarding docs correctly', async () => {
+    renderWithOnboardingLayout(docs, {
+      releaseRegistry: {
+        'sentry.rust': {
+          version: '1.99.9',
+        },
+      },
+    });
 
-describe('GettingStartedWithRust', function () {
-  it('renders doc correctly', function () {
-    render(<GettingStartedWithRust dsn="test-dsn" projectSlug="test-project" />);
+    // Renders main headings
+    expect(screen.getByRole('heading', {name: 'Install'})).toBeInTheDocument();
+    expect(screen.getByRole('heading', {name: 'Configure SDK'})).toBeInTheDocument();
+    expect(screen.getByRole('heading', {name: 'Verify'})).toBeInTheDocument();
 
-    // Steps
-    for (const step of steps()) {
-      expect(
-        screen.getByRole('heading', {name: step.title ?? StepTitle[step.type]})
-      ).toBeInTheDocument();
-    }
+    // Renders SDK version from registry
+    expect(
+      await screen.findByText(textWithMarkupMatcher(/sentry = "1\.99\.9"/))
+    ).toBeInTheDocument();
   });
 });

+ 151 - 78
static/app/gettingStartedDocs/rust/rust.tsx

@@ -1,93 +1,166 @@
-import {Layout, LayoutProps} from 'sentry/components/onboarding/gettingStartedDoc/layout';
-import {ModuleProps} from 'sentry/components/onboarding/gettingStartedDoc/sdkDocumentation';
+import ExternalLink from 'sentry/components/links/externalLink';
 import {StepType} from 'sentry/components/onboarding/gettingStartedDoc/step';
+import type {
+  Docs,
+  DocsParams,
+  OnboardingConfig,
+} from 'sentry/components/onboarding/gettingStartedDoc/types';
 import {t, tct} from 'sentry/locale';
+import {getPackageVersion} from 'sentry/utils/gettingStartedDocs/getPackageVersion';
 
-// Configuration Start
-export const steps = ({
-  dsn,
-  sourcePackageRegistries,
-}: Partial<
-  Pick<ModuleProps, 'dsn' | 'sourcePackageRegistries'>
-> = {}): LayoutProps['steps'] => [
-  {
-    type: StepType.INSTALL,
-    description: (
-      <p>
-        {tct(
-          'To add Sentry to your Rust project you just need to add a new dependency to your [code:Cargo.toml]:',
-          {code: <code />}
-        )}
-      </p>
-    ),
-    configurations: [
-      {
-        language: 'toml',
-        partialLoading: sourcePackageRegistries?.isLoading,
-        code: `
+type Params = DocsParams;
+
+const getInstallSnippet = (params: Params) => `
 [dependencies]
-sentry = "${
-          sourcePackageRegistries?.isLoading
-            ? t('\u2026loading')
-            : sourcePackageRegistries?.data?.['sentry.rust']?.version ?? '0.31.5'
-        }"
-        `,
-      },
-    ],
-  },
-  {
-    type: StepType.CONFIGURE,
-    description: (
-      <p>
-        {tct(
-          '[code:Sentry.init()] will return you a guard that when freed, will prevent process exit until all events have been sent (within a timeout):',
-          {code: <code />}
-        )}
-      </p>
-    ),
-    configurations: [
-      {
-        language: 'rust',
-        code: `
-let _guard = sentry::init(("${dsn}", sentry::ClientOptions {
+sentry = "${getPackageVersion(params, 'sentry.rust', '0.32.1')}"`;
+
+const getInstallSnippetMetrics = (params: Params) => `
+sentry = { version = "${getPackageVersion(
+  params,
+  'sentry.rust',
+  '0.32.1'
+)}", features = ["UNSTABLE_metrics"] }`;
+
+const getConfigureSnippet = (params: Params) => `
+let _guard = sentry::init(("${params.dsn}", sentry::ClientOptions {
   release: sentry::release_name!(),
   ..Default::default()
-}));
-        `,
-      },
-    ],
-  },
-  {
-    type: StepType.VERIFY,
-    description: t(
-      'The quickest way to verify Sentry in your Rust application is to cause a panic:'
-    ),
-    configurations: [
-      {
-        language: 'rust',
-        code: `
+}));`;
+
+const getVerifySnippet = (params: Params) => `
 fn main() {
-  let _guard = sentry::init(("${dsn}", sentry::ClientOptions {
+  let _guard = sentry::init(("${params.dsn}", sentry::ClientOptions {
     release: sentry::release_name!(),
     ..Default::default()
   }));
 
   // Sentry will capture this
   panic!("Everything is on fire!");
-}
-        `,
-      },
-    ],
-  },
-];
-// Configuration End
+}`;
+
+const getVerifySnippetMetrics = () => `
+use sentry::metrics::Metric;
+
+// Add 1 to a counter named 'hits'
+Metric::count("hits").send();`;
+
+const onboarding: OnboardingConfig = {
+  install: params => [
+    {
+      type: StepType.INSTALL,
+      description: tct(
+        'To add Sentry to your Rust project you just need to add a new dependency to your [code:Cargo.toml]:',
+        {code: <code />}
+      ),
+      configurations: [
+        {
+          language: 'toml',
+          partialLoading: params.sourcePackageRegistries.isLoading,
+          code: getInstallSnippet(params),
+        },
+      ],
+    },
+  ],
+  configure: params => [
+    {
+      type: StepType.CONFIGURE,
+      description: tct(
+        '[code:Sentry.init()] will return you a guard that when freed, will prevent process exit until all events have been sent (within a timeout):',
+        {code: <code />}
+      ),
+      configurations: [
+        {
+          language: 'rust',
+          code: getConfigureSnippet(params),
+        },
+      ],
+    },
+  ],
+  verify: params => [
+    {
+      type: StepType.VERIFY,
+      description: t(
+        'The quickest way to verify Sentry in your Rust application is to cause a panic:'
+      ),
+      configurations: [
+        {
+          language: 'rust',
+          code: getVerifySnippet(params),
+        },
+      ],
+    },
+  ],
+};
+
+const customMetricsOnboarding: OnboardingConfig = {
+  install: params => [
+    {
+      type: StepType.INSTALL,
+      description: tct(
+        'You need at least version 0.32.1 of the [codeSentry:sentry] or  [codeSentryCore:sentry-core] crates installed. Enable the [codeFeature:UNSTABLE_metrics] feature:',
+        {
+          codeSentry: <code />,
+          codeSentryCore: <code />,
+          codeSentryFeature: <code />,
+        }
+      ),
+      configurations: [
+        {
+          language: 'toml',
+          partialLoading: params.sourcePackageRegistries.isLoading,
+          code: getInstallSnippetMetrics(params),
+        },
+      ],
+    },
+  ],
+  configure: () => [],
+  verify: () => [
+    {
+      type: StepType.VERIFY,
+      description: tct(
+        "Then you'll be able to add metrics as [codeCounters:counters], [codeSets:sets], [codeDistribution:distributions], and [codeGauge:gauges]. These are available under the [codeNamespace:Sentry.metrics] namespace. Try out this example:",
+        {
+          codeCounters: <code />,
+          codeSets: <code />,
+          codeDistribution: <code />,
+          codeGauge: <code />,
+          codeNamespace: <code />,
+        }
+      ),
+      configurations: [
+        {
+          code: [
+            {
+              label: 'Rust',
+              value: 'rust',
+              language: 'rust',
+              code: getVerifySnippetMetrics(),
+            },
+          ],
+        },
+        {
+          description: t(
+            'With a bit of delay you can see the data appear in the Sentry UI.'
+          ),
+        },
+        {
+          description: tct(
+            'Learn more about metrics and how to configure them, by reading the [docsLink:docs].',
+            {
+              docsLink: (
+                <ExternalLink href="https://docs.rs/sentry/latest/sentry/metrics/index.html" />
+              ),
+            }
+          ),
+        },
+      ],
+    },
+  ],
+};
 
-export function GettingStartedWithRust({
-  dsn,
-  sourcePackageRegistries,
-  ...props
-}: ModuleProps) {
-  return <Layout steps={steps({dsn, sourcePackageRegistries})} {...props} />;
-}
+const docs: Docs = {
+  onboarding,
+  customMetricsOnboarding,
+};
 
-export default GettingStartedWithRust;
+export default docs;