#!/usr/bin/env python from sentry.runner import configure configure() from datetime import timedelta from uuid import uuid4 from django.conf import settings from django.db.models import F from django.utils import timezone from sentry.models import Organization, Project from sentry.utils.samples import create_trace, generate_user, random_normal def main(slow=False): project_names = {"Ludic Science", "Earth", "Fire", "Wind", "Water", "Heart"} project_map = {} if settings.SENTRY_SINGLE_ORGANIZATION: org = Organization.get_default() print(f"Mocking org {org.name}") # NOQA else: print("Mocking org {}".format("Default")) # NOQA org, _ = Organization.objects.get_or_create(slug="default") for project_name in project_names: print(f" > Mocking project {project_name}") # NOQA project, _ = Project.objects.get_or_create( name=project_name, defaults={ "organization": org, "first_event": timezone.now(), "flags": Project.flags.has_releases, }, ) project_map[project_name] = project if not project.first_event: project.update(first_event=project.date_added) if not project.flags.has_releases: project.update(flags=F("flags").bitor(Project.flags.has_releases)) if not project.flags.has_transactions: project.update(flags=F("flags").bitor(Project.flags.has_transactions)) frontend_project = project_map["Fire"] backend_project = project_map["Earth"] service_projects = [ project_map["Wind"], project_map["Water"], project_map["Heart"], ] timestamp = timezone.now() print(f" > Loading normal trace") # NOQA # Normal trace create_trace( slow, timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)), timestamp, generate_user(), uuid4().hex, None, { "project": frontend_project, "transaction": "/plants/:plantId/", "frontend": True, "errors": 1, "children": [ { "project": backend_project, "transaction": "/api/plants/", "children": [ { "project": service_projects[0], "transaction": "/products/all/", "children": [], }, { "project": service_projects[1], "transaction": "/analytics/", "children": [], }, { "project": service_projects[2], "transaction": "tasks.create_invoice", "children": [], }, ], }, ], }, ) print(f" > Loading normal trace, but with performance issue") # NOQA # Normal trace create_trace( slow, timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)), timestamp, generate_user(), uuid4().hex, None, { "project": frontend_project, "transaction": "/plants/:plantId/", "frontend": True, "errors": 1, "children": [ { "project": backend_project, "transaction": "/api/plants/", "performance_issues": ["n+1"], "children": [ { "project": service_projects[0], "transaction": "/products/all/", "children": [], }, { "project": service_projects[1], "transaction": "/analytics/", "children": [], }, { "project": service_projects[2], "transaction": "tasks.create_invoice", "children": [], }, ], }, ], }, ) print(f" > Loading orphan data") # NOQA # Trace only with orphans create_trace( slow, timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)), timestamp, generate_user(), uuid4().hex, uuid4().hex[:16], { "project": frontend_project, "transaction": "/orphans/:orphanId/", "frontend": True, "children": [ { "project": backend_project, "transaction": "/api/orphans/", "errors": 1, "children": [ { "project": service_projects[0], "transaction": "/orphans/all/", "errors": 1, "children": [], }, { "project": service_projects[1], "transaction": "/orphan/analytics/", "children": [], }, { "project": service_projects[2], "transaction": "tasks.invoice_orphans", "errors": 1, "children": [], }, ], }, ], }, ) print(f" > Loading trace with many siblings") # NOQA create_trace( slow, timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)), timestamp, generate_user(), uuid4().hex, None, { "project": frontend_project, "transaction": "/siblings/:count/", "frontend": True, "children": [ { "project": backend_project, "transaction": f"/api/sibling_{i}/", "children": [], } for i in range(15) ], }, ) print(f" > Loading trace with many roots") # NOQA trace_id = uuid4().hex for _ in range(15): create_trace( slow, timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)), timestamp, generate_user(), trace_id, None, { "project": frontend_project, "transaction": "/multiple-root/:root/", "frontend": True, "children": [ { "project": backend_project, "transaction": "/multiple-root/child/", "children": [], } ], }, ) print(f" > Loading chained trace with orphans") # NOQA trace_id = uuid4().hex create_trace( slow, timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)), timestamp, generate_user(), trace_id, None, { "project": frontend_project, "transaction": "/chained/:login/", "frontend": True, "children": [ { "project": backend_project, "transaction": "/api/auth/", "children": [ { "project": service_projects[0], "transaction": "/auth/check-login/", "errors": 1, "children": [ { "project": service_projects[1], "transaction": "/analytics/", "errors": 1, "children": [ { "project": service_projects[2], "transaction": "tasks.check_login", "errors": 1, "children": [], } ], } ], }, ], }, ], }, ) create_trace( slow, timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)), timestamp, generate_user(), trace_id, uuid4().hex[:16], { "project": frontend_project, "transaction": "/orphans/:orphanId/", "frontend": True, "children": [ { "project": backend_project, "transaction": "/api/orphans/", "errors": 1, "children": [], } ], }, ) print(f" > Loading traces missing instrumentation") # NOQA create_trace( slow, timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)), timestamp, generate_user(), uuid4().hex, None, { "project": frontend_project, "transaction": "/missing/:frontend/", "frontend": True, "children": [], }, ) create_trace( slow, timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)), timestamp, generate_user(), uuid4().hex, None, { "project": backend_project, "transaction": "/missing/backend", "children": [], }, ) if __name__ == "__main__": settings.CELERY_ALWAYS_EAGER = True from optparse import OptionParser parser = OptionParser() parser.add_option( "--slow", default=False, action="store_true", help="sleep between each transaction to let clickhouse rest", ) (options, args) = parser.parse_args() try: main( slow=options.slow, ) except Exception: # Avoid reporting any issues recursively back into Sentry import sys import traceback traceback.print_exc() sys.exit(1)