Browse Source

feat(uptime): add trace sampling boolean field to model (#80749)

migration to add trace sampling option to the uptime model. part of
https://github.com/getsentry/team-uptime/issues/22

Note that if set to true, we will set the header so that the sampling
decision is "deferred", a.k.a we will not force a sampling decision, we
will let the user's application's sentry SDK make the sampling decision,
instead of default off.

- https://develop.sentry.dev/sdk/telemetry/traces/#the-sampled-value


reading the docs, i think i need to modify the default migration for
adding a new field with a default? but wanted to double check
Josh Ferge 3 months ago
parent
commit
ce5771894d

+ 1 - 1
migrations_lockfile.txt

@@ -12,5 +12,5 @@ remote_subscriptions: 0003_drop_remote_subscription
 replays: 0004_index_together
 sentry: 0790_delete_dashboard_perms_col
 social_auth: 0002_default_auto_field
-uptime: 0017_unique_on_timeout
+uptime: 0018_add_trace_sampling_field_to_uptime
 workflow_engine: 0012_data_source_type_change

+ 68 - 0
src/sentry/uptime/migrations/0018_add_trace_sampling_field_to_uptime.py

@@ -0,0 +1,68 @@
+# Generated by Django 5.1.1 on 2024-11-14 16:44
+
+import django
+from django.db import migrations, models
+
+from sentry.new_migrations.migrations import CheckedMigration
+
+
+class Migration(CheckedMigration):
+    # This flag is used to mark that a migration shouldn't be automatically run in production.
+    # This should only be used for operations where it's safe to run the migration after your
+    # code has deployed. So this should not be used for most operations that alter the schema
+    # of a table.
+    # Here are some things that make sense to mark as post deployment:
+    # - Large data migrations. Typically we want these to be run manually so that they can be
+    #   monitored and not block the deploy for a long period of time while they run.
+    # - Adding indexes to large tables. Since this can take a long time, we'd generally prefer to
+    #   run this outside deployments so that we don't block them. Note that while adding an index
+    #   is a schema change, it's completely safe to run the operation after the code has deployed.
+    # Once deployed, run these manually via: https://develop.sentry.dev/database-migrations/#migration-deployment
+
+    is_post_deployment = False
+
+    dependencies = [
+        ("uptime", "0017_unique_on_timeout"),
+    ]
+
+    operations = [
+        migrations.SeparateDatabaseAndState(
+            database_operations=[
+                migrations.RunSQL(
+                    """
+                    ALTER TABLE "uptime_uptimesubscription" ADD COLUMN "trace_sampling" boolean NOT NULL DEFAULT false;
+                    """,
+                    reverse_sql="""
+                    ALTER TABLE "uptime_uptimesubscription" DROP COLUMN "trace_sampling";
+                    """,
+                    hints={"tables": ["uptime_uptimesubscription"]},
+                ),
+            ],
+            state_operations=[
+                migrations.AddField(
+                    model_name="uptimesubscription",
+                    name="trace_sampling",
+                    field=models.BooleanField(default=False),
+                ),
+            ],
+        ),
+        migrations.AddConstraint(
+            model_name="uptimesubscription",
+            constraint=models.UniqueConstraint(
+                models.F("url"),
+                models.F("interval_seconds"),
+                models.F("timeout_ms"),
+                models.F("method"),
+                models.F("trace_sampling"),
+                django.db.models.functions.text.MD5("headers"),
+                django.db.models.functions.comparison.Coalesce(
+                    django.db.models.functions.text.MD5("body"), models.Value("")
+                ),
+                name="uptime_uptimesubscription_unique_subscription_check_2",
+            ),
+        ),
+        migrations.RemoveConstraint(
+            model_name="uptimesubscription",
+            name="uptime_uptimesubscription_unique_subscription_check",
+        ),
+    ]

+ 5 - 1
src/sentry/uptime/models.py

@@ -57,6 +57,9 @@ class UptimeSubscription(BaseRemoteSubscription, DefaultFieldsModelExisting):
     headers = JSONField(json_dumps=headers_json_encoder, db_default=[])
     # HTTP body to send when performing the check
     body = models.TextField(null=True)
+    # How to sample traces for this monitor. Note that we always send a trace_id, so any errors will
+    # be associated, this just controls the span sampling.
+    trace_sampling = models.BooleanField(default=False)
 
     objects: ClassVar[BaseManager[Self]] = BaseManager(
         cache_fields=["pk", "subscription_id"],
@@ -73,9 +76,10 @@ class UptimeSubscription(BaseRemoteSubscription, DefaultFieldsModelExisting):
                 "interval_seconds",
                 "timeout_ms",
                 "method",
+                "trace_sampling",
                 MD5("headers"),
                 Coalesce(MD5("body"), Value("")),
-                name="uptime_uptimesubscription_unique_subscription_check",
+                name="uptime_uptimesubscription_unique_subscription_check_2",
             ),
         ]
 

+ 3 - 0
tests/sentry/uptime/migrations/test_0016_translate_uptime_object_headers_to_lists.py

@@ -1,6 +1,9 @@
+import pytest
+
 from sentry.testutils.cases import TestMigrations
 
 
+@pytest.mark.skip("Migration is no longer runnable. Retain until migration is removed.")
 class TestTranslateUotimeHeaderObjectsToList(TestMigrations):
     app = "uptime"
     migrate_from = "0015_headers_deafult_empty_list"