Skip to content

Commit

Permalink
feat(uptime): Extract domain and suffix from urls when creating uptim…
Browse files Browse the repository at this point in the history
…e monitors

This uses `tldextract` to extract the domain and suffix from urls, for use in limiting number of monitors per domain, analytics and detecting anomalous failures across monitors.
  • Loading branch information
wedamija committed Aug 28, 2024
1 parent 0029ce9 commit cd67e72
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 0 deletions.
8 changes: 8 additions & 0 deletions src/sentry/uptime/subscriptions/subscriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from sentry.models.project import Project
from sentry.types.actor import Actor
from sentry.uptime.detectors.url_extraction import extractor
from sentry.uptime.models import (
ProjectUptimeSubscription,
ProjectUptimeSubscriptionMode,
Expand All @@ -28,13 +29,20 @@ def create_uptime_subscription(
Creates a new uptime subscription. This creates the row in postgres, and fires a task that will send the config
to the uptime check system.
"""
# We extract the domain and suffix of the url here. This is used to prevent there being too many checks to a single
# domain.
# We enable private PSL domains so that hosting services that use subdomains are treated as suffixes for the
# purposes of monitoring.
result = extractor.extract_str(url, include_psl_private_domains=True)
subscription, created = UptimeSubscription.objects.get_or_create(
url=url,
interval_seconds=interval_seconds,
defaults={
"status": UptimeSubscription.Status.CREATING.value,
"type": UPTIME_SUBSCRIPTION_TYPE,
"timeout_ms": timeout_ms,
"url_domain": result.domain,
"url_suffix": result.suffix,
},
)
if subscription.status == UptimeSubscription.Status.DELETING.value:
Expand Down
20 changes: 20 additions & 0 deletions tests/sentry/uptime/subscriptions/test_subscriptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,24 @@ def test(self):
assert uptime_sub.status == UptimeSubscription.Status.ACTIVE.value
assert uptime_sub.type == UPTIME_SUBSCRIPTION_TYPE
assert uptime_sub.url == url
assert uptime_sub.url_domain == "sentry"
assert uptime_sub.url_suffix == "io"
assert uptime_sub.interval_seconds == uptime_sub.interval_seconds
assert uptime_sub.timeout_ms == timeout_ms

def test_private_domain_suffix(self):
url = "https://test.vercel.app"
interval_seconds = 300
timeout_ms = 500
uptime_sub = create_uptime_subscription(url, interval_seconds, timeout_ms)
# Subscription.subscription_id ends up set in the task, so refresh
uptime_sub.refresh_from_db()
assert uptime_sub.subscription_id is None
assert uptime_sub.status == UptimeSubscription.Status.CREATING.value
assert uptime_sub.type == UPTIME_SUBSCRIPTION_TYPE
assert uptime_sub.url == url
assert uptime_sub.url_domain == "test"
assert uptime_sub.url_suffix == "vercel.app"
assert uptime_sub.interval_seconds == uptime_sub.interval_seconds
assert uptime_sub.timeout_ms == timeout_ms

Expand Down Expand Up @@ -81,6 +99,8 @@ def test_without_task(self):
assert uptime_sub.status == UptimeSubscription.Status.CREATING.value
assert uptime_sub.type == UPTIME_SUBSCRIPTION_TYPE
assert uptime_sub.url == url
assert uptime_sub.url_domain == "sentry"
assert uptime_sub.url_suffix == "io"
assert uptime_sub.interval_seconds == uptime_sub.interval_seconds
assert uptime_sub.timeout_ms == timeout_ms

Expand Down

0 comments on commit cd67e72

Please sign in to comment.