Skip to content

Commit

Permalink
chore(perf): Add fixture for Slow DB Query alert email (#66595)
Browse files Browse the repository at this point in the history
Preparing for some potential uncoming improvements.

- add a JSON fixture for an occurrence and event of a Slow DB Issue
- produce an occurrence when loading the preview, otherwise it errors
out
  • Loading branch information
gggritso authored Mar 11, 2024
1 parent e38f43f commit 06c4982
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 3 deletions.
154 changes: 154 additions & 0 deletions src/sentry/data/samples/transaction-slow-db-query.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
{
"platform": "python",
"message": "",
"tags": [
["browser", "Safari 15.5"],
["browser.name", "Safari"],
["client_os", "Mac OS X 10.15.7"],
["client_os.name", "Mac OS X"],
["device", "Mac"],
["device.family", "Mac"],
["environment", "production"],
["sentry:release", "0.1"],
["http.status_code", "200"],
["level", "info"],
["runtime", "CPython 3.8.9"],
["runtime.name", "CPython"],
["user", "ip:127.0.0.1"],
["transaction", "/api/marketing-info/"],
["url", "http://service.io/api/marketing-info/"]
],
"_metrics": { "bytes.ingested.event": 45944, "bytes.stored.event": 48948 },
"breakdowns": {
"span_ops": {
"ops.db": { "value": 509.444952, "unit": "millisecond" },
"total.time": { "value": 2065.712928, "unit": "millisecond" }
}
},
"contexts": {
"browser": { "name": "Safari", "version": "15.5", "type": "browser" },
"client_os": { "name": "Mac OS X", "type": "os" },
"response": { "status_code": 200, "type": "response" },
"runtime": {
"name": "CPython",
"version": "3.11.6",
"build": "3.11.6 (main, Nov 29 2023)",
"type": "runtime"
},
"trace": {
"trace_id": "544bb57898d8452a55baff3a83e373",
"span_id": "9d3a7889de40f396",
"op": "http.server",
"status": "ok",
"exclusive_time": 1.35088,
"client_sample_rate": 1.0,
"hash": "4c65d02b403d7cfd",
"type": "trace"
}
},
"culprit": "/api/marketing-info/",
"environment": "production",
"extra": { "sys.argv": ["uwsgi"] },
"grouping_config": {
"enhancements": "KLUv_SCrDQQAgoccI7CnDVQUpQkWg3WZl4GVObL7IItQShcbOqCaSEq4PSwiGyEBCboIuvZFbwr9z_Jm0b8YezsLrsfvusXHrAUeVApY43fPPDSqTdBF0LUp8bc786Nk1pj6hP1s8OeUpKNahVKKWpQBszCEdnQ-oiGjAhIBBBAFLNdQx6dwQXVn",
"id": "newstyle:2023-01-11"
},
"key_id": "7531",
"level": "info",
"location": "/api/marketing-info/",
"logger": "",
"measurements": { "num_of_spans": { "value": 2.0, "unit": "none" } },
"metadata": {
"location": "/api/marketing-info/",
"title": "/api/marketing-info/"
},
"nodestore_insert": 1709676070.473263,
"received": 1709676065.739439,
"request": {
"url": "http://service.io/api/marketing-info/",
"method": "GET",
"data": {},
"headers": [
["Accept", "application/json; charset=utf-8"],
["Accept-Encoding", "gzip, deflate, br, zstd"],
["Accept-Language", "en-US,en;q=0.9"],
["Content-Length", "0"],
["Content-Type", "application/json"],
["Host", "service.io"]
],
"env": {
"REMOTE_ADDR": "127.0.0.1",
"SERVER_NAME": "myserver.local",
"SERVER_PORT": "9000"
},
"inferred_content_type": "application/json"
},
"sdk": {
"name": "sentry.python.django",
"version": "1.39.2",
"integrations": ["django"],
"packages": [{ "name": "pypi:sentry-sdk", "version": "1.39.2" }]
},
"span_grouping_config": { "id": "default:2022-10-27" },
"spans": [
{
"timestamp": 1709676065.721245,
"start_timestamp": 1709676065.192259,
"exclusive_time": 0.072002,
"description": "django.middleware",
"op": "middleware.django",
"span_id": "aeba241186079368",
"parent_span_id": "9d3a7889de40f396",
"trace_id": "544bb57898d8452a55baff3a83e373",
"hash": "410f212e9e071c82",
"same_process_as_parent": true
},
{
"timestamp": 1709676065.710968,
"start_timestamp": 1709676065.21067,
"exclusive_time": 500.298023,
"description": "SELECT \"marketing_information\".\"id\", \"marketing_information\".\"email\", \"marketing_information\".\"subscribed\", \"marketing_information\".\"updated_at\", \"marketing_information\".\"category\", \"marketing_information\".\"opted_out\" FROM \"marketing_information\" WHERE \"marketing_information\".\"email\" IN (SELECT U0.\"email\" FROM \"users\" U0 WHERE U0.\"user_id\" = %s)",
"op": "db",
"span_id": "b3da1046fed392a3",
"trace_id": "544bb57898d8452a55baff3a83e373",
"data": {
"code.filepath": "src/marketing.py",
"code.function": "do_marketing",
"code.lineno": 111,
"code.namespace": "marketing",
"db.name": "control",
"db.system": "postgresql",
"server.address": "127.0.0.1",
"server.port": "6432"
},
"sentry_tags": {
"action": "SELECT",
"browser.name": "Google Chrome",
"category": "db",
"description": "SELECT .. FROM marketing_information WHERE email IN (SELECT email FROM users AS U0 WHERE user_id = %s)",
"domain": ",marketing_information,users,",
"environment": "prod",
"group": "e1d1cce539387892",
"op": "db",
"platform": "python",
"sdk.name": "sentry.python.django",
"sdk.version": "1.39.2",
"system": "postgresql",
"transaction": "/api/marketing-info/",
"transaction.method": "GET",
"transaction.op": "http.server",
"user": "id:1"
},
"hash": "34d43cb5d9e46c99",
"same_process_as_parent": true
}
],
"title": "/api/marketing-info/",
"transaction": "/api/marketing-info/",
"transaction_info": { "source": "route" },
"type": "transaction",
"user": {
"ip_address": "127.0.0.1"
},
"version": "7"
}
1 change: 1 addition & 0 deletions src/sentry/templates/sentry/debug/mail/preview.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
<option value="mail/error-alert/">Error Alert</option>
<option value="mail/performance-alert/transaction-n-plus-one">N+1 Database Query Alert</option>
<option value="mail/performance-alert/transaction-n-plus-one-api-call">N+1 API Call Alert</option>
<option value="mail/performance-alert/transaction-slow-db-query">Slow DB Query</option>
<option value="mail/performance-alert/transaction-render-blocking-asset">Render Blocking Asset Alert</option>
<option value="mail/generic-alert/">Generic Alert</option>
<option value="mail/digest/">Digest</option>
Expand Down
27 changes: 27 additions & 0 deletions src/sentry/testutils/helpers/notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
PerformanceNPlusOneAPICallsGroupType,
PerformanceNPlusOneGroupType,
PerformanceRenderBlockingAssetSpanGroupType,
PerformanceSlowDBQueryGroupType,
ProfileFileIOGroupType,
)
from sentry.issues.issue_occurrence import IssueEvidence, IssueOccurrence
Expand Down Expand Up @@ -123,6 +124,32 @@ def get_title_link(self, *args):
)

