diff --git a/latest_migrations.manifest b/latest_migrations.manifest index 4f5e422e17f82..652db66aee3ed 100644 --- a/latest_migrations.manifest +++ b/latest_migrations.manifest @@ -5,7 +5,7 @@ contenttypes: 0002_remove_content_type_name ee: 0016_rolemembership_organization_member otp_static: 0002_throttling otp_totp: 0002_auto_20190420_0723 -posthog: 0499_hog_function_type +posthog: 0500_errortrackingsymbolset_errortrackingstackframe_and_more sessions: 0001_initial social_django: 0010_uid_db_index two_factor: 0007_auto_20201201_1019 diff --git a/posthog/migrations/0500_errortrackingsymbolset_errortrackingstackframe_and_more.py b/posthog/migrations/0500_errortrackingsymbolset_errortrackingstackframe_and_more.py new file mode 100644 index 0000000000000..9a47a75b71e4f --- /dev/null +++ b/posthog/migrations/0500_errortrackingsymbolset_errortrackingstackframe_and_more.py @@ -0,0 +1,67 @@ +# Generated by Django 4.2.15 on 2024-10-28 10:24 + +from django.db import migrations, models +import django.db.models.deletion +import posthog.models.utils + + +class Migration(migrations.Migration): + dependencies = [ + ("posthog", "0499_hog_function_type"), + ] + + operations = [ + migrations.CreateModel( + name="ErrorTrackingSymbolSet", + fields=[ + ( + "id", + models.UUIDField( + default=posthog.models.utils.UUIDT, editable=False, primary_key=True, serialize=False + ), + ), + ("ref", models.TextField()), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("storage_ptr", models.TextField(null=True)), + ("team", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="posthog.team")), + ], + ), + migrations.CreateModel( + name="ErrorTrackingStackFrame", + fields=[ + ( + "id", + models.UUIDField( + default=posthog.models.utils.UUIDT, editable=False, primary_key=True, serialize=False + ), + ), + ("raw_id", models.TextField()), + ("created_at", models.DateTimeField(auto_now_add=True)), + ("contents", models.JSONField()), + ("resolved", models.BooleanField()), + ( + "symbol_set", + models.ForeignKey( + null=True, on_delete=django.db.models.deletion.CASCADE, to="posthog.errortrackingsymbolset" + ), + ), + ("team", models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to="posthog.team")), + ], + ), + migrations.AddIndex( + model_name="errortrackingsymbolset", + index=models.Index(fields=["team_id", "ref"], name="posthog_err_team_id_927574_idx"), + ), + migrations.AddConstraint( + model_name="errortrackingsymbolset", + constraint=models.UniqueConstraint(fields=("team_id", "ref"), name="unique_ref_per_team"), + ), + migrations.AddIndex( + model_name="errortrackingstackframe", + index=models.Index(fields=["team_id", "raw_id"], name="posthog_err_team_id_dc6a7f_idx"), + ), + migrations.AddConstraint( + model_name="errortrackingstackframe", + constraint=models.UniqueConstraint(fields=("team_id", "raw_id"), name="unique_raw_id_per_team"), + ), + ] diff --git a/posthog/models/error_tracking/error_tracking.py b/posthog/models/error_tracking/error_tracking.py index 7e4c625446520..6cca164d2afe0 100644 --- a/posthog/models/error_tracking/error_tracking.py +++ b/posthog/models/error_tracking/error_tracking.py @@ -69,3 +69,43 @@ class ErrorTrackingIssueFingerprint(models.Model): class Meta: constraints = [models.UniqueConstraint(fields=["team", "fingerprint"], name="unique fingerprint for team")] + + +class ErrorTrackingSymbolSet(UUIDModel): + # Derived from the symbol set reference + ref = models.TextField(null=False, blank=False) + team = models.ForeignKey("Team", on_delete=models.CASCADE) + created_at = models.DateTimeField(auto_now_add=True) + # How we stored this symbol set, and where to look for it + # These are null if we failed to find a symbol set for a given reference. We store a + # row anyway, so if someone comes along later and uploads a symbol set for this reference, + # we can know which frame resolution results below to drop. + storage_ptr = models.TextField(null=True, blank=False) + + class Meta: + indexes = [ + models.Index(fields=["team_id", "ref"]), + ] + + constraints = [ + models.UniqueConstraint(fields=["team_id", "ref"], name="unique_ref_per_team"), + ] + + +class ErrorTrackingStackFrame(UUIDModel): + # Produced by a raw frame + raw_id = models.TextField(null=False, blank=False) + team = models.ForeignKey("Team", on_delete=models.CASCADE) + created_at = models.DateTimeField(auto_now_add=True) + symbol_set = models.ForeignKey("ErrorTrackingSymbolSet", on_delete=models.CASCADE, null=True) + contents = models.JSONField(null=False, blank=False) + resolved = models.BooleanField(null=False, blank=False) + + class Meta: + indexes = [ + models.Index(fields=["team_id", "raw_id"]), + ] + + constraints = [ + models.UniqueConstraint(fields=["team_id", "raw_id"], name="unique_raw_id_per_team"), + ]