diff --git a/LICENSE b/LICENSE
index 5cac0ad6f3d13..331750698c211 100644
--- a/LICENSE
+++ b/LICENSE
@@ -16,7 +16,7 @@ Additional Use Grant: You may make use of the Licensed Work, provided that you d
error-reporting or application monitoring features of the
Licensed Work.
-Change Date: 2026-08-15
+Change Date: 2026-09-19
Change License: Apache License, Version 2.0
diff --git a/gatsby-browser.tsx b/gatsby-browser.tsx
index 7a9b945f6e4c2..7f4f7d31334ba 100644
--- a/gatsby-browser.tsx
+++ b/gatsby-browser.tsx
@@ -1,12 +1,16 @@
import React from 'react';
import {GatsbyBrowser} from 'gatsby';
+import {FeedbackWidgetLoader} from 'sentry-docs/components/feedback/feedbackWidgetLoader';
import PageContext from 'sentry-docs/components/pageContext';
export const wrapPageElement: GatsbyBrowser['wrapPageElement'] = ({
element,
props: {pageContext},
-}) => {element};
+}) =>
+
+ {element}
+
// Disable prefetching altogether so our bw is not destroyed.
// If this turns out to hurt performance significantly, we can
diff --git a/gatsby-ssr.tsx b/gatsby-ssr.tsx
index 865768002530b..9d8bd11c4f78f 100644
--- a/gatsby-ssr.tsx
+++ b/gatsby-ssr.tsx
@@ -4,6 +4,7 @@
import React from 'react';
import {GatsbySSR} from 'gatsby';
+import {FeedbackWidgetLoader} from 'sentry-docs/components/feedback/feedbackWidgetLoader';
import {PageContext} from 'sentry-docs/components/pageContext';
const sentryEnvironment = process.env.GATSBY_ENV || process.env.NODE_ENV || 'development';
@@ -12,7 +13,12 @@ const sentryLoaderUrl = process.env.SENTRY_LOADER_URL;
export const wrapPageElement: GatsbySSR['wrapPageElement'] = ({
element,
props: {pageContext},
-}) => {element};
+}) => (
+
+
+ {element}
+
+);
export const onPreRenderHTML: GatsbySSR['onPreRenderHTML'] = ({getHeadComponents}) => {
if (process.env.NODE_ENV !== 'production') {
diff --git a/package.json b/package.json
index 9c3110dd99972..5e50976cc7c45 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,8 @@
"@mdx-js/mdx": "^1.6.18",
"@mdx-js/react": "^1.6.18",
"@sentry-internal/global-search": "^0.5.7",
- "@sentry/browser": "7.55.2",
+ "@sentry/browser": "7.69.0",
+ "@sentry/core": "7.69.0",
"@sentry/webpack-plugin": "2.2.2",
"@types/dompurify": "^3.0.2",
"@types/js-cookie": "^3.0.3",
diff --git a/src/components/feedback/feedbackButton.tsx b/src/components/feedback/feedbackButton.tsx
new file mode 100644
index 0000000000000..8bc266d6fa05c
--- /dev/null
+++ b/src/components/feedback/feedbackButton.tsx
@@ -0,0 +1,31 @@
+import React from 'react';
+import styled from '@emotion/styled';
+
+const Button = styled.button`
+ position: fixed;
+ right: 0px;
+ bottom: 50%;
+ transform: translate(25%, 50%) rotate(-90deg);
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ color: #231c3d;
+ cursor: pointer;
+ font-size: 14px;
+ font-weight: 600;
+ padding: 6px 16px;
+ text-align: center;
+ text-decoration: none;
+ z-index: 9000;
+ &:hover {
+ background-color: #eee;
+ }
+ &:focus-visible {
+ outline: 1px solid #79628c;
+ background-color: #eee;
+ }
+`;
+
+export function FeedbackButton(props) {
+ return ;
+}
diff --git a/src/components/feedback/feedbackForm.tsx b/src/components/feedback/feedbackForm.tsx
new file mode 100644
index 0000000000000..5e1e4bb2bedfc
--- /dev/null
+++ b/src/components/feedback/feedbackForm.tsx
@@ -0,0 +1,166 @@
+import React, {FormEvent, useRef} from 'react';
+import {css} from '@emotion/react';
+import styled from '@emotion/styled';
+
+interface FeedbackFormProps {
+ onClose: () => void;
+ onSubmit: (data: {comment: string; email: string; name: string}) => void;
+}
+
+const retrieveStringValue = (formData: FormData, key: string) => {
+ const value = formData.get(key);
+ if (typeof value === 'string') {
+ return value.trim();
+ }
+ return '';
+};
+
+export function FeedbackForm({onClose, onSubmit}: FeedbackFormProps) {
+ const formRef = useRef(null);
+
+ const handleSubmit = (e: FormEvent) => {
+ e.preventDefault();
+ const formData = new FormData(e.target as HTMLFormElement);
+ onSubmit({
+ name: retrieveStringValue(formData, 'name'),
+ email: retrieveStringValue(formData, 'email'),
+ comment: retrieveStringValue(formData, 'comment'),
+ });
+ };
+
+ const user = window.Sentry?.getCurrentHub().getScope()?.getUser();
+
+ return (
+
+ );
+}
+
+const Form = styled.form`
+ display: flex;
+ overflow: auto;
+ flex-direction: column;
+ gap: 16px;
+ padding: 24px;
+`;
+
+const Label = styled.label`
+ display: flex;
+ flex-direction: column;
+ gap: 4px;
+ margin: 0px;
+`;
+
+const inputStyles = css`
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ font-size: 14px;
+ padding: 6px 8px;
+ &:focus {
+ outline: 1px solid rgba(108, 95, 199, 1);
+ border-color: rgba(108, 95, 199, 1);
+ }
+`;
+
+const Input = styled.input`
+ ${inputStyles}
+`;
+
+const TextArea = styled.textarea`
+ ${inputStyles}
+ min-height: 64px;
+ resize: vertical;
+`;
+
+const ModalFooter = styled.div`
+ display: flex;
+ justify-content: flex-end;
+ gap: 8px;
+ margin-top: 8px;
+`;
+
+const buttonStyles = css`
+ border: 1px solid #ccc;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 14px;
+ font-weight: 600;
+ padding: 6px 16px;
+`;
+
+const SubmitButton = styled.button`
+ ${buttonStyles}
+ background-color: rgba(108, 95, 199, 1);
+ color: #fff;
+ &:hover {
+ background-color: rgba(88, 74, 192, 1);
+ }
+ &:focus-visible {
+ outline: 1px solid rgba(108, 95, 199, 1);
+ background-color: rgba(88, 74, 192, 1);
+ }
+`;
+
+const CancelButton = styled.button`
+ ${buttonStyles}
+ background-color: #fff;
+ color: #231c3d;
+ font-weight: 500;
+ &:hover {
+ background-color: #eee;
+ }
+ &:focus-visible {
+ outline: 1px solid rgba(108, 95, 199, 1);
+ background-color: #eee;
+ }
+`;
+
+const FlexColumns = styled.div`
+ display: flex;
+ flex-direction: row;
+ gap: 16px;
+ & > * {
+ flex: 1;
+ }
+`;
diff --git a/src/components/feedback/feedbackModal.tsx b/src/components/feedback/feedbackModal.tsx
new file mode 100644
index 0000000000000..be7d5e7038760
--- /dev/null
+++ b/src/components/feedback/feedbackModal.tsx
@@ -0,0 +1,161 @@
+import React, {Fragment, useEffect, useRef, useState} from 'react';
+import styled from '@emotion/styled';
+
+import {useFocusTrap} from '../hooks/useFocusTrap';
+import {useShortcut} from '../hooks/useShortcut';
+
+import {FeedbackForm} from './feedbackForm';
+import {FeedbackSuccessMessage} from './feedbackSuccessMessage';
+import {sendFeedbackRequest} from './sendFeedbackRequest';
+
+interface RenderFunctionProps {
+ /**
+ * Is the modal open/visible
+ */
+ open: boolean;
+
+ /**
+ * Shows the feedback modal
+ */
+ showModal: () => void;
+}
+type FeedbackRenderFunction = (
+ renderFunctionProps: RenderFunctionProps
+) => React.ReactNode;
+
+interface FeedbackModalProps {
+ children: FeedbackRenderFunction;
+ title: string;
+}
+
+interface FeedbackFormData {
+ comment: string;
+ email: string;
+ name: string;
+}
+
+async function sendFeedback(
+ data: FeedbackFormData,
+ replayId: string,
+ pageUrl: string
+): Promise {
+ const feedback = {
+ message: data.comment,
+ email: data.email,
+ replay_id: replayId,
+ url: pageUrl,
+ };
+ return await sendFeedbackRequest(feedback);
+}
+
+function stopPropagation(e: React.MouseEvent) {
+ e.stopPropagation();
+}
+
+export function FeedbackModal({title, children}: FeedbackModalProps) {
+ const [open, setOpen] = useState(false);
+ const dialogRef = useRef(null);
+ const [showSuccessMessage, setShowSuccessMessage] = useState(false);
+
+ const handleClose = () => {
+ setOpen(false);
+ };
+
+ const handleSubmit = (data: FeedbackFormData) => {
+ const replay = window.Sentry?.getCurrentHub?.()
+ ?.getClient()
+ ?.getIntegration(window.Sentry?.Replay);
+
+ // Prepare session replay
+ replay?.flush();
+ const replayId = replay?.getReplayId();
+
+ const pageUrl = document.location.href;
+
+ sendFeedback(data, replayId, pageUrl).then(response => {
+ if (response) {
+ setOpen(false);
+ setShowSuccessMessage(true);
+ } else {
+ // eslint-disable-next-line no-alert
+ alert('Error submitting your feedback. Please try again');
+ }
+ });
+ };
+
+ const showModal = () => {
+ setOpen(true);
+ };
+
+ useEffect(() => {
+ if (!showSuccessMessage) {
+ return () => {};
+ }
+ const timeout = setTimeout(() => {
+ setShowSuccessMessage(false);
+ }, 6000);
+ return () => {
+ clearTimeout(timeout);
+ };
+ }, [showSuccessMessage]);
+
+ useFocusTrap(dialogRef, open);
+ useShortcut('Escape', handleClose);
+
+ return (
+
+
+
+ {children({open, showModal})}
+
+ );
+}
+
+const Dialog = styled.dialog`
+ background-color: rgba(0, 0, 0, 0.05);
+ border: none;
+ position: fixed;
+ inset: 0;
+ z-index: 10000;
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ opacity: 1;
+ transition: opacity 0.2s ease-in-out;
+ &:not([open]) {
+ opacity: 0;
+ pointer-events: none;
+ visibility: hidden;
+ }
+`;
+
+const Content = styled.div`
+ border-radius: 4px;
+ background-color: #fff;
+ width: 500px;
+ max-width: 100%;
+ max-height: calc(100% - 64px);
+ display: flex;
+ flex-direction: column;
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 16px rgba(0, 0, 0, 0.2);
+ transition: transform 0.2s ease-in-out;
+ transform: translate(0, 0) scale(1);
+ dialog:not([open]) & {
+ transform: translate(0, -16px) scale(0.98);
+ }
+`;
+
+const Header = styled.h2`
+ font-size: 20px;
+ font-weight: 600;
+ border-bottom: 1px solid #ccc;
+ padding: 20px 24px;
+ margin: 0px;
+`;
diff --git a/src/components/feedback/feedbackSuccessMessage.tsx b/src/components/feedback/feedbackSuccessMessage.tsx
new file mode 100644
index 0000000000000..3479248882f86
--- /dev/null
+++ b/src/components/feedback/feedbackSuccessMessage.tsx
@@ -0,0 +1,71 @@
+import React from 'react';
+import {keyframes} from '@emotion/react';
+import styled from '@emotion/styled';
+
+const Wrapper = styled.div`
+ position: fixed;
+ width: 100vw;
+ padding: 8px;
+ right: 0;
+ bottom: 0;
+ pointer-events: none;
+ display: flex;
+ justify-content: flex-end;
+ transition: transform 0.4s ease-in-out;
+ transform: translateY(0);
+ z-index: 9000;
+ &[data-hide='true'] {
+ transform: translateY(120%);
+ }
+`;
+
+const borderColor = keyframes`
+ 0% {
+ box-shadow: 0 2px 6px rgba(88, 74, 192, 1);
+ border-color: rgba(88, 74, 192, 1);
+ }
+ 20% {
+ box-shadow: 0 2px 6px #FFC227;
+ border-color: #FFC227;
+ }
+ 40% {
+ box-shadow: 0 2px 6px #FF7738;
+ border-color: #FF7738;
+ }
+ 60% {
+ box-shadow: 0 2px 6px #33BF9E;
+ border-color: #33BF9E;
+ }
+ 80% {
+ box-shadow: 0 2px 6px #F05781;
+ border-color: #F05781;
+ }
+ 100% {
+ box-shadow: 0 2px 6px rgba(88, 74, 192, 1);
+ border-color: rgba(88, 74, 192, 1);
+ }
+`;
+
+const Content = styled.div`
+ background-color: #fff;
+ border: 2px solid rgba(88, 74, 192, 1);
+ border-radius: 20px;
+ color: rgba(43, 34, 51, 1);
+ font-size: 14px;
+ padding: 6px 24px;
+ box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.05), 0 4px 16px;
+ box-shadow-color: red;
+ animation: ${borderColor} 4s alternate infinite;
+`;
+
+interface FeedbackSuccessMessageProps extends React.HTMLAttributes {
+ show: boolean;
+}
+
+export function FeedbackSuccessMessage({show, ...props}: FeedbackSuccessMessageProps) {
+ return (
+
+ š Thank you for your feedback! š
+
+ );
+}
diff --git a/src/components/feedback/feedbackWidget.tsx b/src/components/feedback/feedbackWidget.tsx
new file mode 100644
index 0000000000000..74701746213ef
--- /dev/null
+++ b/src/components/feedback/feedbackWidget.tsx
@@ -0,0 +1,24 @@
+import React from 'react';
+
+import {FeedbackButton} from './feedbackButton';
+import {FeedbackModal} from './feedbackModal';
+
+interface FeedbackWidgetProps {
+ title?: string;
+}
+
+/**
+ * The "Widget" connects the default Feedback button with the Feedback Modal
+ */
+export default function FeedbackWidget({title = 'Got Feedback?'}: FeedbackWidgetProps) {
+ // Don't render anything if Sentry is not already loaded
+ if (!window.Sentry?.getCurrentHub?.()) {
+ return null;
+ }
+
+ return (
+
+ {({open, showModal}) => (open ? null : )}
+
+ );
+}
diff --git a/src/components/feedback/feedbackWidgetLoader.tsx b/src/components/feedback/feedbackWidgetLoader.tsx
new file mode 100644
index 0000000000000..f3618a7b38bdb
--- /dev/null
+++ b/src/components/feedback/feedbackWidgetLoader.tsx
@@ -0,0 +1,20 @@
+import React, {Fragment, lazy, Suspense} from 'react';
+
+const FeedbackWidget = lazy(() => import('./feedbackWidget'));
+
+/**
+ * Only render FeedbackWidget on client as it needs access to `window`
+ */
+export function FeedbackWidgetLoader() {
+ const isSSR = typeof window === 'undefined';
+
+ return (
+
+ {!isSSR && (
+ }>
+
+
+ )}
+
+ );
+}
diff --git a/src/components/feedback/prepareFeedbackEvent.ts b/src/components/feedback/prepareFeedbackEvent.ts
new file mode 100644
index 0000000000000..390c68cd24e84
--- /dev/null
+++ b/src/components/feedback/prepareFeedbackEvent.ts
@@ -0,0 +1,46 @@
+import type {Scope} from '@sentry/core';
+import {prepareEvent} from '@sentry/core';
+import type {Client} from '@sentry/types';
+
+import type {FeedbackEvent} from './types';
+
+/**
+ * Prepare a feedback event & enrich it with the SDK metadata.
+ */
+export async function prepareFeedbackEvent({
+ client,
+ scope,
+ event,
+}: {
+ client: Client;
+ event: FeedbackEvent;
+ scope: Scope;
+}): Promise {
+ const preparedEvent = (await prepareEvent(
+ client.getOptions(),
+ event,
+ {integrations: []},
+ scope
+ )) as FeedbackEvent | null;
+
+ // If e.g. a global event processor returned null
+ if (!preparedEvent) {
+ return null;
+ }
+
+ // This normally happens in browser client "_prepareEvent"
+ // but since we do not use this private method from the client, but rather the plain import
+ // we need to do this manually.
+ preparedEvent.platform = preparedEvent.platform || 'javascript';
+
+ // extract the SDK name because `client._prepareEvent` doesn't add it to the event
+ const metadata = client.getSdkMetadata && client.getSdkMetadata();
+ const {name, version} = (metadata && metadata.sdk) || {};
+
+ preparedEvent.sdk = {
+ ...preparedEvent.sdk,
+ name: name || 'sentry.javascript.unknown',
+ version: version || '0.0.0',
+ };
+ return preparedEvent;
+}
diff --git a/src/components/feedback/sendFeedbackRequest.ts b/src/components/feedback/sendFeedbackRequest.ts
new file mode 100644
index 0000000000000..82d96d6156606
--- /dev/null
+++ b/src/components/feedback/sendFeedbackRequest.ts
@@ -0,0 +1,124 @@
+import {DsnComponents} from '@sentry/types';
+
+import {prepareFeedbackEvent} from './prepareFeedbackEvent';
+
+/**
+ * Function taken from sentry-javascript
+ */
+function dsnToString(dsn: DsnComponents, withPassword: boolean = false): string {
+ const {host, path, pass, port, projectId, protocol, publicKey} = dsn;
+ return (
+ `${protocol}://${publicKey}${withPassword && pass ? `:${pass}` : ''}` +
+ `@${host}${port ? `:${port}` : ''}/${path ? `${path}/` : path}${projectId}`
+ );
+}
+
+/**
+ * Send feedback using `fetch()`
+ */
+export async function sendFeedbackRequest({
+ message,
+ email,
+ replay_id,
+ url,
+}): Promise {
+ const hub = window.Sentry?.getCurrentHub();
+
+ if (!hub) {
+ return null;
+ }
+
+ const client = hub.getClient();
+ const scope = hub.getScope();
+ const transport = client && client.getTransport();
+ const dsn = client && client.getDsn();
+
+ if (!client || !transport || !dsn) {
+ return null;
+ }
+
+ const baseEvent = {
+ feedback: {
+ contact_email: email,
+ message,
+ replay_id,
+ url,
+ },
+ // type: 'feedback_event',
+ };
+
+ const feedbackEvent = await prepareFeedbackEvent({
+ scope,
+ client,
+ event: baseEvent,
+ });
+
+ if (!feedbackEvent) {
+ // Taken from baseclient's `_processEvent` method, where this is handled for errors/transactions
+ // client.recordDroppedEvent('event_processor', 'feedback', baseEvent);
+ return null;
+ }
+
+ /*
+ For reference, the fully built event looks something like this:
+ {
+ "data": {
+ "dist": "abc123",
+ "environment": "production",
+ "feedback": {
+ "contact_email": "colton.allen@sentry.io",
+ "message": "I really like this user-feedback feature!",
+ "replay_id": "ec3b4dc8b79f417596f7a1aa4fcca5d2",
+ "url": "https://docs.sentry.io/platforms/javascript/"
+ },
+ "id": "1ffe0775ac0f4417aed9de36d9f6f8dc",
+ "platform": "javascript",
+ "release": "version@1.3",
+ "request": {
+ "headers": {
+ "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36"
+ }
+ },
+ "sdk": {
+ "name": "sentry.javascript.react",
+ "version": "6.18.1"
+ },
+ "tags": {
+ "key": "value"
+ },
+ "timestamp": "2023-08-31T14:10:34.954048",
+ "user": {
+ "email": "username@example.com",
+ "id": "123",
+ "ip_address": "127.0.0.1",
+ "name": "user",
+ "username": "user2270129"
+ }
+ }
+ }
+ */
+
+ // Prevent this data (which, if it exists, was used in earlier steps in the processing pipeline) from being sent to
+ // sentry. (Note: Our use of this property comes and goes with whatever we might be debugging, whatever hacks we may
+ // have temporarily added, etc. Even if we don't happen to be using it at some point in the future, let's not get rid
+ // of this `delete`, lest we miss putting it back in the next time the property is in use.)
+ delete feedbackEvent.sdkProcessingMetadata;
+
+ try {
+ const path = 'https://sentry.io/api/0/feedback/';
+ const response = await fetch(path, {
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json',
+ Authorization: `DSN ${dsnToString(dsn)}`,
+ },
+ body: JSON.stringify(feedbackEvent),
+ });
+ if (!response.ok) {
+ return null;
+ }
+ return response;
+ } catch (err) {
+ return null;
+ }
+}
diff --git a/src/components/feedback/types.ts b/src/components/feedback/types.ts
new file mode 100644
index 0000000000000..8c3ef9b01c829
--- /dev/null
+++ b/src/components/feedback/types.ts
@@ -0,0 +1,16 @@
+import type {Event} from '@sentry/types';
+
+/**
+ * NOTE: These types are still considered Beta and subject to change.
+ * @hidden
+ */
+export interface FeedbackEvent extends Event {
+ feedback: {
+ contact_email: string;
+ message: string;
+ replay_id: string;
+ url: string;
+ };
+ // TODO: Add this event type to Event
+ // type: 'feedback_event';
+}
diff --git a/src/components/hooks/useFocusTrap.ts b/src/components/hooks/useFocusTrap.ts
new file mode 100644
index 0000000000000..b8f7a8c914973
--- /dev/null
+++ b/src/components/hooks/useFocusTrap.ts
@@ -0,0 +1,48 @@
+import {useEffect} from 'react';
+
+export const focusableElements = [
+ 'input:not([disabled]):not([type="hidden"])',
+ 'textarea:not([disabled])',
+ 'button:not([disabled])',
+].join(',');
+
+export const useFocusTrap = (ref: React.RefObject, autofocus?: boolean) => {
+ useEffect(() => {
+ const element = ref.current;
+ if (!element) {
+ return () => {};
+ }
+ const focusable = element.querySelectorAll(focusableElements);
+ const firstFocusable = focusable[0] as HTMLElement;
+ const lastFocusable = focusable[focusable.length - 1] as HTMLElement;
+
+ const handleKeyDown = (event: KeyboardEvent) => {
+ if (event.key === 'Tab') {
+ if (event.shiftKey) {
+ if (document.activeElement === firstFocusable) {
+ lastFocusable.focus();
+ event.preventDefault();
+ }
+ } else if (document.activeElement === lastFocusable) {
+ firstFocusable.focus();
+ event.preventDefault();
+ }
+ }
+ };
+
+ document.addEventListener('keydown', handleKeyDown);
+
+ return () => {
+ document.removeEventListener('keydown', handleKeyDown);
+ };
+ }, [ref]);
+
+ useEffect(() => {
+ const element = ref.current;
+ if (element && autofocus) {
+ const focusable = element.querySelectorAll(focusableElements);
+ const firstFocusable = focusable[0] as HTMLElement;
+ firstFocusable.focus();
+ }
+ }, [ref, autofocus]);
+};
diff --git a/src/components/hooks/useShortcut.ts b/src/components/hooks/useShortcut.ts
new file mode 100644
index 0000000000000..54c39780e9877
--- /dev/null
+++ b/src/components/hooks/useShortcut.ts
@@ -0,0 +1,35 @@
+import {useEffect} from 'react';
+
+type ShortcutConfig = {
+ key: string;
+ altKey?: boolean;
+ ctrlKey?: boolean;
+ shiftKey?: boolean;
+};
+
+export const useShortcut = (key: string | ShortcutConfig, callback: () => void) => {
+ useEffect(() => {
+ const handleKeyDown = (event: KeyboardEvent) => {
+ if (typeof key === 'string') {
+ if (event.key === key) {
+ callback();
+ }
+ } else {
+ if (
+ event.key === key.key &&
+ event.shiftKey === key.shiftKey &&
+ event.ctrlKey === key.ctrlKey &&
+ event.altKey === key.altKey
+ ) {
+ callback();
+ }
+ }
+ };
+
+ document.addEventListener('keydown', handleKeyDown);
+
+ return () => {
+ document.removeEventListener('keydown', handleKeyDown);
+ };
+ }, [key, callback]);
+};
diff --git a/src/docs/product/accounts/auth-tokens/index.mdx b/src/docs/product/accounts/auth-tokens/index.mdx
new file mode 100644
index 0000000000000..2b109633a63ce
--- /dev/null
+++ b/src/docs/product/accounts/auth-tokens/index.mdx
@@ -0,0 +1,84 @@
+---
+title: "Auth Tokens"
+sidebar_order: 45
+description: "Learn about the different kinds of Auth Tokens Sentry provides, and when to use which."
+---
+
+Auth tokens (short for _authentication tokens_) are a way to authenticate with Sentry. They are similar to passwords but are designed for programmatic interaction with Sentry. Some examples of what you would use auth tokens for include:
+
+- Uploading Source Maps during your CI build
+- Using [Sentry CLI](/product/cli/) to interact with Sentry
+- Using the [Sentry API](/api/auth/)
+
+Each auth token is created with a certain set of permissions and scopes which are mapped to the Sentry API's [Permissions & Scopes](/api/permissions/). Some types of auth tokens have set permissions that can't be edited, while others can be customized upon token creation and edited later.
+
+We recommend using a separate auth token for each use case. For example, you would use a different auth token to upload source maps than the one you use with Sentry CLI. This has the benefit that if an auth token is compromised, you can revoke that auth token without impacting the rest of your workflow.
+
+## Types of Auth Tokens
+
+There are three key types of auth tokens in Sentry:
+
+- [Organization Auth Tokens](#organization-auth-tokens):
+ These tokens are bound to an organization, and have access to all projects within that organization. They have a limited set of permissions and are designed to be used in CI environments and with Sentry CLI.
+
+- [User Auth Tokens](#user-auth-tokens):
+ These tokens are bound to a user, and have access to all organizations and projects that user has access to.
+
+- [Internal Integrations](#internal-integrations):
+ These tokens are bound to an organization, and have access to all projects within that organization. They can be created with a custom set of permissions, and are designed to be used in cases where organization auth tokens don't have sufficient access rights.
+
+### When Should I Use Which?
+
+For most scenarios, we recommend using [Organization Auth Tokens](#organization-auth-tokens). They are designed to be used in CI environments and have a limited set of permissions. This means that if the place you stored the auth token is compromised, the attacker can only do limited damage.
+
+Organization auth tokens permissions aren't customizable. They are set to allow most CI-related tasks, without any unnecessary permissions.
+
+[User Auth Tokens](#user-auth-tokens) should be used to interact with the Sentry API on behalf of a user. For example, to fetch all issues for a user, you would use a User auth token. We don't recommend using User auth tokens for CI tasks because if the user who created the token is removed from the Organization, the token will stop working.
+
+User auth token permissions are customizable and editable.
+
+[Internal Integrations](#internal-integrations) should be used when you need full API access (which the organization auth tokens cannot grant), and you want to interact with the Sentry API on behalf of an organization. For example, to programmatically create a new project, you would use an internal integration.
+
+Permissions for auth tokens created as part of an internal integration are customizable and editable.
+
+### Organization Auth Tokens
+
+[Organization auth tokens](https://sentry.io/orgredirect/organizations/:orgslug/settings/auth-tokens/) can be created in [sentry.io](https://sentry.io) on the **Auth Tokens** page under **Settings > Developer Settings > Auth Tokens**.
+
+![](org-auth-tokens-overview.png)
+
+They can also be generated on certain pages of Sentry's docs if you're signed in, and by using the Sentry Wizard to configure uploading source maps.
+
+Organization auth token names are generated for you unless you create the token through the Sentry UI. This name is only used for display purposes - it helps to identify an auth token in case you want to revoke it later. You can change the name for an organization auth token at [sentry.io](https://sentry.io) on the **Edit Auth Token** page under **Settings > Developer Settings > Auth Tokens**.
+
+For security reasons, organization auth tokens are only visible _once_, right after you create them. If you lose the auth token, you will have to create a new one. This means you can't see the full token on the overview page or on the token detail page, you can only see the last characters of the token to help identify it.
+
+Any user can create organization auth tokens for any of their organizations. This allows any user (not only organization owners) to configure a Sentry SDK and set up CI processes by creating and using organization auth tokens. Since organization auth tokens have limited access, there is limited potential for abuse.
+
+![](org-auth-token-create.png)
+
+All owners of the organization will receive a security email when a new organization auth token is created and can revoke these tokens at any point. _Only_ organization owners & managers can revoke organization auth tokens .
+
+### User Auth Tokens
+
+[User auth tokens](https://sentry.io/settings/account/api/auth-tokens/) can be created in [sentry.io](https://sentry.io) on the **User Auth Tokens** page under the Account dropdown in the top left.
+
+![](user-auth-tokens-menu.png)
+
+User auth tokens can be created by any user, and are bound to that user. The tokens can be given permissions to all organizations and projects that user has access to. This means a user auth token's _maximum_ scope is all the scopes that the user has access to for a given organization. A user auth token cannot exceed the permissions of the user who created it. See [Organization and User Management](/product/accounts/membership/) for more details on how permissions work in Sentry.
+
+When you create a new user auth token, you can select which [scopes](/api/permissions/) the token should have in the UI:
+
+![](user-auth-token-create.png)
+
+Currently, you can view user auth tokens in the UI after creating them. This is a legacy behavior that may change in the future. We recommend only using each user auth token once, and creating a new token for each use case. Any user can always revoke any of their user auth tokens.
+
+![](user-auth-tokens-overview.png)
+
+We recommend only using a user auth token to interact with the Sentry API on behalf of a user. See Sentry's API [Authentication](/api/auth/) docs for more information on how to do this.
+
+### Internal Integrations
+
+We recommend only using an internal integration when you want to interact with the Sentry API on behalf of an organization. See Sentry's API [Authentication](/api/auth/) docs for more information on how to do this.
+
+See our docs on [Internal Integrations](/product/integrations/integration-platform/) to learn more.
diff --git a/src/docs/product/accounts/auth-tokens/org-auth-token-create.png b/src/docs/product/accounts/auth-tokens/org-auth-token-create.png
new file mode 100644
index 0000000000000..f216102b813dd
Binary files /dev/null and b/src/docs/product/accounts/auth-tokens/org-auth-token-create.png differ
diff --git a/src/docs/product/accounts/auth-tokens/org-auth-tokens-overview.png b/src/docs/product/accounts/auth-tokens/org-auth-tokens-overview.png
new file mode 100644
index 0000000000000..2140b9bc3132d
Binary files /dev/null and b/src/docs/product/accounts/auth-tokens/org-auth-tokens-overview.png differ
diff --git a/src/docs/product/accounts/auth-tokens/user-auth-token-create.png b/src/docs/product/accounts/auth-tokens/user-auth-token-create.png
new file mode 100644
index 0000000000000..4be8c20bb65d6
Binary files /dev/null and b/src/docs/product/accounts/auth-tokens/user-auth-token-create.png differ
diff --git a/src/docs/product/accounts/auth-tokens/user-auth-tokens-menu.png b/src/docs/product/accounts/auth-tokens/user-auth-tokens-menu.png
new file mode 100644
index 0000000000000..77fc73145bdd4
Binary files /dev/null and b/src/docs/product/accounts/auth-tokens/user-auth-tokens-menu.png differ
diff --git a/src/docs/product/accounts/auth-tokens/user-auth-tokens-overview.png b/src/docs/product/accounts/auth-tokens/user-auth-tokens-overview.png
new file mode 100644
index 0000000000000..2705e0728da6f
Binary files /dev/null and b/src/docs/product/accounts/auth-tokens/user-auth-tokens-overview.png differ
diff --git a/src/docs/product/cli/releases.mdx b/src/docs/product/cli/releases.mdx
index b7e687a5de3f7..74306ec9cdb96 100644
--- a/src/docs/product/cli/releases.mdx
+++ b/src/docs/product/cli/releases.mdx
@@ -28,6 +28,11 @@ The value can be arbitrary, but for certain platforms, recommendations exist:
- if you use a DVCS we recommend using the identifying hash (eg: the commit SHA, `da39a3ee5e6b4b0d3255bfef95601890afd80709`). You can let sentry-cli automatically determine this hash for supported version control systems with `sentry-cli releases propose-version`.
- if you tag releases we recommend using the release tag prefixed with a product or package name (for example, `my-project-name@2.3.12`).
+```bash
+#!/bin/sh
+sentry-cli releases new "$VERSION"
+```
+
Releases can also be auto created by different systems. For instance upon uploading a source map a release is automatically created. Likewise releases are created by some clients when an event for a release comes in.
## Finalizing Releases
@@ -60,9 +65,9 @@ VERSION=`sentry-cli releases propose-version`
## Commit Integration {#sentry-cli-commit-integration}
-If you have [repositories configured](/product/releases/setup/release-automation/) within your Sentry organization you can associate commits with your release.
+If you have [repositories configured](/product/releases/setup/release-automation/) within your Sentry organization, you can associate commits with your release automatically or manually. If you don't have a source code integration installed, you can still send Sentry commit information. See [Alternatively: Without a Repository Integration](#alternatively-without-a-repository-integration) to associate commits using the git tree of your local repo.
-There are two modes in which you can use this. One is the fully automatic mode. If you are deploying from a git repository and sentry-cli can discover the git repository from the current working directory you can set the commits with the `--auto` flag:
+To integrate commits automatically, you need to deploy from a git repository that sentry-cli can discover from your current working directory and set commits with the `--auto` flag:
```bash
sentry-cli releases set-commits "$VERSION" --auto
diff --git a/src/docs/product/issues/issue-details/performance-issues/frame-drop/frame-drop-function-evidence.png b/src/docs/product/issues/issue-details/performance-issues/frame-drop/frame-drop-function-evidence.png
new file mode 100644
index 0000000000000..6c40f984c9582
Binary files /dev/null and b/src/docs/product/issues/issue-details/performance-issues/frame-drop/frame-drop-function-evidence.png differ
diff --git a/src/docs/product/issues/issue-details/performance-issues/frame-drop/frame-drop-profile.png b/src/docs/product/issues/issue-details/performance-issues/frame-drop/frame-drop-profile.png
new file mode 100644
index 0000000000000..4bbfee2508d3c
Binary files /dev/null and b/src/docs/product/issues/issue-details/performance-issues/frame-drop/frame-drop-profile.png differ
diff --git a/src/docs/product/issues/issue-details/performance-issues/frame-drop/frame-drop-stack-trace.png b/src/docs/product/issues/issue-details/performance-issues/frame-drop/frame-drop-stack-trace.png
new file mode 100644
index 0000000000000..5dcc0a2c78207
Binary files /dev/null and b/src/docs/product/issues/issue-details/performance-issues/frame-drop/frame-drop-stack-trace.png differ
diff --git a/src/docs/product/issues/issue-details/performance-issues/frame-drop/index.mdx b/src/docs/product/issues/issue-details/performance-issues/frame-drop/index.mdx
new file mode 100644
index 0000000000000..36e068aee1f3a
--- /dev/null
+++ b/src/docs/product/issues/issue-details/performance-issues/frame-drop/index.mdx
@@ -0,0 +1,111 @@
+---
+title: "Frame Drop"
+sidebar_order: 30
+redirect_from:
+ - /product/issues/performance-issues/frame-drop/
+description: "Learn more about how we detect Frame Drop issues and what you can do to help fix them."
+---
+
+The main (or UI) thread in a mobile app is responsible for handling all user interaction and needs to be able to respond to gestures and taps in real time. If a long-running operation blocks the main thread, the app becomes unresponsive, impacting the quality of the user experience.
+
+We can detect some specific causes for a main thread stall, like decoding [images](/product/issues/issue-details/performance-issues/image-decoding-main-thread/) or [JSON](/product/issues/issue-details/performance-issues/json-decoding-main-thread/), or [searching strings with regexes](/product/issues/issue-details/performance-issues/regex-main-thread/), but there are many other things that could cause a stall. If a main thread stall causes your app to drop UI frames, but doesn't match one of our specific detectors, Sentry reports it under the generic Frame Drop issue type.
+
+## Detection Criteria
+
+[Profiling](/product/profiling/) must be enabled for Sentry to detect Frame Drop issues. Once set up, Sentry will look for profiles that record a frozen UI frame and then search for the most time-consuming application function call delaying the display link's next vsync. In a run of functions calling through without any self-time, the deepest call will be chosen.
+
+
+
+The minimum supported version for Cocoa is `8.12.0`.
+
+
+
+## Function Evidence
+
+To find additional information about your Frame Drop problem, go to its **Issue Details** page and scroll down to the "Function Evidence" section, which shows the following:
+
+- **Transaction Name:** The name of the transaction where the issue was detected.
+- **Suspect Function:** The function that triggered the issue detection.
+- **Duration:** How long the function took to execute and the number of consecutive samples collected by the profiler that contained the function.
+
+![Frame Drop Function Evidence](frame-drop-function-evidence.png)
+
+To view the entire profile associated with the issue, click the āView Profileā button.
+
+The profile will indicate where the suspect function was called from, along with other functions being called _by_ the suspect function:
+
+![Frame Drop Profile](frame-drop-profile.png)
+
+## Stack Trace
+
+The āStack Traceā section shows a full stack trace view, highlighting the long-running function frame:
+
+![Frame Drop Stack Trace](frame-drop-stack-trace.png)
+
+## Example
+
+### iOS
+
+The following code executes a long-running `while` loop on the main thread:
+
+```objective-c
+// given an array of number strings...
+
+NSMutableOrderedSet *sortedEvenNumbers = [NSMutableOrderedSet orderedSet];
+[numbers enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger __unused idx, BOOL * _Nonnull __unused stop) {
+ if (obj.integerValue % 2 == 0) {
+ [sortedEvenNumbers addObject:obj];
+ }
+}];
+```
+
+Performance could be improved by moving the long computation off of the main thread. The simplest approach is dispatching it to a lower Quality of Service (QoS) queue (or `NSOperationQueue`):
+
+```objective-c {tabTitle:Dispatch to Background Queue}
+// given an array of number strings...
+
+NSMutableOrderedSet *sortedEvenNumbers = [NSMutableOrderedSet orderedSet];
+dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^{
+ [numbers enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger __unused idx, BOOL * _Nonnull __unused stop) {
+ if (obj.integerValue % 2 == 0) {
+ [sortedEvenNumbers addObject:obj];
+ }
+ }];
+});
+```
+
+Another avenue to consider for loops is to parallelize iterations. There are several options for doing this:
+
+1. If you're iterating through a Foundation collection, you may already be using `enumerateObjects` or `enumerateKeysAndObjects`. Change this to `-[NSArray|NSSet|NSOrderedSet enumerateObjectsWithOptions:usingBlock:]` or `-[NSDictionary enumerateKeysAndObjectsWithOptions:usingBlock:]`, with option `NSEnumerationConcurrent`. Note that modifying the collection from inside the block will result in an exception being thrown. This is roughly equivalent to dispatching each iteration of the loop body to a concurrent GCD queue.
+
+1. Use `dispatch_apply` to perform iterations of a general loop on a concurrent queue.
+
+```objective-c {tabTitle:Foundation Collection Concurrent Enumeration}
+// given an array of number strings...
+
+NSMutableOrderedSet *sortedEvenNumbers = [NSMutableOrderedSet orderedSet];
+[numbers enumerateObjectsWithOptions:NSEnumerationConcurrent usingBlock:^(NSString * _Nonnull obj, NSUInteger __unused idx, BOOL * _Nonnull __unused stop) {
+ if (obj.integerValue % 2 == 0) {
+ [sortedEvenNumbers addObject:obj];
+ }
+}];
+```
+
+```objective-c {tabTitle:dispatch_apply}
+// given an array of number strings...
+
+NSMutableOrderedSet *sortedEvenNumbers = [NSMutableOrderedSet orderedSet];
+dispatch_apply(numberOfNumbers, dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^(size_t iteration) {
+ NSString *number = numbers[iteration];
+ if (number.integerValue % 2 == 0) {
+ [sortedEvenNumbers addObject:number];
+ }
+});
+```
+
+There are several things to keep in mind when introducing concurrency:
+
+- You may need to `@synchronize` critical sections, use semaphores, or dispatch back to a serial queue (or the main queue for UI work).
+- You may be unable to parallelize loops whose iterations are dependent or where order is significant.
+- Parallelization may be less efficient for small collections because [thread spawning has its own costs](https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Multithreading/AboutThreads/AboutThreads.html#//apple_ref/doc/uid/10000057i-CH6-SW20). So always measure first!
+- Both `enumerateObjects...` and `dispatch_apply` are synchronous and won't return until all iterations have completed. Dispatch their invocation asynchronously off the main queue to avoid waiting.
diff --git a/src/docs/product/performance/retention-priorities/index.mdx b/src/docs/product/performance/retention-priorities/index.mdx
index 30e9453ed2bb9..7b3b014cf2cb4 100644
--- a/src/docs/product/performance/retention-priorities/index.mdx
+++ b/src/docs/product/performance/retention-priorities/index.mdx
@@ -2,7 +2,10 @@
title: Retention Priorities
sidebar_order: 100
redirect_from:
+ - /product/sentry-basics/metrics/
+ - /product/sentry-basics/sampling/
- /product/data-management-settings/server-side-sampling/
+ - /product/data-management-settings/server-side-sampling/getting-started/
- /product/data-management-settings/server-side-sampling/current-limitations/
- /product/data-management-settings/server-side-sampling/sampling-configurations/
- /product/data-management-settings/dynamic-sampling/current-limitations/
@@ -10,7 +13,7 @@ redirect_from:
- /product/data-management-settings/dynamic-sampling/
- /product/performance/performance-at-scale/
- /product/performance/performance-at-scale/getting-started/
- - /product/performance-at-scale/benefits-performance-at-scale/
+ - /product/performance/performance-at-scale/benefits-performance-at-scale/
description: "Learn how Sentry determines retention priorities and how to update them."
---
diff --git a/src/docs/product/profiling/mobile-app-profiling/flamechart-with-gpu-overlay.png b/src/docs/product/profiling/mobile-app-profiling/flamechart-with-gpu-overlay.png
new file mode 100644
index 0000000000000..407d084d2e78c
Binary files /dev/null and b/src/docs/product/profiling/mobile-app-profiling/flamechart-with-gpu-overlay.png differ
diff --git a/src/docs/product/profiling/mobile-app-profiling.mdx b/src/docs/product/profiling/mobile-app-profiling/index.mdx
similarity index 97%
rename from src/docs/product/profiling/mobile-app-profiling.mdx
rename to src/docs/product/profiling/mobile-app-profiling/index.mdx
index d3b681afabae8..3e866099fca8d 100644
--- a/src/docs/product/profiling/mobile-app-profiling.mdx
+++ b/src/docs/product/profiling/mobile-app-profiling/index.mdx
@@ -1,6 +1,8 @@
---
title: Mobile App Profiling
-sidebar_order: 3
+sidebar_order: 50
+redirect_from:
+ - /profiling/mobile-app-profiling
description: "Get started with Mobile App Profiling, which allows you to see code-level profiling information for your mobile apps."
---
diff --git a/src/docs/product/profiling/mobile-app-profiling/metrics.mdx b/src/docs/product/profiling/mobile-app-profiling/metrics.mdx
new file mode 100644
index 0000000000000..fa01407b3be82
--- /dev/null
+++ b/src/docs/product/profiling/mobile-app-profiling/metrics.mdx
@@ -0,0 +1,29 @@
+---
+title: Metrics
+sidebar_order: 50
+redirect_from:
+ - /profiling/mobile-app-profiling/metrics/
+description: "Measurements taken by the Sentry profiler that help us contextualize the work your mobile app does and detect possible issues impacting performance."
+---
+
+The Sentry profiler records several system measurements to help analyze the backtraces it gathers. Some, like CPU and heap usage, are taken on a regular sampling interval using functions from `mach/mach.h`, albeit with a lower frequency than backtrace sampling. Others, like GPU information, are taken from `CADisplayLink` callback invocations, as they're received.
+
+## CPU Usage
+
+The amount of CPU used by the app process, (as a scaled percentage of total CPU capacity, which varies depending on the number of cores), is measured every 100 ms. The value is calculated using `thread_info` with `THREAD_BASIC_INFO`, which returns a CPU usage value per thread and sums up the values for all current threads.
+
+## Heap Usage
+
+The amount of heap memory used by the application is recorded every 100 ms using `task_info` with `TASK_VM_INFO`.
+
+## GPU Information
+
+In addition to counting the number of [slow and frozen UI frame renders](/product/performance/mobile-vitals/#slow-and-frozen-frames) for Mobile Vitals, Sentry now records the timestamp for every frame and overlays it on top of profiling flame charts:
+
+![Sentry displays slow and frozen frames above the flamechart of a particular profile.](./flamechart-with-gpu-overlay.png)
+
+The profiler records the current frame rate upon start, and then any time it changes, (for example if a user puts their device into low-power mode).
+
+## Energy Usage
+
+The amount of energy expended by CPU work allocated to the app process is calculated every 100 ms using `task_info` with `TASK_POWER_INFO_V2`.
diff --git a/src/docs/product/sentry-basics/tracing/trace-view.mdx b/src/docs/product/sentry-basics/tracing/trace-view.mdx
index 559ad390eb162..b34dbb970c86d 100644
--- a/src/docs/product/sentry-basics/tracing/trace-view.mdx
+++ b/src/docs/product/sentry-basics/tracing/trace-view.mdx
@@ -40,7 +40,7 @@ Also, in these cases you can click "Open In Discover" to see all the events in t
Broken subtraces may be caused by:
-- SDK sampling. Setting a sample rate that's too low may prevent the SDK from sending a transaction. [We recommend sending us all of your transaction data](/product/sentry-basics/sampling/).
+- SDK sampling. Setting a sample rate that's too low may prevent the SDK from sending a transaction. We recommend [sending us all of your transaction data](/product/performance/retention-priorities/#deciding-on-your-sdk-sample-rate).
- [Ad blockers](/platforms/javascript/troubleshooting/#dealing-with-ad-blockers) may prevent transactions in browsers being sent, but HTTP requests to backend projects will still create child transactions
- [Rate-limiting](/product/accounts/quotas/#limiting-events) on a project may cause only some events to be sent to Sentry
- [Project permissions](/product/accounts/membership/#restricting-access) may mean you do not have access to transactions in another project
diff --git a/src/gatsby/utils/resolveOpenAPI.ts b/src/gatsby/utils/resolveOpenAPI.ts
index 90f1745243ca4..0204e200cb622 100644
--- a/src/gatsby/utils/resolveOpenAPI.ts
+++ b/src/gatsby/utils/resolveOpenAPI.ts
@@ -6,7 +6,7 @@ import {promises as fs} from 'fs';
// SENTRY_API_SCHEMA_SHA is used in the sentry-docs GHA workflow in getsentry/sentry-api-schema.
// DO NOT change variable name unless you change it in the sentry-docs GHA workflow in getsentry/sentry-api-schema.
-const SENTRY_API_SCHEMA_SHA = '0fc080ddbc055ec01c65a50aa00617b10fb62c58';
+const SENTRY_API_SCHEMA_SHA = 'db5ca15cbf931352e049f113e5e325522d96e33c';
const activeEnv = process.env.GATSBY_ENV || process.env.NODE_ENV || 'development';
diff --git a/src/includes/sentry-cli-sourcemaps.mdx b/src/includes/sentry-cli-sourcemaps.mdx
index e0616640c1679..737274ec9eb6a 100644
--- a/src/includes/sentry-cli-sourcemaps.mdx
+++ b/src/includes/sentry-cli-sourcemaps.mdx
@@ -82,7 +82,8 @@ sentry-cli sourcemaps upload --release= /path/to/directory
-Running `upload` with `--release` **doesn't automatically create a release in Sentry**. For that, you should create a release with the same name as a separate step in your pipeline or send the first event to Sentry with that release.
+Running `upload` with `--release` **doesn't automatically create a release in Sentry**.
+Either wait until the first event with the new release set in `Sentry.init` is sent to Sentry, or create a release with the same name in a separate step [with the CLI](/product/cli/releases).
diff --git a/src/platform-includes/configuration/before-send-transaction/go.mdx b/src/platform-includes/configuration/before-send-transaction/go.mdx
index ae21e0dd3061d..4819881a02f69 100644
--- a/src/platform-includes/configuration/before-send-transaction/go.mdx
+++ b/src/platform-includes/configuration/before-send-transaction/go.mdx
@@ -12,4 +12,5 @@ sentry.Init(sentry.ClientOptions{
event.Message += " [example]"
return event
},
+})
```
diff --git a/src/platform-includes/configuration/ignore-errors/go.mdx b/src/platform-includes/configuration/ignore-errors/go.mdx
new file mode 100644
index 0000000000000..a4cdf095aa672
--- /dev/null
+++ b/src/platform-includes/configuration/ignore-errors/go.mdx
@@ -0,0 +1,6 @@
+```go
+sentry.Init(sentry.ClientOptions{
+ // ...
+ IgnoreErrors: []string{"my-error", "error-*"},
+})
+```
diff --git a/src/platform-includes/configuration/ignore-transactions/go.mdx b/src/platform-includes/configuration/ignore-transactions/go.mdx
new file mode 100644
index 0000000000000..8941b39a48c97
--- /dev/null
+++ b/src/platform-includes/configuration/ignore-transactions/go.mdx
@@ -0,0 +1,6 @@
+```go
+sentry.Init(sentry.ClientOptions{
+ // ...
+ IgnoreTransactions: []string{"/home", "/check-*"},
+})
+```
diff --git a/src/platform-includes/getting-started-config/javascript.remix.mdx b/src/platform-includes/getting-started-config/javascript.remix.mdx
index d898d22674faa..eac0be07a843f 100644
--- a/src/platform-includes/getting-started-config/javascript.remix.mdx
+++ b/src/platform-includes/getting-started-config/javascript.remix.mdx
@@ -1,185 +1,2 @@
-To use this SDK, initialize Sentry in your Remix entry points for both the client and server.
-
-Create two files in the root directory of your project, `entry.client.tsx` and `entry.server.tsx` (if they don't exist yet). In these files, add your initialization code for the client-side SDK and server-side SDK, respectively.
-
-The two configuration types are mostly the same, except that some configuration features, like Session Replay, only work in `entry.client.tsx`.
-
-
-
-```typescript {tabTitle:Client} {filename: entry.client.tsx}
-import { useLocation, useMatches } from "@remix-run/react";
-import * as Sentry from "@sentry/remix";
-import { useEffect } from "react";
-
-Sentry.init({
- dsn: "___PUBLIC_DSN___",
- integrations: [
- new Sentry.BrowserTracing({
- routingInstrumentation: Sentry.remixRouterInstrumentation(
- useEffect,
- useLocation,
- useMatches
- ),
- }),
- // Replay is only available in the client
- new Sentry.Replay(),
- ],
-
- // Set tracesSampleRate to 1.0 to capture 100%
- // of transactions for performance monitoring.
- // We recommend adjusting this value in production
- tracesSampleRate: 1.0,
-
- // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled
- tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/],
-
- // Capture Replay for 10% of all sessions,
- // plus for 100% of sessions with an error
- replaysSessionSampleRate: 0.1,
- replaysOnErrorSampleRate: 1.0,
-});
-```
-
-```typescript {tabTitle:Server} {filename: entry.server.tsx}
-import { useLocation, useMatches } from "@remix-run/react";
-import * as Sentry from "@sentry/remix";
-import { useEffect } from "react";
-
-Sentry.init({
- dsn: "___PUBLIC_DSN___",
-
- // Set tracesSampleRate to 1.0 to capture 100%
- // of transactions for performance monitoring.
- // We recommend adjusting this value in production
- tracesSampleRate: 1.0,
-});
-```
-
-Initialize Sentry in your entry point for the server to capture exceptions and get performance metrics for your [`action`](https://remix.run/docs/en/v1/api/conventions#action) and [`loader`](https://remix.run/docs/en/v1/api/conventions#loader) functions. You can also initialize Sentry's database integrations, such as Prisma, to get spans for your database calls.
-
-To catch React component errors (in Remix v1) and routing transactions, wrap your Remix root with `withSentry`.
-
-
-
-If you use the Remix `v2_errorBoundary` future flag, you must also configure a [v2 ErrorBoundary](#v2-errorboundary).
-
-
-
-```typescript {filename: root.tsx}
-import {
- Links,
- LiveReload,
- Meta,
- Outlet,
- Scripts,
- ScrollRestoration,
-} from "@remix-run/react";
-
-import { withSentry } from "@sentry/remix";
-
-function App() {
- return (
-
-
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-export default withSentry(App);
-```
-
-You can disable or configure `ErrorBoundary` using a second parameter to `withSentry`.
-
-```typescript
-withSentry(App, {
- wrapWithErrorBoundary: false,
-});
-
-// or
-
-withSentry(App, {
- errorBoundaryOptions: {
- fallback:
An error has occurred
,
- },
-});
-```
-
-## Custom Express Server
-
-If you use a custom Express server in your Remix application, you should wrap your [`createRequestHandler` function](https://remix.run/docs/en/v1/other-api/adapter#createrequesthandler) manually with `wrapExpressCreateRequestHandler`. This is not required if you use the built-in Remix App Server.
-
-
-
-`wrapExpressCreateRequestHandler` is available starting with version 7.11.0.
-
-
-
-```typescript {filename: server/index.ts}
-import { wrapExpressCreateRequestHandler } from "@sentry/remix";
-import { createRequestHandler } from "@remix-run/express";
-
-// ...
-
-const createSentryRequestHandler =
- wrapExpressCreateRequestHandler(createRequestHandler);
-
-// Use createSentryRequestHandler like you would with createRequestHandler
-app.all("*", createSentryRequestHandler(/* ... */));
-```
-
-## Remix v2 features
-
-_Available from SDK version 7.59.0_
-
-[Remix v2](https://remix.run/docs/en/main/pages/v2) will introduce new features that require additional configuration to work with Sentry. These features are also available from version [1.17.0](https://github.com/remix-run/remix/releases/tag/remix%401.17.0) with [future flags](https://remix.run/docs/en/main/pages/api-development-strategy#current-future-flags).
-
-### v2 ErrorBoundary
-
-To capture errors from [v2 ErrorBoundary](https://remix.run/docs/en/main/route/error-boundary-v2), you should define your own `ErrorBoundary` in `root.tsx` and use `Sentry.captureRemixErrorBoundaryError` inside of it. You can also create route-specific error capturing behaviour by defining `ErrorBoundary` in your route components. The `ErrorBoundary` you define in `root.tsx` will be used as a fallback for all routes.
-
-```typescript {filename: root.tsx}
-import { captureRemixErrorBoundaryError } from "@sentry/remix";
-
-export const ErrorBoundary: V2_ErrorBoundaryComponent = () => {
- const error = useRouteError();
-
- captureRemixErrorBoundaryError(error);
-
- return
...
;
-};
-```
-
-## v2 Server-side Errors
-
-When using `v2_errorBoundary` future flag, Sentry can't capture your server-side errors automatically. Instead, define a [`handleError`](https://remix.run/docs/en/main/file-conventions/entry.server#handleerror) function in your server entry point. Then, you should use `Sentry.captureRemixServerError` to capture errors in your server-side code.
-
-```typescript {filename: entry.server.tsx}
-export function handleError(
- error: unknown,
- { request }: DataFunctionArgs
-): void {
- if (error instanceof Error) {
- Sentry.captureRemixServerException(error, "remix.server", request);
- } else {
- // Optionally capture non-Error objects
- Sentry.captureException(error);
- }
-}
-```
-
-Once you've done this set up, the SDK will automatically capture unhandled errors and promise rejections, and monitor performance in the client. You can also [manually capture errors](/platforms/javascript/guides/remix/usage).
-
-
-
-You can refer to [Remix Docs](https://remix.run/docs/en/v1/guides/envvars#browser-environment-variables) to learn how to use your Sentry DSN from environment variables.
-
-
+To complete your configuration, add options to your `Sentry.init()` calls.
+Here, you'll also be able to set context data, which includes data about the user, tags, or even arbitrary data, all of which will be added to every event sent to Sentry.
diff --git a/src/platform-includes/getting-started-config/python.flask.mdx b/src/platform-includes/getting-started-config/python.flask.mdx
deleted file mode 100644
index a97d01e665234..0000000000000
--- a/src/platform-includes/getting-started-config/python.flask.mdx
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-```python
-import sentry_sdk
-from flask import Flask
-
-sentry_sdk.init(
- dsn="___PUBLIC_DSN___",
-
- # Set traces_sample_rate to 1.0 to capture 100%
- # of transactions for performance monitoring.
- # We recommend adjusting this value in production.
- traces_sample_rate=1.0,
-
- # By default the SDK will try to use the SENTRY_RELEASE
- # environment variable, or infer a git commit
- # SHA as release, however you may want to set
- # something more human-readable.
- # release="myapp@1.0.0",
-)
-
-app = Flask(__name__)
-```
diff --git a/src/platform-includes/getting-started-install/javascript.remix.mdx b/src/platform-includes/getting-started-install/javascript.remix.mdx
index fec7751e1b4ab..7f5b2b30458b1 100644
--- a/src/platform-includes/getting-started-install/javascript.remix.mdx
+++ b/src/platform-includes/getting-started-install/javascript.remix.mdx
@@ -1,7 +1,23 @@
-```bash {tabTitle:npm}
-npm install --save @sentry/remix
-```
+We recommend installing the SDK through our installation wizard:
-```bash {tabTitle:Yarn}
-yarn add @sentry/remix
+```bash
+npx @sentry/wizard@latest -i remix
```
+
+The wizard will prompt you to log in to Sentry. It will then automatically do the following steps for you:
+
+- create two files in the root directory of your project, `entry.client.tsx` and `entry.server.tsx` (if they don't already exist).
+- add the default `Sentry.init()` for the client in `entry.client.tsx` and the server in `entry.server.tsx`.
+- create `.sentryclirc` with an auth token to upload source maps (this file is automatically added to `.gitignore`).
+- adjust your `build` script in `package.json` to automatically upload source maps to Sentry when you build your application.
+
+If you use [Remix future flags](https://remix.run/docs/en/main/pages/api-development-strategy#current-future-flags), the wizard will instrument your application accordingly to support Remix v2 features.
+
+After the wizard setup is completed, the SDK will automatically capture unhandled errors, and monitor performance.
+You can also manually capture errors.
+
+
+
+If the wizard setup isn't working for you, you can set up the SDK manually.
+
+
diff --git a/src/platform-includes/getting-started-install/python.flask.mdx b/src/platform-includes/getting-started-install/python.flask.mdx
deleted file mode 100644
index c9e56c3f4f04b..0000000000000
--- a/src/platform-includes/getting-started-install/python.flask.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-Install `sentry-sdk` from PyPI with the `flask` extra:
-
-```bash
-pip install --upgrade 'sentry-sdk[flask]'
-```
diff --git a/src/platform-includes/getting-started-primer/python.flask.mdx b/src/platform-includes/getting-started-primer/python.flask.mdx
deleted file mode 100644
index 30ef372a0bd42..0000000000000
--- a/src/platform-includes/getting-started-primer/python.flask.mdx
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-Our Python SDK will install the Flask integration for all of your apps. It hooks into Flaskās signals, not anything on the app object. Each request has a separate scope. Changes to the scope within a view, for example setting a tag, will only apply to events sent as part of the request being handled.
-
-
diff --git a/src/platform-includes/getting-started-verify/python.flask.mdx b/src/platform-includes/getting-started-verify/python.flask.mdx
deleted file mode 100644
index cf823e375b369..0000000000000
--- a/src/platform-includes/getting-started-verify/python.flask.mdx
+++ /dev/null
@@ -1,11 +0,0 @@
-```python
-@app.route('/debug-sentry')
-def trigger_error():
- division_by_zero = 1 / 0
-```
-
-After initialization:
-
-- If you use `flask-login` and have set `send_default_pii=True` in your call to `init`, user data (current user id, email address, username) is attached to the event.
-- Request data is attached to all events: **HTTP method, URL, headers, form data, JSON payloads**. Sentry excludes raw bodies and multipart file uploads.
-- Logs emitted by `app.logger` or _any_ logger are recorded as breadcrumbs by the [Logging](/platforms/python/guides/logging/) integration (this integration is enabled by default).
diff --git a/src/platform-includes/performance/add-spans-example/go.mdx b/src/platform-includes/performance/add-spans-example/go.mdx
index 7590a1638cb55..fddf909140ae0 100644
--- a/src/platform-includes/performance/add-spans-example/go.mdx
+++ b/src/platform-includes/performance/add-spans-example/go.mdx
@@ -1,15 +1,18 @@
## Add More Spans to the Transaction
-The next example contains the implementation of the hypothetical `doWork` function called from the code snippet in the previous section. Our SDK can determine if there is currently an open transaction in the current context and add all newly created spans as child operations to that transaction. Keep in mind that each individual span also needs to be manually finished; otherwise, spans will not show up in the transaction.
-
-You can choose the value of `operation` and `description`.
+The next example contains the implementation of the hypothetical `doWork` function called from the code snippet in the previous section. Our SDK can determine if there is currently an open transaction in the current context and add all newly created spans as child operations to that transaction. Keep in mind that each individual span also needs to be manually finished. Otherwise, spans will not show up on the transaction.
```go
-func doWork(ctx context.Context, item Item) {
- span := sentry.StartSpan(ctx, "suboperation1")
+func doWork(ctx context.Context) {
+ // Set the OP based on values from https://develop.sentry.dev/sdk/performance/span-operations/
+ span := sentry.StartSpan(ctx, "function")
+ span.Description = "suboperation1"
// omitted code ...
span.Finish()
- span := sentry.StartSpan(ctx, "suboperation2")
+
+ // Set the OP based on values from https://develop.sentry.dev/sdk/performance/span-operations/
+ span := sentry.StartSpan(ctx, "function")
+ span.Description = "suboperation2"
// omitted code ...
span.Finish()
}
diff --git a/src/platform-includes/performance/enable-manual-instrumentation/go.mdx b/src/platform-includes/performance/enable-manual-instrumentation/go.mdx
index 8e877730c43bc..33df391622eb7 100644
--- a/src/platform-includes/performance/enable-manual-instrumentation/go.mdx
+++ b/src/platform-includes/performance/enable-manual-instrumentation/go.mdx
@@ -1,14 +1,30 @@
To instrument certain regions of your code, you can create transactions to capture them.
-The following example creates a transaction span to time runs of an expensive operation on items from a channel. Timing for each operation is sent to Sentry and grouped by transaction name:
+The following example creates a transaction based on an incoming request:
```go
-ctx := context.Background()
-
-for item := range ch {
- span := sentry.StartSpan(ctx, "doWork",
- sentry.WithTransactionName(fmt.Sprintf("doWork: %s", item.Type)))
- doWork(span.Context(), item) // doWork may create additional spans
- span.Finish()
-}
+http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
+ ctx := r.Context()
+ hub := sentry.GetHubFromContext(ctx)
+ if hub == nil {
+ // Check the concurrency guide for more details: https://docs.sentry.io/platforms/go/concurrency/
+ hub = sentry.CurrentHub().Clone()
+ ctx = sentry.SetHubOnContext(ctx, hub)
+ }
+
+ options := []sentry.SpanOption{
+ // Set the OP based on values from https://develop.sentry.dev/sdk/performance/span-operations/
+ sentry.WithOpName("http.server"),
+ sentry.ContinueFromRequest(r),
+ sentry.WithTransactionSource(sentry.SourceURL),
+ }
+
+ transaction := sentry.StartTransaction(ctx,
+ fmt.Sprintf("%s %s", r.Method, r.URL.Path),
+ options...,
+ )
+ defer transaction.Finish()
+
+ doWork(transaction.Context());
+})
```
diff --git a/src/platform-includes/performance/traces-sampler-as-filter/go.mdx b/src/platform-includes/performance/traces-sampler-as-filter/go.mdx
index fd9cfb80b3212..78fb2e7f00392 100644
--- a/src/platform-includes/performance/traces-sampler-as-filter/go.mdx
+++ b/src/platform-includes/performance/traces-sampler-as-filter/go.mdx
@@ -1,5 +1,5 @@
```go
-err := sentry.Init(sentry.ClientOptions{
+sentry.Init(sentry.ClientOptions{
// ...
TracesSampler: sentry.TracesSampler(func(ctx sentry.SamplingContext) float64 {
if condition {
diff --git a/src/platform-includes/sourcemaps/overview/javascript.vue.mdx b/src/platform-includes/sourcemaps/overview/javascript.vue.mdx
index 016fc16e3c03e..8345a9725d4ee 100644
--- a/src/platform-includes/sourcemaps/overview/javascript.vue.mdx
+++ b/src/platform-includes/sourcemaps/overview/javascript.vue.mdx
@@ -1,4 +1,4 @@
-## Uploading Source Maps using Vite
+## Uploading Source Maps in a Vue Project
@@ -8,10 +8,20 @@ If you are on an older version and you want to upload source maps we recommend u
+### Using the Sentry Wizard
+
+The easiest and recommended way to configure uploading source maps is by using the Sentry Wizard:
+
+
+
+If you want to configure source maps upload manually, follow the guide for your bundler or build tool below.
+
+### Manual Setup with Vite
+
If you are using Vue, chances are good you are using Vite to bundle your project.
You can use the Sentry Vite plugin to automatically create [releases](/product/releases/) and upload source maps to Sentry when bundling your app.
-### Installation
+#### Installation
```bash {tabTitle:npm}
npm install @sentry/vite-plugin --save-dev
@@ -21,7 +31,7 @@ npm install @sentry/vite-plugin --save-dev
yarn add @sentry/vite-plugin --dev
```
-### Configuration
+#### Configuration
Learn more about configuring the plugin in our [Sentry Vite Plugin documentation](https://www.npmjs.com/package/@sentry/vite-plugin).
@@ -69,11 +79,11 @@ We recommend running a production build to test your implementation.
-## Other Bundlers
+### Other Bundlers
In case you are using a bundler other than Vite to build your Vue project, we've compiled a list of guides on how to upload source maps to Sentry for the most popular JavaScript bundlers:
-- webpack
+- Webpack
-
TypeScript (tsc)
diff --git a/src/platforms/common/configuration/filtering.mdx b/src/platforms/common/configuration/filtering.mdx
index 22cc95c081523..a7d261f7f4849 100644
--- a/src/platforms/common/configuration/filtering.mdx
+++ b/src/platforms/common/configuration/filtering.mdx
@@ -75,7 +75,7 @@ In this example, the fingerprint is forced to a common value if an exception of
-
+
### Using
@@ -120,7 +120,7 @@ Learn more about configuring the sam
-
+
### Using
diff --git a/src/platforms/common/configuration/options.mdx b/src/platforms/common/configuration/options.mdx
index b2c4ac66aa877..5ce8554e4dafc 100644
--- a/src/platforms/common/configuration/options.mdx
+++ b/src/platforms/common/configuration/options.mdx
@@ -211,12 +211,12 @@ When enabled, stack traces are automatically attached to all messages logged. St
-This option is `on` by default.
+This option is turned on by default.
-This option is `off` by default.
+This option is turned off by default.
@@ -234,7 +234,7 @@ If you are using Sentry in your mobile app, read our [frequently asked questions
-This option is `off` by default.
+This option is turned off by default.
If you enable this option, be sure to manually remove what you don't want to send using our features for managing [_Sensitive Data_](../../data-management/sensitive-data/).
@@ -242,7 +242,7 @@ If you enable this option, be sure to manually remove what you don't want to sen
-If is `off`, scrubs the event payload for sensitive information from a `denylist`. See how to [configure the scrubber here](../../data-management/sensitive-data/#event-scrubber).
+If is turned off, scrubs the event payload for sensitive information from a `denylist`. See how to [configure the scrubber here](../../data-management/sensitive-data/#event-scrubber).
diff --git a/src/platforms/common/crons/index.mdx b/src/platforms/common/crons/index.mdx
index 614d7cc6d42d9..51701ea694ddc 100644
--- a/src/platforms/common/crons/index.mdx
+++ b/src/platforms/common/crons/index.mdx
@@ -200,46 +200,6 @@ It's important to provide a timezone for non-repeating crontab schedules, such a
-### Check-in Attachment (Optional)
-
-Sentry Crons can help you better understand your job check-ins by storing a file, such as a log output. You'll be able to use this to debug check-in failures or track job statuses. To upload your attachment, execute the following `HTTP POST (multipart/form-data)` request:
-
-
-
-```bash {tabTitle: curl}
-# Perform a POST request to attach a file to a check-in
-curl -X POST \
- 'https://sentry.io/api/0/organizations/___ORG_SLUG___/monitors//checkins/latest/attachment/' \
- --header 'Authorization: DSN ___PUBLIC_DSN___' \
- --form 'file='
-```
-
-```http {tabTitle: HTTP}
-POST /api/0/organizations/___ORG_SLUG___/monitors//checkins/latest/attachment/ HTTP/1.1
-Host: sentry.io
-Authorization: DSN ___PUBLIC_DSN___
-Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
-
-------WebKitFormBoundary7MA4YWxkTrZu0gW
-Content-Disposition: form-data; name="file"
-
-
-------WebKitFormBoundary7MA4YWxkTrZu0gW--
-```
-
-
- We recommend uploading your attachment before you complete your second
- check-in.
-
-
-Attachments can be downloaded in each corresponding check-in on your āMonitor Detailsā page.
-
-Current attachment limitations:
-
-1. Each job is limited to one attachment.
-2. The maximum file size is 100kb.
-3. Attachments aren't currently supported by our CLI or SDKs.
-
### Overlapping Jobs (Optional)
A job execution that begins before the previous job execution has been completed is called an overlapping job. This happens if you have a job with a runtime duration longer than your job's interval schedule.
diff --git a/src/platforms/common/profiling/index.mdx b/src/platforms/common/profiling/index.mdx
index 2ca7d8b1da118..b85d6e08f991d 100644
--- a/src/platforms/common/profiling/index.mdx
+++ b/src/platforms/common/profiling/index.mdx
@@ -168,7 +168,7 @@ By default, some transactions will be created automatically for common operation
-iOS profiling is available starting in SDK version `8.3.1`.
+iOS profiling is available starting in SDK version `8.12.0`.
diff --git a/src/platforms/dotnet/guides/aspnet/performance/troubleshooting.mdx b/src/platforms/dotnet/guides/aspnet/performance/troubleshooting.mdx
new file mode 100644
index 0000000000000..44681c186bbce
--- /dev/null
+++ b/src/platforms/dotnet/guides/aspnet/performance/troubleshooting.mdx
@@ -0,0 +1,31 @@
+---
+title: Troubleshooting
+sidebar_order: 100
+description: "Learn more about how to troubleshoot performance issues with the ASP.NET SDK."
+---
+
+## Transactions get grouped together as `GET /*/*.`
+
+The SDK creates the transaction name as follows
+
+```csharp
+var method = httpContext.Request.HttpMethod;
+var path = httpContext.Request.Path;
+
+var transactionName = $"{method} {path}";
+
+// Since the name is derived from the path and potentially contains identifiers it is marked as such
+transactionContext.NameSource = TransactionNameSource.Url;
+```
+
+Since the `URL` might contain potential identifiers, such as `GET /users/123`, the backend tries to remove values with high variations. Leading it to `GET /users/*`. Sometimes, when there are many paths, it can result in `GET /*/*`.
+It is possible to work around this and still rely on automatic performance instrumentation. You can access the currently active transaction and overwrite the `Name` and `NameSource`. Specifying the exact name of the transaction, without any variables. Using the example above, it would look like:
+
+```csharp
+if (SentrySdk.GetSpan()?.GetTransaction() is TransactionTracer transactionTracer)
+{
+ transactionTracer.NameSource = TransactionNameSource.Custom;
+ transactionTracer.Name = "GET /users/{id}";
+}
+
+```
diff --git a/src/platforms/go/common/configuration/options.mdx b/src/platforms/go/common/configuration/options.mdx
index 27a709e4c0b16..187557ac3dfc6 100644
--- a/src/platforms/go/common/configuration/options.mdx
+++ b/src/platforms/go/common/configuration/options.mdx
@@ -34,10 +34,16 @@ type ClientOptions struct {
TracesSampleRate float64
// Used to customize the sampling of traces, overrides TracesSampleRate.
TracesSampler TracesSampler
+ // The sample rate for profiling traces in the range [0.0, 1.0].
+ // This is relative to TracesSampleRate - it is a ratio of profiled traces out of all sampled traces.
+ ProfilesSampleRate float64
// List of regexp strings that will be used to match against event's message
// and if applicable, caught errors type and value.
// If the match is found, then a whole event will be dropped.
IgnoreErrors []string
+ // List of regexp strings that will be used to match against a transaction's
+ // name. If a match is found, then the transaction will be dropped.
+ IgnoreTransactions []string
// If this flag is enabled, certain personally identifiable information (PII) is added by active integrations.
// By default, no such data is sent.
SendDefaultPII bool
diff --git a/src/platforms/javascript/guides/remix/manual-setup.mdx b/src/platforms/javascript/guides/remix/manual-setup.mdx
new file mode 100644
index 0000000000000..20a2c659f2fca
--- /dev/null
+++ b/src/platforms/javascript/guides/remix/manual-setup.mdx
@@ -0,0 +1,211 @@
+---
+title: Manual Setup
+sidebar_order: 1
+description: "Learn how to set up the SDK manually."
+---
+
+If you can't (or prefer not to) run the [automatic setup](/platforms/javascript/guides/remix/#install), you can follow the instructions below to configure your application.
+
+## Installation
+
+Get started by installing the Sentry Remix SDK:
+
+```bash {tabTitle:npm}
+npm install --save @sentry/remix
+```
+
+```bash {tabTitle:Yarn}
+yarn add @sentry/remix
+```
+
+```bash {tabTitle:pnpm}
+pnpm add @sentry/remix
+```
+
+## Configuration
+
+To use this SDK, initialize Sentry in your Remix entry points for both the client and server.
+
+Create two files in the root directory of your project, `entry.client.tsx` and `entry.server.tsx` (if they don't already exist). Add your initialization code in these files for the client-side and server-side SDK, respectively.
+
+The two configuration types are mostly the same, except that some configuration features, like Session Replay, only work in `entry.client.tsx`.
+
+
+
+```typescript {tabTitle:Client} {filename: entry.client.tsx}
+import { useLocation, useMatches } from "@remix-run/react";
+import * as Sentry from "@sentry/remix";
+import { useEffect } from "react";
+
+Sentry.init({
+ dsn: "___PUBLIC_DSN___",
+ integrations: [
+ new Sentry.BrowserTracing({
+ routingInstrumentation: Sentry.remixRouterInstrumentation(
+ useEffect,
+ useLocation,
+ useMatches
+ ),
+ }),
+ // Replay is only available in the client
+ new Sentry.Replay(),
+ ],
+
+ // Set tracesSampleRate to 1.0 to capture 100%
+ // of transactions for performance monitoring.
+ // We recommend adjusting this value in production
+ tracesSampleRate: 1.0,
+
+ // Set `tracePropagationTargets` to control for which URLs distributed tracing should be enabled
+ tracePropagationTargets: ["localhost", /^https:\/\/yourserver\.io\/api/],
+
+ // Capture Replay for 10% of all sessions,
+ // plus for 100% of sessions with an error
+ replaysSessionSampleRate: 0.1,
+ replaysOnErrorSampleRate: 1.0,
+});
+```
+
+```typescript {tabTitle:Server} {filename: entry.server.tsx}
+import { useLocation, useMatches } from "@remix-run/react";
+import * as Sentry from "@sentry/remix";
+import { useEffect } from "react";
+
+Sentry.init({
+ dsn: "___PUBLIC_DSN___",
+
+ // Set tracesSampleRate to 1.0 to capture 100%
+ // of transactions for performance monitoring.
+ // We recommend adjusting this value in production
+ tracesSampleRate: 1.0,
+});
+```
+
+Initialize Sentry in your entry point for the server to capture exceptions and get performance metrics for your [`action`](https://remix.run/docs/en/main/route/action) and [`loader`](https://remix.run/docs/en/main/route/loader) functions. You can also initialize Sentry's database integrations, such as Prisma, to get spans for your database calls.
+
+To catch React component errors (in Remix v1) and routing transactions, wrap your Remix root with `withSentry`.
+
+
+
+If you use the Remix `v2_errorBoundary` future flag, you must also configure a [v2 ErrorBoundary](#v2-errorboundary).
+
+
+
+```typescript {filename: root.tsx}
+import {
+ Links,
+ LiveReload,
+ Meta,
+ Outlet,
+ Scripts,
+ ScrollRestoration,
+} from "@remix-run/react";
+
+import { withSentry } from "@sentry/remix";
+
+function App() {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default withSentry(App);
+```
+
+You can disable or configure `ErrorBoundary` using a second parameter to `withSentry`.
+
+```typescript
+withSentry(App, {
+ wrapWithErrorBoundary: false,
+});
+
+// or
+
+withSentry(App, {
+ errorBoundaryOptions: {
+ fallback:
An error has occurred
,
+ },
+});
+```
+
+## Remix v2 Features
+
+_Available from SDK version 7.59.0_
+
+[Remix v2](https://remix.run/docs/en/main/pages/v2) will introduce new features that require additional configuration to work with Sentry. These features are also available from version [1.17.0](https://github.com/remix-run/remix/releases/tag/remix%401.17.0) with [future flags](https://remix.run/docs/en/main/pages/api-development-strategy#current-future-flags).
+
+### v2 ErrorBoundary
+
+To capture errors from [v2 ErrorBoundary](https://remix.run/docs/en/main/route/error-boundary-v2), you should define your own `ErrorBoundary` in `root.tsx` and use `Sentry.captureRemixErrorBoundaryError` inside of it. You can also create route-specific error capturing behavior by defining `ErrorBoundary` in your route components. The `ErrorBoundary` you define in `root.tsx` will be used as a fallback for all routes.
+
+```typescript {filename: root.tsx}
+import { captureRemixErrorBoundaryError } from "@sentry/remix";
+
+export const ErrorBoundary: V2_ErrorBoundaryComponent = () => {
+ const error = useRouteError();
+
+ captureRemixErrorBoundaryError(error);
+
+ return
...
;
+};
+```
+
+## v2 Server-side Errors
+
+Sentry won't be able to capture your server-side errors automatically if you're using the`v2_errorBoundary` future flag. To work around this, define a [`handleError`](https://remix.run/docs/en/main/file-conventions/entry.server#handleerror) function in your server entry point. Then use `Sentry.captureRemixServerError` to capture errors in your server-side code.
+
+```typescript {filename: entry.server.tsx}
+export function handleError(
+ error: unknown,
+ { request }: DataFunctionArgs
+): void {
+ if (error instanceof Error) {
+ Sentry.captureRemixServerException(error, "remix.server", request);
+ } else {
+ // Optionally capture non-Error objects
+ Sentry.captureException(error);
+ }
+}
+```
+
+After you've completed this setup, the SDK will automatically capture unhandled errors and promise rejections, and monitor performance in the client. You can also [manually capture errors](/platforms/javascript/guides/remix/usage).
+
+
+
+You can refer to [Remix Docs](https://remix.run/docs/en/v1/guides/envvars#browser-environment-variables) to learn how to use your Sentry DSN with environment variables.
+
+
+
+## Custom Express Server
+
+If you use a custom Express server in your Remix application, you should wrap your [`createRequestHandler` function](https://remix.run/docs/en/v1/other-api/adapter#createrequesthandler) manually with `wrapExpressCreateRequestHandler`. This isn't necessary if you're using the built-in Remix App Server.
+
+
+
+`wrapExpressCreateRequestHandler` is available starting with version 7.11.0.
+
+
+
+```typescript {filename: server/index.ts}
+import { wrapExpressCreateRequestHandler } from "@sentry/remix";
+import { createRequestHandler } from "@remix-run/express";
+
+// ...
+
+const createSentryRequestHandler =
+ wrapExpressCreateRequestHandler(createRequestHandler);
+
+// Use createSentryRequestHandler like you would with createRequestHandler
+app.all("*", createSentryRequestHandler(/* ... */));
+```
diff --git a/src/platforms/php/guides/laravel/other-versions/index.mdx b/src/platforms/php/guides/laravel/other-versions/index.mdx
index d56c33657eba9..2b2a5cdbebfa1 100644
--- a/src/platforms/php/guides/laravel/other-versions/index.mdx
+++ b/src/platforms/php/guides/laravel/other-versions/index.mdx
@@ -1,5 +1,7 @@
---
title: Other Versions
+redirect_from:
+ - /platforms/php/guides/laravel/other-versions/laravel5-6-7/
description: "Learn about using Sentry with Laravel Lumen or Laravel 4.x/5.x/6.x/7.x."
---
diff --git a/src/platforms/python/common/configuration/integrations/gnu_backtrace.mdx b/src/platforms/python/common/configuration/integrations/gnu_backtrace.mdx
index f37695b2986f5..d99cf3d8e18fb 100644
--- a/src/platforms/python/common/configuration/integrations/gnu_backtrace.mdx
+++ b/src/platforms/python/common/configuration/integrations/gnu_backtrace.mdx
@@ -4,20 +4,14 @@ description: "Learn about the GNU backtrace integration and how to add it to you
sidebar_order: 50
---
-
-
The GNU backtrace integration parses native stack trace produced by [`backtrace_symbols`](https://linux.die.net/man/3/backtrace_symbols) from error messages and concatenates them with the Python traceback.
It is currently tested to work with server exceptions raised by [`clickhouse-driver`](https://github.com/mymarilyn/clickhouse-driver).
-
-
-**This integration is experimental.** It may be removed in minor versions. When enabling this integration, expect to see new event groups due to new stack trace frames.
-
-
-
## Install
+Install `sentry-sdk` from PyPI.
+
```bash
pip install --upgrade 'sentry-sdk'
```
@@ -39,3 +33,9 @@ sentry_sdk.init(
],
)
```
+
+## Verify
+
+The GNU backtrace integration is tested with server exceptions raised by [`clickhouse-driver`](https://github.com/mymarilyn/clickhouse-driver).
+
+Other libraries must emit exceptions that have backtrace-compatible values for the GNU backtrace integration to parse the exceptions.
diff --git a/src/platforms/python/common/configuration/integrations/index.mdx b/src/platforms/python/common/configuration/integrations/index.mdx
index 3787c103b76f4..46c3882134202 100644
--- a/src/platforms/python/common/configuration/integrations/index.mdx
+++ b/src/platforms/python/common/configuration/integrations/index.mdx
@@ -46,7 +46,7 @@ If you don't want integrations to be enabled automatically, set the `default_int
- [Cloud Resource Context](cloudresourcecontext/)
- [Enhanced Locals](pure_eval/)
- [GNU Backtrace](gnu_backtrace/)
-- [SOCKET](socket/)
+- [Socket](socket/)
- [WSGI](wsgi/)
## Web Frameworks
diff --git a/src/platforms/python/common/configuration/integrations/pure_eval.mdx b/src/platforms/python/common/configuration/integrations/pure_eval.mdx
index dbc8ea5cd0d27..416a5300da873 100644
--- a/src/platforms/python/common/configuration/integrations/pure_eval.mdx
+++ b/src/platforms/python/common/configuration/integrations/pure_eval.mdx
@@ -4,16 +4,8 @@ description: "Learn about `pure_eval` and how to add it to your integrations lis
sidebar_order: 40
---
-
-
This integration uses [`pure_eval`](https://github.com/alexmojaki/pure_eval) to safely evaluate additional expressions in the source code and display their values alongside other local variables.
-
-
-**This integration is experimental.** It may be removed in minor versions.
-
-
-
## Install
Install `sentry-sdk` from PyPI with the `pure_eval` extra or `pip install pure_eval executing asttokens`.
@@ -40,6 +32,23 @@ sentry_sdk.init(
)
```
+## Verify
+
+```python
+from types import SimpleNamespace
+
+def main():
+ sentry_sdk.init(...) # same as above
+
+ namespace = SimpleNamespace()
+ namespace.d = {1: 2}
+ print(namespace.d[1] / 0)
+
+main()
+```
+
+When you run this example script an error will be sent to Sentry. Through the `PureEvalIntegration` the stack trace of the error will include the values of `namespace.d` and `namespace.d[1]` which would not be shown without `PureEvalIntegration`.
+
## Supported Versions
- Python: 3.5+
diff --git a/src/platforms/python/common/configuration/integrations/socket.mdx b/src/platforms/python/common/configuration/integrations/socket.mdx
index a830ab15f369e..be5795b68a08d 100644
--- a/src/platforms/python/common/configuration/integrations/socket.mdx
+++ b/src/platforms/python/common/configuration/integrations/socket.mdx
@@ -1,14 +1,18 @@
---
-title: SOCKET
+title: Socket
description: "Learn about the Socket integration and how it adds support network actions."
sidebar_order: 90
---
-Use this integration to create spans for dns resolves and connection creations.
+Use this integration to create spans for DNS resolves and socket connection creations.
## Install
-`socket` is included by default in CPython
+Install `sentry-sdk`` from PyPI.
+
+```bash
+pip install --upgrade 'sentry-sdk'
+```
## Configure
@@ -22,12 +26,33 @@ from sentry_sdk.integrations.socket import SocketIntegration
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
integrations=[
SocketIntegration(),
],
)
```
+## Verify
+
+```python
+import socket
+
+def main():
+ sentry_init(...) # same as above
+ with sentry_sdk.start_transaction(name="testing_sentry"):
+ timeout = 10
+ socket.getaddrinfo("sentry.io", 443)
+ socket.create_connection(("sentry.io", 443), timeout, None)
+main()
+```
+
+This example will create a transaction called `testing_sentry` in the Performance section of [sentry.io](https://sentry.io), and create spans for the socket commands.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
+
## Supported Versions
- Python: 2.7+
diff --git a/src/platforms/python/common/configuration/integrations/sqlalchemy.mdx b/src/platforms/python/common/configuration/integrations/sqlalchemy.mdx
index fae39e5f87e76..3407234952deb 100644
--- a/src/platforms/python/common/configuration/integrations/sqlalchemy.mdx
+++ b/src/platforms/python/common/configuration/integrations/sqlalchemy.mdx
@@ -34,7 +34,7 @@ sentry_sdk.init(
)
```
-The Redis integration is enabled automatically if you have the `sqlalchemy` package installed.
+The SQLAlchemy integration is enabled automatically if you have the `sqlalchemy` package installed.
## Verify
diff --git a/src/platforms/python/guides/aiohttp/index.mdx b/src/platforms/python/guides/aiohttp/index.mdx
index e5fe7ce2fe98a..92fa0771ee7e3 100644
--- a/src/platforms/python/guides/aiohttp/index.mdx
+++ b/src/platforms/python/guides/aiohttp/index.mdx
@@ -5,16 +5,14 @@ redirect_from:
description: "Learn about using Sentry with AIOHTTP."
---
-The AIOHTTP integration adds support for the [AIOHTTP-Server Web
-Framework](https://docs.aiohttp.org/en/stable/web.html). A Python version of
-3.6 or greater is required.
+The AIOHTTP integration adds support for the [AIOHTTP-Server Web Framework](https://docs.aiohttp.org/en/stable/web.html).
## Install
-Install `sentry-sdk` from PyPI:
+Install `sentry-sdk` from PyPI with the `aiohttp` extra:
```bash
-pip install --upgrade sentry-sdk
+pip install --upgrade sentry-sdk[aiohttp]
```
If you're on Python 3.6, you also need the `aiocontextvars` package:
@@ -25,28 +23,31 @@ pip install --upgrade aiocontextvars
## Configure
+If you have the `aiohttp` package in your dependencies, the AIOHTTO integration will be enabled automatically when you initialize the Sentry SDK.
+
```python
import sentry_sdk
-from sentry_sdk.integrations.aiohttp import AioHttpIntegration
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
- integrations=[
- AioHttpIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
)
+```
+## Verify
+
+```python
from aiohttp import web
+sentry_sdk.init(...) # same as above
+
async def hello(request):
- return web.Response(text="Hello, world")
+ 1/0 # raises an error
+ return web.Response(text="Hello, world")
app = web.Application()
app.add_routes([web.get('/', hello)])
@@ -54,6 +55,10 @@ app.add_routes([web.get('/', hello)])
web.run_app(app)
```
+When you point your browser to [http://localhost:8080/](http://localhost:8080/) a transaction will be created in the Performance section of [sentry.io](https://sentry.io). Additionally, an error event will be sent to [sentry.io](https://sentry.io) and will be connected to the transaction.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
+
## Behavior
- The Sentry Python SDK will install the AIOHTTP integration for all of your apps.
@@ -70,7 +75,7 @@ web.run_app(app)
## Options
-You can pass the following keyword arguments to `AioHttpIntegration()`:
+By adding `AioHttpIntegration` to your `sentry_sdk.init()` call explicitly, you can set options for `AioHttpIntegration` to change its behavior:
```python
import sentry_sdk
@@ -86,6 +91,8 @@ sentry_sdk.init(
)
```
+You can pass the following keyword arguments to `AioHttpIntegration()`:
+
### `transaction_style`
Configure the way Sentry names transactions:
@@ -94,3 +101,8 @@ Configure the way Sentry names transactions:
- `.hello` if you set `transaction_style="handler_name"`
The default is `"handler_name"`.
+
+## Supported Versions
+
+- AIOHTTP: 3.5+
+- Python: 3.7+
diff --git a/src/platforms/python/guides/arq/index.mdx b/src/platforms/python/guides/arq/index.mdx
index 286f3902e030c..7e8386d162d95 100644
--- a/src/platforms/python/guides/arq/index.mdx
+++ b/src/platforms/python/guides/arq/index.mdx
@@ -15,57 +15,68 @@ pip install --upgrade "sentry-sdk[arq]"
## Configure
-Job definition in `demo.py`:
+
+
+Add `ArqIntegration()` to your `integrations` list:
```python
import sentry_sdk
from sentry_sdk.integrations.arq import ArqIntegration
-
sentry_sdk.init(
- dsn="...",
+ dsn="___PUBLIC_DSN___",
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
integrations=[
ArqIntegration(),
],
- traces_sample_rate=1.0,
)
+```
+## Verify
-async def add_numbers(ctx, a, b):
- return a + b
+### Enqueing the jobs in `run.py`:
+```python
+import asyncio
-class WorkerSettings:
- functions = [add_numbers]
+from arq import create_pool
+from arq.connections import RedisSettings
+
+async def main():
+ sentry_sdk.init(...) # same as above
+ redis = await create_pool(RedisSettings())
+
+ with sentry_sdk.start_transaction(name="testing_sentry"):
+ r = await redis.enqueue_job("add_numbers", 1, 2)
+
+asyncio.run(main())
```
-Running the jobs in `run.py`:
+When you run `run.sh` it will create a transaction called `testing_sentry` in the Performance section of [sentry.io](https://sentry.io), and create a span for enqueing the job.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
+
+### Job definition in `demo.py`:
```python
-import asyncio
import sentry_sdk
from sentry_sdk.integrations.arq import ArqIntegration
-from sentry_sdk.tracing import TRANSACTION_SOURCE_COMPONENT
-
-async def main():
- sentry_sdk.init(
- dsn="...",
- integrations=[
- ArqIntegration(),
- ],
- traces_sample_rate=1.0,
- )
+sentry_sdk.init(...) # same as above
- redis = await create_pool(RedisSettings())
+async def add_numbers(ctx, a, b):
+ 1/0 # raises an error!
+ return a + b
- with sentry_sdk.start_transaction(name="testing_arq_jobs", source=TRANSACTION_SOURCE_COMPONENT):
- r = await redis.enqueue_job("download_content", 1, 2)
+class WorkerSettings:
+ functions = [add_numbers]
+```
+When you run a worker with `arq demo.WorkerSettings` it will create a transaction called `add_numbers` in the Performance section of [sentry.io](https://sentry.io), and will also create and issue in Sentry and connect it to the transaction.
-if __name__ == "__main__":
- asyncio.run(main())
-```
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
## Supported Versions
diff --git a/src/platforms/python/guides/bottle/index.mdx b/src/platforms/python/guides/bottle/index.mdx
index 943fc9c7e2f91..5ae3920b42ec1 100644
--- a/src/platforms/python/guides/bottle/index.mdx
+++ b/src/platforms/python/guides/bottle/index.mdx
@@ -15,36 +15,50 @@ However the integration with the development version (0.13) doesn't work properl
Install `sentry-sdk` from PyPI with the `bottle` extra:
```bash
-pip install --upgrade 'sentry-sdk[bottle]==0.16.2'
+pip install --upgrade 'sentry-sdk[bottle]'
```
## Configure
-To configure the SDK, initialize it with the integration before your app has been initialized:
+If you have the `bottle` package in your dependencies, the Bottle integration will be enabled automatically when you initialize the Sentry SDK.
```python
+from bottle import Bottle
import sentry_sdk
-from bottle import Bottle, run
-from sentry_sdk.integrations.bottle import BottleIntegration
-
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
- integrations=[
- BottleIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
)
app = Bottle()
```
+## Verify
+
+```python
+from bottle import Bottle, run
+
+sentry_sdk.init(...) # same as above
+
+app = Bottle()
+
+@app.route('/')
+def hello():
+ 1/0
+ return "Hello World!"
+
+run(app, host='localhost', port=8000)
+```
+
+When you point your browser to [http://localhost:8000/](http://localhost:8000/) a transaction in the Performance section of [sentry.io](https://sentry.io) will be created. Additionally, an error event will be sent to [sentry.io](https://sentry.io) and will be connected to the transaction.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
+
## Behavior
- The Sentry Python SDK will install the Bottle integration for all of your apps. The integration hooks into base Bottle class.
@@ -57,6 +71,26 @@ app = Bottle()
## Options
+If you add `BottleIntegration` explicitly to your `sentry_sdk.init()` call you can set options for `BottleIntegration` to change its behavior:
+
+```python
+import sentry_sdk
+from sentry_sdk.integrations.bottle import BottleIntegration
+
+sentry_sdk.init(
+ dsn="___PUBLIC_DSN___",
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
+ integrations = [
+ BottleIntegration(
+ transaction_style="endpoint",
+ ),
+ ],
+)
+
+```
+
You can pass the following keyword arguments to `BottleIntegration()`:
- `transaction_style`:
@@ -73,3 +107,8 @@ You can pass the following keyword arguments to `BottleIntegration()`:
- `myendpoint` if you set `transaction_style="endpoint"`
The default is `"endpoint"`.
+
+## Supported Versions
+
+- Bottle: 0.12.13+
+- Python: 2.7+
diff --git a/src/platforms/python/guides/celery/index.mdx b/src/platforms/python/guides/celery/index.mdx
index 98ddd984a5bfc..a7a1b98591314 100644
--- a/src/platforms/python/guides/celery/index.mdx
+++ b/src/platforms/python/guides/celery/index.mdx
@@ -8,34 +8,34 @@ description: "Learn about using Sentry with Celery."
The Celery integration adds support for the [Celery Task Queue System](https://docs.celeryq.dev/).
-Just add `CeleryIntegration()` to your `integrations` list:
+## Install
+
+Install `sentry-sdk` from PyPI with the `celery` extra:
+
+```bash
+pip install --upgrade 'sentry-sdk[celery]'
+```
+
+## Configure
+
+If you have the `celery` package in your dependencies, the Celery integration will be enabled automatically when you initialize the Sentry SDK.
+
+Make sure that the **call to `init` is loaded on worker startup**, and not only in the module where your tasks are defined. Otherwise, the initialization happens too late and events might end up not being reported.
```python
import sentry_sdk
-from sentry_sdk.integrations.celery import CeleryIntegration
sentry_sdk.init(
dsn='___PUBLIC_DSN___',
- integrations=[
- CeleryIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
)
```
-Additionally, the Sentry Python SDK will set the transaction on the event to the task name, and it will improve the grouping for global Celery errors such as timeouts.
-
-The integration will automatically report errors from all celery jobs.
-
-Generally, make sure that the **call to `init` is loaded on worker startup**, and not only in the module where your tasks are defined. Otherwise, the initialization happens too late and events might end up not being reported.
-
-## Standalone Setup
+### Standalone Setup
If you're using Celery standalone, there are two ways to set this up:
@@ -51,16 +51,16 @@ If you're using Celery standalone, there are two ways to set this up:
#@signals.worker_init.connect
@signals.celeryd_init.connect
def init_sentry(**_kwargs):
- sentry_sdk.init(dsn="...")
+ sentry_sdk.init(...) # same as above
```
-## Setup With Django
+### Setup With Django
If you're using Celery with Django in a conventional setup, have already initialized the SDK in [your `settings.py` file](/platforms/python/guides/django/#configure), and have Celery using the same settings with [`config_from_object`](https://docs.celeryq.dev/en/stable/django/first-steps-with-django.html), you don't need to initialize the SDK separately for Celery.
## Verify
-To verify if your SDK is initialized on worker start, you can pass `debug=True` to see extra output when the SDK is initialized. If the output appears during worker startup and not only after a task has started, then it's working properly.
+To verify if your SDK is initialized on worker start, you can pass `debug=True` to `sentry_sdk.init()` to see extra output when the SDK is initialized. If the output appears during worker startup and not only after a task has started, then it's working properly.
@@ -156,3 +156,8 @@ my_task_b.apply_async(
# Note: overriding the tracing behaviour using `task_x.delay()` is not possible.
```
+
+## Supported Versions
+
+- Celery: 3.0+
+- Python: 2.7+ (Celery 3+), 3.6+ (Celery 5.0+), 3.7+ (Celery 5.1+)
diff --git a/src/platforms/python/guides/chalice/index.mdx b/src/platforms/python/guides/chalice/index.mdx
index 5d2963ba78e6a..352674c33bdfe 100644
--- a/src/platforms/python/guides/chalice/index.mdx
+++ b/src/platforms/python/guides/chalice/index.mdx
@@ -18,50 +18,53 @@ pip install --upgrade sentry-sdk[chalice]
```python
-import sentry_sdk
from chalice import Chalice
+import sentry_sdk
from sentry_sdk.integrations.chalice import ChaliceIntegration
-
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
- integrations=[
- ChaliceIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
+ integrations=[
+ ChaliceIntegration(),
+ ],
)
app = Chalice(app_name="appname")
```
-## Testing
-
-You can create a route that triggers an error for validate your Sentry installation like this:
+## Verify
```python
-@app.route("/boom")
-def boom():
- raise Exception("boom goes the dynamite!")
-```
+from chalice import Chalice
-when you enter the route will throw an error that will be captured by Sentry.
+sentry_sdk.init(...) # as above
-for everything else (like events)
+app = Chalice(app_name="helloworld")
-```python
@app.schedule(Rate(1, unit=Rate.MINUTES))
-def every_hour(event):
- raise Exception("only chalice event!")
+def every_minute(event):
+ 1/0 # raises an error
+
+@app.route("/")
+def index():
+ 1/0 # raises an error
+ return {"hello": "world"}
```
+When you enter the `"/"` route or the scheduled task is run, an error event will be sent to [sentry.io](https://sentry.io).
+
## Behavior
- Request data is attached to all events: HTTP method, URL, headers, form data, JSON payloads. Sentry excludes raw bodies and multipart file uploads. Sentry also excludes personally identifiable information (such as user ids, usernames, cookies, authorization headers, IP addresses) unless you set send_default_pii to True.
- Each request has a separate scope. Changes to the scope within a view, for example setting a tag, will only apply to events sent as part of the request being handled.
+
+## Supported Versions
+
+- Chalice: 1.16.0+
+- Python: 3.6+
diff --git a/src/platforms/python/guides/fastapi/index.mdx b/src/platforms/python/guides/fastapi/index.mdx
index 1f45fbf674afd..220607b37dede 100644
--- a/src/platforms/python/guides/fastapi/index.mdx
+++ b/src/platforms/python/guides/fastapi/index.mdx
@@ -18,22 +18,18 @@ pip install --upgrade 'sentry-sdk[fastapi]'
## Configure
-To configure the Sentry SDK, initialize it before your app has been initialized:
+If you have the `fastapi` package in your dependencies, the FastAPI integration will be enabled automatically when you initialize the Sentry SDK.
```python
from fastapi import FastAPI
-
import sentry_sdk
-
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
)
@@ -42,21 +38,21 @@ app = FastAPI()
## Verify
-This snippet includes an intentional error, so you can test that everything is working as soon as you set it up:
-
```python
from fastapi import FastAPI
+sentry_sdk.init(...) # same as above
app = FastAPI()
@app.get("/sentry-debug")
async def trigger_error():
division_by_zero = 1 / 0
-
```
-Visiting `"/sentry-debug"` will trigger an error that will be captured by Sentry.
+When you point your browser to [http://localhost:8000/sentry-debug](http://localhost:8000/sentry-debug) a transaction will be created in the Performance section of [sentry.io](https://sentry.io). Additionally, an error event will be sent to [sentry.io](https://sentry.io) and will be connected to the transaction.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
## Behaviour
@@ -88,43 +84,59 @@ The parameter `traces_sample_rate` needs to be set when initializing the Sentry
-## Integration Options
-
-If you want to change the default behavior of the FastAPI integration, you need to instantiate the integration manually and then pass it to Sentry's `init` function. Because FastAPI is based on the Starlette framework, both integrations, `StarletteIntegration` and `FastApiIntegration`, must be instantiated.
-
-
+## Options
-You can pass the keyword argument `transaction_style` to `StarletteIntegration()` and `FastApiIntegration()`.
-
-With this option, you can influence how the transactions are named in Sentry. For example:
+By adding `FastApiIntegration` to your `sentry_sdk.init()` call explicitly, you can set options for `FastApiIntegration` to change its behavior.
+Because FastAPI is based on the Starlette framework, both integrations, `StarletteIntegration` and `FastApiIntegration`, must be instantiated.
```python
from sentry_sdk.integrations.starlette import StarletteIntegration
from sentry_sdk.integrations.fastapi import FastApiIntegration
sentry_sdk.init(
- # ...
+ dsn="___PUBLIC_DSN___",
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
integrations=[
- StarletteIntegration(transaction_style="endpoint"),
- FastApiIntegration(transaction_style="endpoint"),
- ],
+ StarletteIntegration(transaction_style="endpoint",),
+ FastApiIntegration(transaction_style="endpoint",),
+ ]
)
+```
-app = FastAPI()
+You can pass the following keyword arguments to `StarletteIntegration()` and `FastApiIntegration()`:
-@app.get("/catalog/product/{product_id}")
-async def product_detail(product_id):
- return {...}
-```
+- `transaction_style`:
+
+ This option lets you influence how the transactions are named in Sentry. For example:
+
+ ```python
+ import sentry_sdk
+ from sentry_sdk.integrations.starlette import StarletteIntegration
+ from sentry_sdk.integrations.fastapi import FastApiIntegration
+
+ sentry_sdk.init(
+ # ...
+ integrations=[
+ StarletteIntegration(transaction_style="endpoint"),
+ FastApiIntegration(transaction_style="endpoint"),
+ ],
+ )
+
+ app = FastAPI()
-In the above code, the transaction name will be:
+ @app.get("/catalog/product/{product_id}")
+ async def product_detail(product_id):
+ return {...}
+ ```
-- `"/catalog/product/{product_id}"` if you set `transaction_style="url"`
-- `"product_detail"` if you set `transaction_style="endpoint"`
+ In the above code, the transaction name will be:
-The default is `"url"`.
+ - `"/catalog/product/{product_id}"` if you set `transaction_style="url"`
+ - `"product_detail"` if you set `transaction_style="endpoint"`
-
+ The default is `"url"`.
## Supported Versions
diff --git a/src/platforms/python/guides/flask/config.yml b/src/platforms/python/guides/flask/config.yml
deleted file mode 100644
index 61d0168917cd4..0000000000000
--- a/src/platforms/python/guides/flask/config.yml
+++ /dev/null
@@ -1,4 +0,0 @@
-title: Flask
-caseStyle: snake_case
-supportLevel: production
-sdk: sentry.python.flask
diff --git a/src/platforms/python/guides/flask/index.mdx b/src/platforms/python/guides/flask/index.mdx
new file mode 100644
index 0000000000000..2a3098259b309
--- /dev/null
+++ b/src/platforms/python/guides/flask/index.mdx
@@ -0,0 +1,112 @@
+---
+title: Flask
+redirect_from:
+ - /platforms/python/flask/
+description: "Learn about using Sentry with Flask."
+---
+
+The Flask integration adds support for the [Flask Web Framework](https://flask.palletsprojects.com).
+
+## Install
+
+Install `sentry-sdk` from PyPI with the `flask` extra:
+
+```bash
+pip install --upgrade "sentry-sdk[flask]"
+```
+
+## Configure
+
+If you have the `flask` package in your dependencies, the Flask integration will be enabled automatically when you initialize the Sentry SDK.
+
+
+
+```python
+from flask import Flask
+import sentry_sdk
+
+sentry_sdk.init(
+ dsn="___PUBLIC_DSN___",
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
+)
+
+app = Flask(__name__)
+```
+
+
+
+Our Python SDK will install the Flask integration for all of your apps. It hooks into Flaskās signals, not anything on the app object.
+
+
+
+## Verify
+
+```python
+from flask import Flask
+
+sentry_sdk.init(...) # same as above
+
+app = Flask(__name__)
+
+@app.route("/")
+def hello_world():
+ 1/0 # raises an error
+ return "
Hello, World!
"
+```
+
+When you point your browser to [http://localhost:5000/](http://localhost:5000/) a transaction in the Performance section of [sentry.io](https://sentry.io) will be created. Additionally, an error event will be sent to [sentry.io](https://sentry.io) and will be connected to the transaction.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
+
+## Behavior
+
+After initialization:
+
+- If you use `flask-login` and set `send_default_pii=True` in your call to `init`, user data (current user id, email address, username) will be attached to the event.
+- Request data will be attached to all events: **HTTP method, URL, headers, form data, JSON payloads**. Sentry excludes raw bodies and multipart file uploads.
+- Logs emitted by `app.logger` or _any_ logger will be recorded as breadcrumbs by the [Logging](/platforms/python/guides/logging/) integration (this integration is enabled by default).
+
+## Options
+
+If you add `FlaskIntegration` explicitly to your `sentry_sdk.init()` call you can set options for `FlaskIntegration` to change its behavior:
+
+```python
+import sentry_sdk
+from sentry_sdk.integrations.flask import FlaskIntegration
+
+sentry_sdk.init(
+ dsn="___PUBLIC_DSN___",
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
+ integrations = [
+ FlaskIntegration(
+ transaction_style="url",
+ ),
+ ],
+)
+```
+
+You can pass the following keyword arguments to `FlaskIntegration()`:
+
+- `transaction_style`:
+
+ ```python
+ @app.route("/myurl/")
+ def myendpoint():
+ return "
Hello, World!
"
+ ```
+
+ In the above code, you would set the transaction to:
+
+ - `/myurl/` if you set `transaction_style="url"`.
+ - `myendpoint` if you set `transaction_style="endpoint"`
+
+ The default is `"endpoint"`.
+
+## Supported Versions
+
+- Flask: 0.11+
+- Python: 2.7+ (Flask 0.11+), 3.6 (Flask 2.0+)
diff --git a/src/platforms/python/guides/logging/index.mdx b/src/platforms/python/guides/logging/index.mdx
index 8a9f19abbe1c7..85114252ef2b7 100644
--- a/src/platforms/python/guides/logging/index.mdx
+++ b/src/platforms/python/guides/logging/index.mdx
@@ -6,69 +6,78 @@ redirect_from:
description: "Learn about logging with Python."
---
-Calling `sentry_sdk.init()` already integrates with the logging module. It is
-equivalent to this explicit configuration:
+Adds support for Python logging.
+
+## Install
+
+Install `sentry-sdk` from PyPI:
+
+```bash
+pip install --upgrade sentry-sdk
+```
+
+## Configure
+
+The logging integrations is a default integration so it will be enabled automatically when you initialize the Sentry SDK.
```python
-import logging
import sentry_sdk
-from sentry_sdk.integrations.logging import LoggingIntegration
-# All of this is already happening by default!
-sentry_logging = LoggingIntegration(
- level=logging.INFO, # Capture info and above as breadcrumbs
- event_level=logging.ERROR # Send errors as events
-)
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
- integrations=[
- sentry_logging,
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
)
```
-## Usage
+## Verify
```python
import logging
-logging.debug("I am ignored")
-logging.info("I am a breadcrumb")
-logging.error("I am an event", extra=dict(bar=43))
-logging.exception("An exception happened")
+
+def main():
+ sentry_sdk.init(...) # same as above
+
+ logging.debug("I am ignored")
+ logging.info("I am a breadcrumb")
+ logging.error("I am an event", extra=dict(bar=43))
+ logging.exception("An exception happened")
+
+main()
```
- There will be an error event with the message `"I am an event"`.
- `"I am a breadcrumb"` will be attached as a breadcrumb to that event.
- `bar` will end up in the event's `extra` attributes.
- `"An exception happened"` will send the current exception from `sys.exc_info()` with the stack trace and everything to the Sentry Python SDK. If there's no exception, the current stack will be attached.
-- The debug message `"I am ignored"` will not surface anywhere. To capture it, you need to lower `level` to `DEBUG`.
+- The debug message `"I am ignored"` will not surface anywhere. To capture it, you need to lower `level` to `DEBUG` (See below).
-## Ignoring a logger
+## Options
-Sometimes a logger is extremely noisy and spams you with pointless errors. You can completely ignore that logger by calling `ignore_logger`:
+To change the default behavior of the logging integration, instantiate the integration manually and pass it to Sentry's `init` function:
```python
-from sentry_sdk.integrations.logging import ignore_logger
-
-
-ignore_logger("a.spammy.logger")
+import logging
+import sentry_sdk
+from sentry_sdk.integrations.logging import LoggingIntegration
-logger = logging.getLogger("a.spammy.logger")
-logger.error("hi") # no error sent to sentry
+sentry_sdk.init(
+ dsn="___PUBLIC_DSN___",
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
+ integrations=[
+ LoggingIntegration(
+ level=logging.INFO, # Capture info and above as breadcrumbs
+ event_level=logging.ERROR # Send errors as events
+ ),
+ ],
+)
```
-You can also use `before-send` and `before-breadcrumb` to ignore
-only certain messages. See [_Filtering Events_](configuration/filtering/) for more information.
-
-## Options
-
You can pass the following keyword arguments to `LoggingIntegration()`:
- `level` (default `INFO`): The Sentry Python SDK will record log records with a level higher than or equal to `level` as breadcrumbs. Inversely, the SDK completely ignores any log record with a level lower than this one. If a value of `None` occurs, the SDK won't send log records as breadcrumbs.
@@ -81,6 +90,22 @@ The Sentry Python SDK will honor the configured level of each logger (set with `
+## Ignoring a logger
+
+Sometimes a logger is extremely noisy and spams you with pointless errors. You can ignore that logger by calling `ignore_logger`:
+
+```python
+from sentry_sdk.integrations.logging import ignore_logger
+
+ignore_logger("a.spammy.logger")
+
+logger = logging.getLogger("a.spammy.logger")
+logger.error("hi") # no error sent to sentry
+```
+
+You can also use `before-send` and `before-breadcrumb` to ignore
+only certain messages. See [_Filtering Events_](configuration/filtering/) for more information.
+
## Handler classes
Instead of using `LoggingIntegration`, you can use two regular logging `logging.Handler` subclasses that the integration exports.
diff --git a/src/platforms/python/guides/pyramid/index.mdx b/src/platforms/python/guides/pyramid/index.mdx
index 3576d5b919a1b..64501077e2b52 100644
--- a/src/platforms/python/guides/pyramid/index.mdx
+++ b/src/platforms/python/guides/pyramid/index.mdx
@@ -6,7 +6,7 @@ redirect_from:
description: "Learn about using Sentry with Pyramid."
---
-The Pyramid integration adds support for the [Pyramid Web Framework](https://trypyramid.com/). It requires Pyramid 1.6 or later.
+The Pyramid integration adds support for the [Pyramid Web Framework](https://trypyramid.com/).
## Install
@@ -24,19 +24,16 @@ To configure the SDK, initialize it with the integration before or after your ap
```python
import sentry_sdk
-
from sentry_sdk.integrations.pyramid import PyramidIntegration
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
- integrations=[
- PyramidIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
+ integrations=[
+ PyramidIntegration(),
+ ],
)
from pyramid.config import Configurator
@@ -45,6 +42,31 @@ with Configurator() as config:
# ...
```
+## Verify
+
+```python
+from wsgiref.simple_server import make_server
+from pyramid.config import Configurator
+from pyramid.response import Response
+
+sentry_sdk.init(...) # same as above
+
+def hello_world(request):
+ 1/0 # raises an error
+ return Response('Hello World!')
+
+if __name__ == '__main__':
+ with Configurator() as config:
+ config.add_route('hello', '/')
+ config.add_view(hello_world, route_name='hello')
+ app = config.make_wsgi_app()
+
+ server = make_server('0.0.0.0', 6543, app)
+ server.serve_forever()
+```
+
+When you point your browser to [http://localhost:6543/](http://localhost:6543/) an error event will be sent to [sentry.io](https://sentry.io).
+
## Behavior
- The Sentry Python SDK will install the Pyramid integration for all of your apps. The integration hooks into Pyramid itself, not any of your apps specifically.
@@ -79,3 +101,8 @@ You can pass the following keyword arguments to `PyramidIntegration()`:
- `myroute` if you set `transaction_style="route_name"`
The default is `"route_name"`.
+
+## Supported Versions
+
+- Pyramid: 1.6+
+- Python: 2.7+
diff --git a/src/platforms/python/guides/quart/index.mdx b/src/platforms/python/guides/quart/index.mdx
index 6cf195dbe027e..5f21d6d5713e7 100644
--- a/src/platforms/python/guides/quart/index.mdx
+++ b/src/platforms/python/guides/quart/index.mdx
@@ -3,18 +3,14 @@ title: Quart
description: "Learn about using Sentry with Quart."
---
-The Quart integration adds support for the [Quart Web Framework](https://gitlab.com/pgjones/quart). We support Quart versions 0.16.1 and higher.
-
-Requires `sentry-sdk` version `1.5.2` or higher.
-
-A Python version of 3.7 or higher is also required.
+The Quart integration adds support for the [Quart Web Framework](https://gitlab.com/pgjones/quart).
## Install
-Install `sentry-sdk` from PyPI:
+Install `sentry-sdk` from PyPI with the `quart` extra:
```bash
-pip install --upgrade sentry-sdk
+pip install --upgrade sentry-sdk[quart]
```
## Configure
@@ -24,25 +20,45 @@ To configure the SDK, initialize it with the integration before or after your ap
```python
+from quart import Quart
+
import sentry_sdk
from sentry_sdk.integrations.quart import QuartIntegration
-from quart import Quart
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
- integrations=[
- QuartIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
+ integrations=[
+ QuartIntegration(),
+ ],
)
app = Quart(__name__)
```
+# Verify
+
+```python
+from quart import Quart
+
+sentry_sdk.init(...) # same as above
+
+app = Quart(__name__)
+
+@app.route("/")
+async def hello():
+ 1/0 # raises an error
+ return {"hello": "world"}
+
+app.run()
+```
+
+When you point your browser to [http://localhost:5000/](http://localhost:5000/) a transaction in the Performance section of [sentry.io](https://sentry.io) will be created. Additionally, an error event will be sent to [sentry.io](https://sentry.io) and will be connected to the transaction.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
+
## Behavior
- The Sentry Python SDK will install the Quart integration for all of your apps.
@@ -54,3 +70,8 @@ app = Quart(__name__)
- Each request has a separate scope. Changes to the scope within a view, for example setting a tag, will only apply to events sent as part of the request being handled.
- Logging with any logger will create breadcrumbs when the [Logging](/platforms/python/guides/logging/) integration is enabled (done by default).
+
+## Supported Versions
+
+- Quart: 0.16.1+
+- Python: 3.7+
diff --git a/src/platforms/python/guides/rq/index.mdx b/src/platforms/python/guides/rq/index.mdx
index fbb7ea6cbb883..fc026e37f46d5 100644
--- a/src/platforms/python/guides/rq/index.mdx
+++ b/src/platforms/python/guides/rq/index.mdx
@@ -8,24 +8,31 @@ description: "Learn about using Sentry with RQ."
The RQ integration adds support for the [RQ Job Queue System](https://python-rq.org/).
+## Install
+
+Install `sentry-sdk` from PyPI with the `rq` extra:
+
+```bash
+pip install --upgrade 'sentry-sdk[rq]'
+```
+
+## Configure
+
+If you have the `rq` package in your dependencies, the RQ integration will be enabled automatically when you initialize the Sentry SDK.
+
Create a file called `mysettings.py` with the following content:
```python {filename:mysettings.py}
+# mysettings.py
import sentry_sdk
-from sentry_sdk.integrations.rq import RqIntegration
sentry_sdk.init(
- dsn="___PUBLIC_DSN___",
- integrations=[
- RqIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
+ dsn="___PUBLIC_DSN___",
)
```
@@ -34,32 +41,25 @@ Start your worker with:
```shell
rq worker \
-c mysettings \ # module name of mysettings.py
- --sentry-dsn="" # only necessary for RQ < 1.0
+ --sentry-dsn="___PUBLIC_DSN___" # only necessary for RQ < 1.0
```
The integration will automatically report errors from all RQ jobs.
Generally, make sure that the **call to `init` is loaded on worker startup**, and not only in the module where your jobs are defined. Otherwise, the initialization happens too late and events might end up not being reported.
-In addition, make sure that **`init` is called only once** in your app. For example, if you have a Flask app and a worker that depends on the app, we recommend initializing Sentry with a single configuration that is suitable for Flask and RQ, as in:
+In addition, make sure that **`init` is called only once** in your app. For example, if you have a `Flask` app and a worker that depends on the app, we recommend only initializing Sentry once. Note that because the Flask integration is enabled automatically, you don't need to change the configuration shown above.
```python {filename:app.py}
+# app.py
import sentry_sdk
-from sentry_sdk.integrations.flask import FlaskIntegration
-from sentry_sdk.integrations.rq import RqIntegration
sentry_sdk.init(
dsn=___PUBLIC_DSN___,
- integrations=[
- FlaskIntegration(),
- RqIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
)
```
@@ -67,12 +67,76 @@ sentry_sdk.init(
The worker configuration `mysettings.py` then becomes:
```python {filename:mysettings.py}
+# mysettings.py
# This import causes the Sentry SDK to be initialized
import app
```
+## Verify
+
+To verify, create a `main.py` script that enqueues a function in RQ, then start an RQ worker to run the function:
+
+### Job definition:
+
+```python {filename:jobs.py}
+# jobs.py
+def hello(name):
+ 1/0 # raises an error
+ return "Hello %s!" % name
+```
+
+### Settings for worker
+
+```python {filename:mysettings.py}
+# mysettings.py
+import sentry_sdk
+
+# Sentry configuration for RQ worker processes
+sentry_sdk.init(
+ dsn=___PUBLIC_DSN___,
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
+)
+```
+
+### Main Python Script
+
+```python {filename:main.py}
+# main.py
+from redis import Redis
+from rq import Queue
+
+from jobs import hello
+
+import sentry_sdk
+
+# Sentry configuration for main.py process
+sentry_sdk.init(
+ dsn=___PUBLIC_DSN___,
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
+)
+
+q = Queue(connection=Redis())
+with sentry_sdk.start_transaction(name="testing_sentry"):
+ result = q.enqueue(hello, "World")
+```
+
+When you run `python main.py` a transaction named `testing_sentry` will be created in the Performance section of [sentry.io](https://sentry.io) and spans for the enqueueing will be created.
+
+If you run the RQ worker with `rq worker -c mysettings`, a transaction for the execution of `hello()` will be created. Additionally, an error event will be sent to [sentry.io](https://sentry.io) and will be connected to the transaction.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
+
## The `--sentry-dsn` CLI option
Passing `--sentry-dsn=""` to RQ forcibly disables [RQ's shortcut for using Sentry](https://python-rq.org/patterns/sentry/). For RQ versions before 1.0 this is necessary to avoid conflicts, because back then RQ would attempt to use the `raven` package instead of this SDK. Since RQ 1.0 it's possible to use this CLI option and the associated RQ settings for initializing the SDK.
We still recommend against using those shortcuts because it would be harder to provide options to the SDK at a later point. See [the GitHub issue about RQ's Sentry integration](https://github.com/rq/rq/issues/1003) for discussion.
+
+## Supported Versions
+
+- RQ: 0.6+
+- Python: 2.7+ (RQ 0.6+), 3.5+ (RQ 1.4+)
diff --git a/src/platforms/python/guides/sanic/index.mdx b/src/platforms/python/guides/sanic/index.mdx
index 125ed9f6b7f7e..108131e644fc6 100644
--- a/src/platforms/python/guides/sanic/index.mdx
+++ b/src/platforms/python/guides/sanic/index.mdx
@@ -5,26 +5,14 @@ redirect_from:
description: "Learn about using Sentry with Sanic."
---
-The Sanic integration adds support for the [Sanic Web Framework](https://sanicframework.org). We support the following versions, which are known to work with the SDK:
-
-- `0.8`
-- `18.12 LTS`
-- `19.12 LTS`
-- `21.3`, `21.6`, `21.9`, `21.12 LTS`
-- `22.6
-
-_\* Starting with Sanic v21, `sentry-sdk` v1.3.0 or higher is required_
-
-The SDK will support any Sanic version of the form `x.12` (LTS versions). If the latest version of Sanic is not explicitly listed here, it _might_ not be supported.
-
-A Python version of 3.6 or greater is also required.
+The Sanic integration adds support for the [Sanic Web Framework](https://sanic.dev/).
## Install
-Install `sentry-sdk` from PyPI:
+Install `sentry-sdk` from PyPI with the `sanic` extra:
```bash
-pip install --upgrade sentry-sdk
+pip install --upgrade sentry-sdk[sanic]
```
If you're on Python 3.6, you also need the `aiocontextvars` package:
@@ -35,30 +23,42 @@ pip install --upgrade aiocontextvars
## Configure
-To configure the SDK, initialize it with the integration before or after your app has been initialized:
+If you have the `sanic` package in your dependencies, the Bottle integration will be enabled automatically when you initialize the Sentry SDK.
```python
-import sentry_sdk
-from sentry_sdk.integrations.sanic import SanicIntegration
from sanic import Sanic
+import sentry_sdk
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
- integrations=[
- SanicIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
)
app = Sanic(__name__)
```
+## Verify
+
+```python
+from sanic import Sanic
+from sanic.response import text
+
+sentry_sdk.init(...) # same as above
+
+app = Sanic(__name__)
+
+@app.get("/")
+async def hello_world(request):
+ 1 / 0 # raises an error
+ return text("Hello, world.")`
+```
+
+When you point your browser to [http://localhost:8000/](http://localhost:8000/) an error event will be sent to [sentry.io](https://sentry.io).
+
## Behavior
- The Sentry Python SDK will install the Sanic integration for all of your apps.
@@ -72,3 +72,8 @@ app = Sanic(__name__)
- Logging with any logger will create breadcrumbs when
the [Logging](/platforms/python/guides/logging/)
integration is enabled (done by default).
+
+## Supported Versions
+
+- Sanic: 0.8+
+- Python: 3.6+ (Sanic 0.8+), 3.7+ (Sanic 21.0+)
diff --git a/src/platforms/python/guides/serverless/index.mdx b/src/platforms/python/guides/serverless/index.mdx
index ca56e68d17574..08d6c73426853 100644
--- a/src/platforms/python/guides/serverless/index.mdx
+++ b/src/platforms/python/guides/serverless/index.mdx
@@ -5,6 +5,8 @@ redirect_from:
description: "Learn about using Sentry's Python SDK for a serverless environment."
---
+The Serverless integration adds support for the [Serverless Framework](https://www.serverless.com/).
+
It is recommended to use an integration for your particular serverless environment if available, as those are easier to use and capture more useful information:
-
@@ -14,6 +16,16 @@ It is recommended to use an integration for your particular serverless environme
If you use a serverless provider not directly supported by the SDK, you can use this generic integration.
+## Install
+
+Install `sentry-sdk` from PyPI:
+
+```bash
+pip install --upgrade 'sentry-sdk'
+```
+
+## Configure
+
Apply the `serverless_function` decorator to each function that might throw errors:
@@ -23,12 +35,10 @@ import sentry_sdk
from sentry_sdk.integrations.serverless import serverless_function
sentry_sdk.init(
- dsn="___PUBLIC_DSN___",
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
+ dsn="___PUBLIC_DSN___",
)
@serverless_function
@@ -36,9 +46,19 @@ def my_function(...): ...
```
Use the generic integration by calling the `serverless_function` decorator.
-Decorators wrap a function and modify its behavior. Then, deploy and test the
-function. Check out Sentry's [sample
-apps](https://github.com/getsentry/examples) for detailed examples.
+Decorators wrap a function and modify its behavior. Then, deploy and test the function.
+
+## Verify
+
+Wrap a functions with the `serverless_function` that triggers an error:
+
+```python
+@serverless_function
+def my_function(...):
+ 1/0 # raises an error
+```
+
+Now deploy your function. When you now run your function an error event will be sent to [sentry.io](https://sentry.io).
## Behavior
diff --git a/src/platforms/python/guides/starlette/index.mdx b/src/platforms/python/guides/starlette/index.mdx
index 748f6a7507787..acf790876167b 100644
--- a/src/platforms/python/guides/starlette/index.mdx
+++ b/src/platforms/python/guides/starlette/index.mdx
@@ -8,8 +8,6 @@ description: "Learn about using Sentry with Starlette."
The Starlette integration adds support for the [Starlette Framework](https://www.starlette.io/).
-The Sentry SDK automatically enables support for Starlette if you have the `starlette` Python package installed in your project. There are no configuration options you need to add when initializing the Sentry SDK, as everything works out of the box.
-
## Install
Install `sentry-sdk` from PyPI with the `starlette` extra:
@@ -20,23 +18,19 @@ pip install --upgrade 'sentry-sdk[starlette]'
## Configure
-To configure the SDK, initialize it with the integration before your app has been initialized:
+If you have the `starlette` package in your dependencies, the Starlette integration will be enabled automatically when you initialize the Sentry SDK.
```python
from starlette.applications import Starlette
-
import sentry_sdk
-
sentry_sdk.init(
- dsn="___PUBLIC_DSN___",
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
+ dsn="___PUBLIC_DSN___",
)
app = Starlette(routes=[...])
@@ -44,12 +38,11 @@ app = Starlette(routes=[...])
## Verify
-This snippet includes an intentional error, so you can test that everything is working as soon as you set it up:
-
```python
from starlette.applications import Starlette
from starlette.routing import Route
+sentry_sdk.init(...) # same as above
async def trigger_error(request):
division_by_zero = 1 / 0
@@ -59,7 +52,9 @@ app = Starlette(routes=[
])
```
-Visiting `"/sentry-debug"` will trigger an error that will be captured by Sentry.
+When you point your browser to [http://localhost:8000/sentry-debug](http://localhost:8000/sentry-debug) a transaction will be created in the Performance section of [sentry.io](https://sentry.io). Additionally, an error event will be sent to [sentry.io](https://sentry.io) and will be connected to the transaction.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
## Behavior
@@ -71,33 +66,45 @@ Visiting `"/sentry-debug"` will trigger an error that will be captured by Sentry
## Options
-If you want to change the default behavior of the Starlette integration, you need to instantiate the integration by hand and pass it to Sentry's `init` function.
-
-You can pass the keyword argument `transaction_style` to `StarletteIntegration()`.
-
-With this option, you can influence how the transactions are named in Sentry. For example:
+By adding `StarletteIntegration` explicitly to your `sentry_sdk.init()` call you can set options for `StarletteIntegration` to change its behavior:
```python
from sentry_sdk.integrations.starlette import StarletteIntegration
sentry_sdk.init(
- # ...
+ dsn="___PUBLIC_DSN___",
+ # Set traces_sample_rate to 1.0 to capture 100%
+ # of transactions for performance monitoring.
+ traces_sample_rate=1.0,
integrations=[
- StarletteIntegration(transaction_style="endpoint"),
+ StarletteIntegration(
+ transaction_style="endpoint",
+ )
],
)
+```
-async def product_detail(request):
- return JSONResponse({...})
+You can pass the following keyword arguments to `StarletteIntegration()`:
-app = Starlette(routes=[
- Route('/catalog/product/{product_id}', product_detail),
-])
-```
+- `transaction_style`:
+
+ ```
+ async def product_detail(request):
+ return JSONResponse({...})
+
+ app = Starlette(routes=[
+ Route('/catalog/product/{product_id}', product_detail),
+ ])
+ ```
+
+ In the above code, the transaction name will be:
+
+ - `"/catalog/product/{product_id}"` if you set `transaction_style="url"`.
+ - `"product_detail"` if you set `transaction_style="endpoint"`
-In the above code, the transaction name will be:
+ The default is `"url"`.
-- `"/catalog/product/{product_id}"` if you set `transaction_style="url"`.
-- `"product_detail"` if you set `transaction_style="endpoint"`
+## Supported Versions
-The default is `"url"`.
+- Starlette: 0.19.1+
+- Python: 3.7+
diff --git a/src/platforms/python/guides/tornado/index.mdx b/src/platforms/python/guides/tornado/index.mdx
index 2aab72cece86c..c0178a57b1979 100644
--- a/src/platforms/python/guides/tornado/index.mdx
+++ b/src/platforms/python/guides/tornado/index.mdx
@@ -6,14 +6,14 @@ redirect_from:
description: "Learn about using Sentry with Tornado."
---
-The Tornado integration adds support for the [Tornado Web Framework](https://www.tornadoweb.org/). A Tornado version of 5 or greater and Python 3.6 or greater is required.
+The Tornado integration adds support for the [Tornado Web Framework](https://www.tornadoweb.org/).
## Install
-Install `sentry-sdk` from PyPI:
+Install `sentry-sdk` from PyPI with the `tornado` extra:
```bash
-pip install --upgrade sentry-sdk
+pip install --upgrade sentry-sdk[tornado]
```
If you're on Python 3.6, you also need the `aiocontextvars` package:
@@ -34,22 +34,48 @@ from sentry_sdk.integrations.tornado import TornadoIntegration
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
- integrations=[
- TornadoIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
+ integrations=[
+ TornadoIntegration(),
+ ],
)
-# Your app code here, without changes
-
-class MyHandler(...):
+class MainHandler(tornado.web.RequestHandler):
# ...
```
+## Verify
+
+```python
+import asyncio
+import tornado
+
+sentry_sdk.init(...) # same as above
+
+class MainHandler(tornado.web.RequestHandler):
+ def get(self):
+ 1/0 # raises an error
+ self.write("Hello, world")
+
+def make_app():
+ return tornado.web.Application([
+ (r"/", MainHandler),
+ ])
+
+async def main():
+ app = make_app()
+ app.listen(8888)
+ await asyncio.Event().wait()
+
+asyncio.run(main())
+```
+
+When you point your browser to [http://localhost:8888/](http://localhost:8888/) a transaction in the Performance section of [sentry.io](https://sentry.io) will be created. Additionally, an error event will be sent to [sentry.io](https://sentry.io) and will be connected to the transaction.
+
+It takes a couple of moments for the data to appear in [sentry.io](https://sentry.io).
+
## Behavior
- The Tornado integration will be installed for all of your apps and handlers.
@@ -63,3 +89,8 @@ class MyHandler(...):
- Logging with any logger will create breadcrumbs when
the [Logging](/platforms/python/guides/logging/)
integration is enabled (done by default).
+
+## Supported Versions
+
+- Tornado: 5+
+- Python: 2.7+
diff --git a/src/platforms/python/guides/tryton/index.mdx b/src/platforms/python/guides/tryton/index.mdx
index 45b694b56961f..d258fcaa1f980 100644
--- a/src/platforms/python/guides/tryton/index.mdx
+++ b/src/platforms/python/guides/tryton/index.mdx
@@ -7,25 +7,25 @@ description: "Learn aboutn using Sentry with Tryton."
The Tryton integration adds support for the [Tryton Framework Server](https://www.tryton.org/).
-To configure the SDK, initialize it with the integration in a custom wsgi.py script:
+## Configure
+
+To configure the SDK, initialize it with the integration in a custom `wsgi.py` script:
-```python
+```python {filename:wsgi.py}
# wsgi.py
import sentry_sdk
-import sentry_sdk.integrations.trytond
+from sentry_sdk.integrations.trytond import TrytondWSGIIntegration
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
- integrations=[
- sentry_sdk.integrations.trytond.TrytondWSGIIntegration(),
- ],
-
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for performance monitoring.
- # We recommend adjusting this value in production,
traces_sample_rate=1.0,
+ integrations=[
+ TrytondWSGIIntegration(),
+ ],
)
from trytond.application import app as application
@@ -36,12 +36,11 @@ from trytond.application import app as application
In Tryton>=5.4 an error handler can be registered to respond the client
with a custom error message including the Sentry event id instead of a traceback.
-```python
+```python {filename:wsgi.py}
# wsgi.py
# ...
-from trytond.exceptions import TrytonException
-from trytond.exceptions import UserError
+from trytond.exceptions import TrytonException, UserError
@application.error_handler
def _(app, request, e):
@@ -51,7 +50,6 @@ def _(app, request, e):
event_id = sentry_sdk.last_event_id()
data = UserError('Custom message', f'{event_id}\n{e}')
return app.make_response(request, data)
-
```
## Behavior
@@ -63,3 +61,8 @@ def _(app, request, e):
- Request data is attached to all events: **HTTP method, URL, headers, form data, JSON payloads**. Sentry excludes raw bodies and multipart file uploads. Sentry also excludes personally identifiable information (such as user ids, usernames, cookies, authorization headers, IP addresses) unless you set `send_default_pii` to `True`.
Each request has a separate scope. Changes to the scope within a view, for example setting a tag, will only apply to events sent as part of the request being handled.
+
+## Supported Versions
+
+- Tryton: 4.6+
+- Python: 3.5+ (Tryton 4.6+), 3.6+ (Tryton 5.4+)
diff --git a/src/wizard/apple/profiling-onboarding/ios/1.install.md b/src/wizard/apple/profiling-onboarding/ios/1.install.md
index 9cceb392c39a8..8f8191b5ba5b7 100644
--- a/src/wizard/apple/profiling-onboarding/ios/1.install.md
+++ b/src/wizard/apple/profiling-onboarding/ios/1.install.md
@@ -7,8 +7,8 @@ type: language
#### Install
-For the Profiling integration to work, you must have the Sentry Cocoa package (minimum version 7.23.0). We offer installation methods for Carthage (shown below), CocoaPods, and Swift Package Manager. Learn more about installation methods in our [full documentation](/platforms/apple/install/).
+For the Profiling integration to work, you must have the Sentry Cocoa package (minimum version 8.12.0). We offer installation methods for Carthage (shown below), CocoaPods, and Swift Package Manager. Learn more about installation methods in our [full documentation](/platforms/apple/install/).
```ruby
-github "getsentry/sentry-cocoa" "{{@inject packages.version('sentry.cocoa','7.23.0') }}"
+github "getsentry/sentry-cocoa" "{{@inject packages.version('sentry.cocoa','8.12.0') }}"
```
diff --git a/yarn.lock b/yarn.lock
index ab5a05f5f4868..ab30bffda602b 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2582,27 +2582,27 @@
"@sentry/utils" "7.53.1"
tslib "^1.9.3"
-"@sentry-internal/tracing@7.55.2":
- version "7.55.2"
- resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.55.2.tgz#29687b8327cc9d980695603d451316706f2630ed"
- integrity sha512-yBW+R7NfwLrOjpwOJHoOSvGDDoM3ZKod5OKXi7Gd5tYqVm1mCaL0n2/wlNMcGTbPbulLBtgzjoTU1bPJAGhmYw==
- dependencies:
- "@sentry/core" "7.55.2"
- "@sentry/types" "7.55.2"
- "@sentry/utils" "7.55.2"
- tslib "^1.9.3"
-
-"@sentry/browser@7.55.2":
- version "7.55.2"
- resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.55.2.tgz#32a5cf7cc2af14b83926ea04ea140e1024f000a6"
- integrity sha512-RgA4KOD6t8XHVLm6D2oTh9KW19g3DoQ0QsrUmAq4+giSj2AyDW67VP2V4E72mCZ9Ln9AkNhY0Eh3XuD3opiFQA==
- dependencies:
- "@sentry-internal/tracing" "7.55.2"
- "@sentry/core" "7.55.2"
- "@sentry/replay" "7.55.2"
- "@sentry/types" "7.55.2"
- "@sentry/utils" "7.55.2"
- tslib "^1.9.3"
+"@sentry-internal/tracing@7.69.0":
+ version "7.69.0"
+ resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.69.0.tgz#8d8eb740b72967b6ba3fdc0a5173aa55331b7d35"
+ integrity sha512-4BgeWZUj9MO6IgfO93C9ocP3+AdngqujF/+zB2rFdUe+y9S6koDyUC7jr9Knds/0Ta72N/0D6PwhgSCpHK8s0Q==
+ dependencies:
+ "@sentry/core" "7.69.0"
+ "@sentry/types" "7.69.0"
+ "@sentry/utils" "7.69.0"
+ tslib "^2.4.1 || ^1.9.3"
+
+"@sentry/browser@7.69.0":
+ version "7.69.0"
+ resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.69.0.tgz#65427c90fb71c1775e2c1e38431efb7f4aec1e34"
+ integrity sha512-5ls+zu2PrMhHCIIhclKQsWX5u6WH0Ez5/GgrCMZTtZ1d70ukGSRUvpZG9qGf5Cw1ezS1LY+1HCc3whf8x8lyPw==
+ dependencies:
+ "@sentry-internal/tracing" "7.69.0"
+ "@sentry/core" "7.69.0"
+ "@sentry/replay" "7.69.0"
+ "@sentry/types" "7.69.0"
+ "@sentry/utils" "7.69.0"
+ tslib "^2.4.1 || ^1.9.3"
"@sentry/bundler-plugin-core@2.2.2":
version "2.2.2"
@@ -2637,14 +2637,14 @@
"@sentry/utils" "7.53.1"
tslib "^1.9.3"
-"@sentry/core@7.55.2":
- version "7.55.2"
- resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.55.2.tgz#a3988393ab791eba5d7fe735dfecea5a615e9e50"
- integrity sha512-clzQirownxqADv9+fopyMJTHzaoWedkN2+mi4ro1LxjLgROdXBFurMCC1nT+7cH/xvQ5gMIRkM/y/4gRtKy2Ew==
+"@sentry/core@7.69.0":
+ version "7.69.0"
+ resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.69.0.tgz#ebbe01df573f438f8613107020a4e18eb9adca4d"
+ integrity sha512-V6jvK2lS8bhqZDMFUtvwe2XvNstFQf5A+2LMKCNBOV/NN6eSAAd6THwEpginabjet9dHsNRmMk7WNKvrUfQhZw==
dependencies:
- "@sentry/types" "7.55.2"
- "@sentry/utils" "7.55.2"
- tslib "^1.9.3"
+ "@sentry/types" "7.69.0"
+ "@sentry/utils" "7.69.0"
+ tslib "^2.4.1 || ^1.9.3"
"@sentry/node@7.53.1":
version "7.53.1"
@@ -2660,24 +2660,24 @@
lru_map "^0.3.3"
tslib "^1.9.3"
-"@sentry/replay@7.55.2":
- version "7.55.2"
- resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.55.2.tgz#001eeb4d0dd900630ddfcea99185556b0699c12a"
- integrity sha512-G9iAcI9bvy5X8fvdz0QxF3LJ8oGB0Vxt0iOPdRZYhjIcPbNpE3NaeT6xZlNX1pCcHLroE6BMRF/6TTalcl5Erw==
+"@sentry/replay@7.69.0":
+ version "7.69.0"
+ resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.69.0.tgz#d727f96292d2b7c25df022fa53764fd39910fcda"
+ integrity sha512-oUqWyBPFUgShdVvgJtV65EQH9pVDmoYVQMOu59JI6FHVeL3ald7R5Mvz6GaNLXsirvvhp0yAkcAd2hc5Xi6hDw==
dependencies:
- "@sentry/core" "7.55.2"
- "@sentry/types" "7.55.2"
- "@sentry/utils" "7.55.2"
+ "@sentry/core" "7.69.0"
+ "@sentry/types" "7.69.0"
+ "@sentry/utils" "7.69.0"
"@sentry/types@7.53.1":
version "7.53.1"
resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.53.1.tgz#3eefbad851f2d0deff67285d7e976d23d7d06a41"
integrity sha512-/ijchRIu+jz3+j/zY+7KRPfLSCY14fTx5xujjbOdmEKjmIHQmwPBdszcQm40uwofrR8taV4hbt5MFN+WnjCkCw==
-"@sentry/types@7.55.2":
- version "7.55.2"
- resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.55.2.tgz#1abd2e02308fcd9ff3e0ac0a56c6d67e36764964"
- integrity sha512-mAtkA8wvUDrLjAAmy9tjn+NiXcxVz/ltbslTKaIW6JNgVRz5kMt1Ny8RJsgqaZqa4LFP8q+IvWw4Vd91kb57rA==
+"@sentry/types@7.69.0":
+ version "7.69.0"
+ resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.69.0.tgz#012b8d90d270a473cc2a5cf58a56870542739292"
+ integrity sha512-zPyCox0mzitzU6SIa1KIbNoJAInYDdUpdiA+PoUmMn2hFMH1llGU/cS7f4w/mAsssTlbtlBi72RMnWUCy578bw==
"@sentry/utils@7.53.1":
version "7.53.1"
@@ -2687,13 +2687,13 @@
"@sentry/types" "7.53.1"
tslib "^1.9.3"
-"@sentry/utils@7.55.2":
- version "7.55.2"
- resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.55.2.tgz#6a214c867c73305faac0997bdef4581f3bee0128"
- integrity sha512-Yv9XtbOESdN7bkK2AMrKsmKMF5OOVv5v5hVcOqXtSTw1t2oMAtRjXXqGpUo+TkdTOjeoX6dr19ozVFHaGvqHkw==
+"@sentry/utils@7.69.0":
+ version "7.69.0"
+ resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.69.0.tgz#b7594e4eb2a88b9b25298770b841dd3f81bd2aa4"
+ integrity sha512-4eBixe5Y+0EGVU95R4NxH3jkkjtkE4/CmSZD4In8SCkWGSauogePtq6hyiLsZuP1QHdpPb9Kt0+zYiBb2LouBA==
dependencies:
- "@sentry/types" "7.55.2"
- tslib "^1.9.3"
+ "@sentry/types" "7.69.0"
+ tslib "^2.4.1 || ^1.9.3"
"@sentry/webpack-plugin@2.2.2":
version "2.2.2"
@@ -14822,6 +14822,11 @@ tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.5.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913"
integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==
+"tslib@^2.4.1 || ^1.9.3":
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae"
+ integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==
+
tslib@~2.4.0:
version "2.4.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e"