SAMPLE_TO_OCCURRENCE_MAP = {
"transaction-slow-db-query": IssueOccurrence(
uuid.uuid4().hex,
1,
uuid.uuid4().hex,
["ad800f7f33d223e714d718cb4e7d3ce1"],
"Slow DB Query",
'SELECT "marketing_information"."id", "marketing_information"."email", "marketing_information"."subscribed", "marketing_information"."updated_at", "marketing_information"."category", "marketing_information"."opted_out" FROM "marketing_information" WHERE "marketing_information"."email" IN (SELECT U0."email" FROM "users" U0 WHERE U0."user_id" = %s)',
None,
{
"op": "db",
"cause_span_ids": [],
"parent_span_ids": [],
"offender_span_ids": [
"b3da1046fed392a3",
],
"transaction_name": "",
"num_repeating_spans": "1",
"repeating_spans": 'SELECT "marketing_information"."id", "marketing_information"."email", "marketing_information"."subscribed", "marketing_information"."updated_at", "marketing_information"."category", "marketing_information"."opted_out" FROM "marketing_information" WHERE "marketing_information"."email" IN (SELECT U0."email" FROM "users" U0 WHERE U0."user_id" = %s)',
"repeating_spans_compact": 'SELECT "marketing_information"."id", "marketing_information"."email", "marketing_information"."subscribed", "marketing_information"."updated_at", "marketing_information"."category", "marketing_information"."opted_out" FROM "marketing_information" WHERE "marketing_information"."email" IN (SELECT U0."email" FROM "users" U0 WHERE U0."user_id" = %s)',
},
[],
PerformanceSlowDBQueryGroupType,
datetime.now(UTC),
"info",
"/api/marketing-info/",
),
"transaction-n-plus-one-api-call": IssueOccurrence(
uuid.uuid4().hex,
1,
Expand Down
10 changes: 7 additions & 3 deletions src/sentry/web/frontend/debug/mail.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@
from sentry.digests.utils import get_digest_metadata
from sentry.event_manager import EventManager, get_event_type
from sentry.http import get_server_hostname
from sentry.issues.grouptype import NoiseConfig, PerformanceNPlusOneGroupType
from sentry.issues.grouptype import NoiseConfig
from sentry.issues.occurrence_consumer import process_event_and_issue_occurrence
from sentry.issues.producer import PayloadType, produce_occurrence_to_kafka
from sentry.mail.notifications import get_builder_args
from sentry.models.activity import Activity
from sentry.models.group import Group, GroupStatus
Expand Down Expand Up @@ -203,19 +204,22 @@ def make_performance_event(project: Project, sample_name: str):
timestamp = datetime(2017, 9, 6, 0, 0)
start_timestamp = timestamp - timedelta(seconds=3)
event_id = "44f1419e73884cd2b45c79918f4b6dc4"
occurrence_data = SAMPLE_TO_OCCURRENCE_MAP[sample_name].to_dict()
mock_occurrence = SAMPLE_TO_OCCURRENCE_MAP[sample_name]
occurrence_data = mock_occurrence.to_dict()
occurrence_data["event_id"] = event_id
perf_data = dict(load_data(sample_name, start_timestamp=start_timestamp, timestamp=timestamp))
perf_data["event_id"] = event_id
perf_data["project_id"] = project.id

with mock.patch.object(
PerformanceNPlusOneGroupType, "noise_config", new=NoiseConfig(0, timedelta(minutes=1))
mock_occurrence.type, "noise_config", new=NoiseConfig(0, timedelta(minutes=1))
):
occurrence, group_info = process_event_and_issue_occurrence(
occurrence_data,
perf_data,
)
produce_occurrence_to_kafka(payload_type=PayloadType.OCCURRENCE, occurrence=occurrence)

assert group_info is not None
generic_group = group_info.group
group_event = generic_group.get_latest_event()
Expand Down

0 comments on commit 06c4982

Please sign in to comment.