This repository has been archived by the owner on Aug 14, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 225
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(feedback): add page for feedback architecture (#1313)
* feat(feedback): add a page for feedback architecture * Camelcase for model name * Add diagrams * Add some whitespace * Header capitalizion * Update src/docs/feedback-architecture.mdx Co-authored-by: Catherine Lee <[email protected]> * Update src/docs/feedback-architecture.mdx Co-authored-by: Michelle Zhang <[email protected]> * Update src/docs/feedback-architecture.mdx Co-authored-by: Michelle Zhang <[email protected]> * Update src/docs/feedback-architecture.mdx Co-authored-by: Michelle Zhang <[email protected]> * Update src/docs/feedback-architecture.mdx Co-authored-by: Michelle Zhang <[email protected]> * Update src/docs/feedback-architecture.mdx Co-authored-by: Michelle Zhang <[email protected]> * Update src/docs/feedback-architecture.mdx Co-authored-by: Michelle Zhang <[email protected]> * Add to bottom of sidebar as 'User Feedback Architecture' * Make diagrams light mode * Tweak ##Creation sources wording * Add links to envelope formats in Creation sources + some more tweaks * Code-ify user_report * Reword mistakenly * Tweak diagrams: envelopes->envelope and rm widget/api from first graph * Reword user report endpoint * Add crash reports section * Split up diagrams and finalize * Tweak feedback envelope * Update report diagram * Update title * Add ff's * Use bullet points * Tweak ff descrip * Final tweaks --------- Co-authored-by: Catherine Lee <[email protected]> Co-authored-by: Michelle Zhang <[email protected]>
- Loading branch information
1 parent
8c0e0a8
commit 024b711
Showing
2 changed files
with
200 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
--- | ||
title: User Feedback Architecture | ||
--- | ||
|
||
**The goal of this doc is to give engineers an in-depth understanding of User Feedback's backend.** | ||
It will: | ||
1. describe the relevant ingestion pipelines, data models, and functions. | ||
2. explain the difference between “feedback”, “user reports”, and “crash reports”, and why we built and need to support each. | ||
|
||
## Creation sources | ||
When broken down, there are **5** ways to create feedback in our system 😵💫. | ||
(But 4 of them, related to user reports, are quite similar!) A good reference is the | ||
`FeedbackCreationSource(Enum)` in [create_feedback.py](https://github.com/getsentry/sentry/blob/2b642e149c79b251e1c2f4339fc73d656347d74e/src/sentry/feedback/usecases/create_feedback.py#L33-L33). | ||
The 4 ways _clients_ can create feedback are: | ||
|
||
`NEW_FEEDBACK_ENVELOPE`: [The new format](https://develop.sentry.dev/sdk/envelopes/#full-examples) created by the Replay team when adding | ||
the [User Feedback Widget](https://docs.sentry.io/product/user-feedback/#user-feedback-widget) | ||
to the JavaScript SDK. It allows adding more information, for example tags, | ||
release, url, etc. | ||
|
||
`USER_REPORT_ENVELOPE`: [The older format](https://develop.sentry.dev/sdk/envelopes/#user-feedback) with name/email/comments, that requires | ||
`event_id` to link a Sentry error event. | ||
|
||
`USER_REPORT_DJANGO_ENDPOINT`: [The Web API](https://docs.sentry.io/api/projects/submit-user-feedback/) | ||
|
||
`CRASH_REPORT_EMBED_FORM`: The [crash report modal](https://docs.sentry.io/product/user-feedback/#crash-report-modal) | ||
|
||
## How feedback is stored | ||
On the backend, each feedback submission in Sentry's UI is **an un-grouped issue occurrence**, | ||
saved via the [issues platform](https://develop.sentry.dev/issue-platform/). | ||
The entrypoint is [**`create_feedback_issue()`**](https://github.com/getsentry/sentry/blob/2b642e149c79b251e1c2f4339fc73d656347d74e/src/sentry/feedback/usecases/create_feedback.py#L184-L184), | ||
which | ||
1. filters feedback with empty or spam messages. Note **anonymous feedbacks are not filtered** (missing name and/or email). | ||
2. sends to issues pipeline in a standardized format. To make sure it is never grouped, we use a random UUID for the fingerprint. | ||
|
||
--- | ||
|
||
## Feedback events | ||
|
||
The new and preferred way to send feedback from the SDK is in an [event envelope](https://develop.sentry.dev/sdk/envelopes/#full-examples). | ||
The format is the same as error events, except the `type` header = `"feedback"`. While | ||
user reports have an associated event, **new feedback _is_ an event**. This | ||
offers 2 improvements: | ||
|
||
1. Users can submit generic feedback without an error occurring. We're allowing users to catch things that Sentry can’t! | ||
2. Rather than waiting for the associated error to be ingested asynchronously, we immediately get access to context like the environment, platform, replay, user, tags... | ||
|
||
The user's submission is wrapped in a context object: | ||
|
||
```Python/Javascript | ||
event[”contexts”][”feedback”] = { | ||
"name": <user-provided>, | ||
"contact_email": <user-provided>, | ||
"message": <user-provided>, | ||
"url": <referring web page>, | ||
"source": <developer-provided, ex: "widget"> | ||
} | ||
// all fields are technically optional, but recommended | ||
// the widget can be configured to require a non-empty email and/or name | ||
``` | ||
|
||
- This doc refers to the payload format (`event` in the pseudo-code above) as a “**feedback event”**. | ||
- The feedback [widget](https://docs.sentry.io/platforms/javascript/user-feedback/#user-feedback-widget), which is installed by default, sends these envelopes. | ||
- API: for SDK v8.0.0+, we use the `sendFeedback` function. | ||
<br/><br/> | ||
|
||
### Ingest diagram | ||
|
||
![](https://mermaid.ink/svg/pako:eNptkc1qwzAQhF9F7MmGmN59KJSmx_ZQ91IsYxR5YwvbkqqfgEny7l05NW0hOg3a0erb2TNI0yGU0DthB_ax55rREdbWnyY69mTtpKQIyuiGFcUju3BAfcLJWORwYe84iYVrHlaxOo6tNNrHGV1WK92jD8URsTsIORZ4Qh18k6cXv76t8VfEiJ4JzyRO6BYWhB_TL9KhCNhubVrlfcTU425hbWf-UHD44TBSRudQS_QcbhTmP4WmNHwwDuvsbZN5c8dIuC9pmCoQwpwgvY4HUWccqiQenim3cTDRU055Azugl7NQHWV9TiFzCAPOVCxJTqofAgeur2QUMZhq0RLK4CLuINqOhtwrQTuat0vsFLG93pa37vD6DRJvo7g) | ||
[diagram source](https://mermaid.live/edit#pako:eNptkc1qwzAQhF9F7MmGmN59KJSmx_ZQ91IsYxR5YwvbkqqfgEny7l05NW0hOg3a0erb2TNI0yGU0DthB_ax55rREdbWnyY69mTtpKQIyuiGFcUju3BAfcLJWORwYe84iYVrHlaxOo6tNNrHGV1WK92jD8URsTsIORZ4Qh18k6cXv76t8VfEiJ4JzyRO6BYWhB_TL9KhCNhubVrlfcTU425hbWf-UHD44TBSRudQS_QcbhTmP4WmNHwwDuvsbZN5c8dIuC9pmCoQwpwgvY4HUWccqiQenim3cTDRU055Azugl7NQHWV9TiFzCAPOVCxJTqofAgeur2QUMZhq0RLK4CLuINqOhtwrQTuat0vsFLG93pa37vD6DRJvo7g) | ||
|
||
In Relay v24.5.1, we migrated feedback to its own kafka topic + consumer, | ||
`ingest-feedback-events`. This decouples risk and ownership from errors | ||
(`ingest-events`). | ||
<br/> | ||
|
||
### Attachments | ||
|
||
We only use attachments for the widget’s screenshot feature, which allows users | ||
to submit **at most 1 screenshot per feedback**. Attachments are another [item type](https://develop.sentry.dev/sdk/envelopes/#attachment) | ||
in an envelope. | ||
- SDK v8.0.0+, Relay v24.5.1+: Sends the feedback and attachment items in the same envelope. | ||
- SDK < v8, all Relay versions: Sends a separate envelope for each item. | ||
|
||
**The feedback pipeline does not process attachments**. Relay routes them to | ||
a separate topic and storage, and the UI makes a separate request for them. | ||
|
||
--- | ||
|
||
## User reports | ||
|
||
The deprecated way of sending feedback is as a **user report**. This is a simple typed dict: | ||
|
||
```Python/Javascript | ||
user_report = { | ||
"event_id": <required UUID str>, | ||
"email": <optional str>, | ||
"name": <optional str>, | ||
"comments": <optional str>, | ||
} | ||
``` | ||
<br/> | ||
|
||
### Ingest diagram | ||
![](https://mermaid.ink/svg/pako:eNp9VNtq3DAQ_ZVBEHAgy77vQ6EkDfShF7KhUKzFaOXZtYgtqbpsCUn-vaOxvWmT3frF4-HozJkzIz8J7VoUK7EPyndwfyOtTDFvx8812hQeS0qmgN6F1KBtvTM21VIsc8Sw2CG2W6UfpNiMQB1U7JoJPrhW9YS9Lkm44yT8MPh7ghMdvf6uuctWJ-NsrG_nCBYQsgVjIeAOQ8AwlYrqgE1RMVYrSaAndmZokmuO0iZdqBIek42JMeNJHlgsPsCzFJ9vAQ9kAfjgNMaIrRTPZ9jfZpnjbMlj2xcXgPaAvfMI3njsjWWA8r7-6XKAj973Rqviw2bWNZ8oau6wVzwhDhihSIc3uqqN3WNMC5WS0t1AjcTNJZOPAAa_t3BWNc4ZlG2BRwojIk7yZjHfv63vi5A3-3GG_NTJ9wvzX2VsYgTfq7RzYSjZkz4ziWs0LVAeMFS0hZMhTutMrJZmSmvIlrzi-JilSxGTC1hXX-fwcnMCSG18KiuypvuhBl4Pm7eqrtbltbym2T10jrrg02MDpafJLm4yLrNvST87e2oVvYtpHzDWFZk2xVKMerjcLOVXxmDIG95aFs2K_qUUV4LUD8q0dO2fpAWQInU4EHZFYW_2XZJC2hcCqpzc-tFqsUoh45UYhd4YRXd1EKud6iNlsTVU68v4I-H_ycsfwTWaqg) | ||
[diagram source](https://mermaid.live/edit#pako:eNp9VNtq3DAQ_ZVBEHAgy77vQ6EkDfShF7KhUKzFaOXZtYgtqbpsCUn-vaOxvWmT3frF4-HozJkzIz8J7VoUK7EPyndwfyOtTDFvx8812hQeS0qmgN6F1KBtvTM21VIsc8Sw2CG2W6UfpNiMQB1U7JoJPrhW9YS9Lkm44yT8MPh7ghMdvf6uuctWJ-NsrG_nCBYQsgVjIeAOQ8AwlYrqgE1RMVYrSaAndmZokmuO0iZdqBIek42JMeNJHlgsPsCzFJ9vAQ9kAfjgNMaIrRTPZ9jfZpnjbMlj2xcXgPaAvfMI3njsjWWA8r7-6XKAj973Rqviw2bWNZ8oau6wVzwhDhihSIc3uqqN3WNMC5WS0t1AjcTNJZOPAAa_t3BWNc4ZlG2BRwojIk7yZjHfv63vi5A3-3GG_NTJ9wvzX2VsYgTfq7RzYSjZkz4ziWs0LVAeMFS0hZMhTutMrJZmSmvIlrzi-JilSxGTC1hXX-fwcnMCSG18KiuypvuhBl4Pm7eqrtbltbym2T10jrrg02MDpafJLm4yLrNvST87e2oVvYtpHzDWFZk2xVKMerjcLOVXxmDIG95aFs2K_qUUV4LUD8q0dO2fpAWQInU4EHZFYW_2XZJC2hcCqpzc-tFqsUoh45UYhd4YRXd1EKud6iNlsTVU68v4I-H_ycsfwTWaqg) | ||
<br/> | ||
|
||
### Shimming to feedback | ||
|
||
Before it was extended to generic feedback, the [`UserReport` model](https://github.com/getsentry/sentry/blob/2b642e149c79b251e1c2f4339fc73d656347d74e/src/sentry/models/userreport.py#L9-L9) | ||
was first used for crash reports. Therefore an associated event ID is required, and | ||
we use it to set environment and group before saving the model to **Postgres**. | ||
Only then can we shim the report to a **feedback event** and pass it to `create_feedback_issue()`. | ||
|
||
If the event hasn’t reached eventstore (Snuba) by the time of ingest, we still | ||
save the report, but leave the environment + group empty and skip feedback creation. | ||
|
||
To ensure the skipped reports eventually get fixed and shimmed, we | ||
added a post process job to the errors pipeline: [`link_event_to_user_report()`](https://github.com/getsentry/sentry/blob/2b642e149c79b251e1c2f4339fc73d656347d74e/src/sentry/tasks/post_process.py#L1387-L1387). | ||
This is the 5th, automated way of creating feedback. | ||
|
||
Simplified diagram: | ||
![](https://mermaid.ink/svg/pako:eNpdULtuwzAM_BWBUwIkzm4UXZq1QIF0MwNDlllLTfSoKAUokvx7ZasZWi06kMfj8a6g_EjQwhRl0OJ9j06Ux9rYPvn-g2gcpDqJ7fZZ3BCapkG4CXZ5kN3qMH-7l7NRJ-0z0_qIDtPSfAx8ZYqGWNCFXOLkI83zIfSffqirKu4QKEYfWQTPSYToFTGLmQVH8fRXbZfDKBPxIlXoUyTuVghvvxihOqnSi5X_B9XdsAFL0UozlgSucw0habLFZFvg2Uw6IaC7F6LMyR--nYI2xUwbqB72Rpbk7KNIoyk3vtZIl2TvP_9DeX4) | ||
[diagram source](https://mermaid.live/edit#pako:eNpdULtuwzAM_BWBUwIkzm4UXZq1QIF0MwNDlllLTfSoKAUokvx7ZasZWi06kMfj8a6g_EjQwhRl0OJ9j06Ux9rYPvn-g2gcpDqJ7fZZ3BCapkG4CXZ5kN3qMH-7l7NRJ-0z0_qIDtPSfAx8ZYqGWNCFXOLkI83zIfSffqirKu4QKEYfWQTPSYToFTGLmQVH8fRXbZfDKBPxIlXoUyTuVghvvxihOqnSi5X_B9XdsAFL0UozlgSucw0habLFZFvg2Uw6IaC7F6LMyR--nYI2xUwbqB72Rpbk7KNIoyk3vtZIl2TvP_9DeX4) | ||
|
||
<br/> | ||
|
||
### Envelopes | ||
|
||
User reports are also sent to Relay in [envelope format](https://develop.sentry.dev/sdk/envelopes/#user-feedback). | ||
**This item type is misleadingly called “user feedback” in some of our docs, but the | ||
item header will read `"user_report"`.** | ||
|
||
The SDK function that sends these is `captureUserFeedback`. | ||
<br/> | ||
|
||
### Django endpoint | ||
|
||
Before our envelope ingest service existed, older SDKs directly POST the report | ||
to Sentry, with | ||
`/api/0/projects/{organization_id_or_slug}/{project_id_or_slug}/user-feedback/`. | ||
|
||
See [https://docs.sentry.io/api/projects/submit-user-feedback/](https://docs.sentry.io/api/projects/submit-user-feedback/). | ||
<br/> | ||
|
||
### Crash reports | ||
|
||
The **crash report modal** pops up when Sentry detects an error on the current | ||
page, prompting users to describe what happened. On the backend, crash report | ||
data is the same as user reports. | ||
|
||
You can install it as an [SDK integration](https://docs.sentry.io/platforms/javascript/user-feedback/#crash-report-modal). | ||
|
||
We implement it as a Django view: | ||
* URL: `/api/embed/error-page/` | ||
* Python Class: `error_page_embed.ErrorPageEmbedView` | ||
|
||
Crash reports are also shimmed to feedback. The pipeline is the same as the | ||
`/user-feedback` endpoint. | ||
|
||
--- | ||
|
||
## Sentry UI | ||
|
||
![](https://mermaid.ink/svg/pako:eNp9Uj1vwjAQ_SvWTUECsWdgKaViqFQVmDhUmeRILBI7tc8DAv577YRAG6F68fn53b37OkNmcoIUCiubUqznqEU4zu87YMXGyoJcB8fTGMeFJbdNED5utkg2juwnNcayGyGMdg--034vt8kqXtOXSmXH0nhHPYV03hmokR-ypNmeIoSsnPPkvgKxMUrzFmHaQQi7pwwxmczEBeHtdY1wEV4FlwVRvpfZUWyWIpkebq_RPYRtc_8jEpK0k57ZEvuSBuSB3u23lV3GzMScWKrKRe2ZiJ0Si2dh_y_jHvZX3zqzn0jv8O3JqtieyzDTtsdxEE-oA3UYQ022lioPy3GOQghcUk0IaTArVZSMgPoaiNKzWZ10BilbT2PwTS6Z5kqGYdaQHmTlAkq5Csv03q1bu3XXH4El2dU) | ||
[diagram source](https://mermaid.live/edit#pako:eNp9Uj1vwjAQ_SvWTUECsWdgKaViqFQVmDhUmeRILBI7tc8DAv577YRAG6F68fn53b37OkNmcoIUCiubUqznqEU4zu87YMXGyoJcB8fTGMeFJbdNED5utkg2juwnNcayGyGMdg--034vt8kqXtOXSmXH0nhHPYV03hmokR-ypNmeIoSsnPPkvgKxMUrzFmHaQQi7pwwxmczEBeHtdY1wEV4FlwVRvpfZUWyWIpkebq_RPYRtc_8jEpK0k57ZEvuSBuSB3u23lV3GzMScWKrKRe2ZiJ0Si2dh_y_jHvZX3zqzn0jv8O3JqtieyzDTtsdxEE-oA3UYQ022lioPy3GOQghcUk0IaTArVZSMgPoaiNKzWZ10BilbT2PwTS6Z5kqGYdaQHmTlAkq5Csv03q1bu3XXH4El2dU) | ||
|
||
You can view the user reports related to a specific issue at the "User Feedback" | ||
tab of Issue Details. This excludes "new" feedback (anything sent from the widget). | ||
|
||
--- | ||
|
||
## Email alerts | ||
|
||
Email alerts are triggered in feedback’s post process pipeline. (Unrelated to | ||
the post process diagram above.) We apply some feedback-specific | ||
filters, **skipping emails if:** | ||
|
||
1. The feedback is [marked as spam](https://docs.sentry.io/product/user-feedback/#spam-detection-for-user-feedback) AND the `organizations.user-feedback-spam-filter-actions` feature flag is enabled. | ||
2. The source is NOT a new feedback envelope / the widget, AND the “Crash Report Notifications” setting is disabled. | ||
- in UI: Settings > Projects > (project slug) > User Feedback > “Enable Crash Report Notifications” | ||
- project option in code: `sentry:feedback_user_report_notifications` | ||
- default = true/enabled | ||
|
||
--- | ||
|
||
## Feature flags for self-hosted | ||
To disable all UI features and/or ingestion, set these to false: | ||
* `organizations:user-feedback-ui` | ||
* `organizations:feedback-visible` | ||
* `organizations:user-feedback-ingest` | ||
|
||
To disable auto spam filters, set these to false: | ||
* `organizations:user-feedback-spam-filter-ingest` | ||
* `organizations:user-feedback-spam-filter-actions` |