mock-traces 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. #!/usr/bin/env python
  2. from sentry.runner import configure
  3. configure()
  4. from datetime import timedelta
  5. from uuid import uuid4
  6. from django.conf import settings
  7. from django.db.models import F
  8. from django.utils import timezone
  9. from sentry.models import Organization, Project
  10. from sentry.utils.samples import create_trace, generate_user, random_normal
  11. def main(slow=False):
  12. project_names = {"Ludic Science", "Earth", "Fire", "Wind", "Water", "Heart"}
  13. project_map = {}
  14. if settings.SENTRY_SINGLE_ORGANIZATION:
  15. org = Organization.get_default()
  16. print(f"Mocking org {org.name}") # NOQA
  17. else:
  18. print("Mocking org {}".format("Default")) # NOQA
  19. org, _ = Organization.objects.get_or_create(slug="default")
  20. for project_name in project_names:
  21. print(f" > Mocking project {project_name}") # NOQA
  22. project, _ = Project.objects.get_or_create(
  23. name=project_name,
  24. defaults={
  25. "organization": org,
  26. "first_event": timezone.now(),
  27. "flags": Project.flags.has_releases,
  28. },
  29. )
  30. project_map[project_name] = project
  31. if not project.first_event:
  32. project.update(first_event=project.date_added)
  33. if not project.flags.has_releases:
  34. project.update(flags=F("flags").bitor(Project.flags.has_releases))
  35. if not project.flags.has_transactions:
  36. project.update(flags=F("flags").bitor(Project.flags.has_transactions))
  37. frontend_project = project_map["Fire"]
  38. backend_project = project_map["Earth"]
  39. service_projects = [
  40. project_map["Wind"],
  41. project_map["Water"],
  42. project_map["Heart"],
  43. ]
  44. timestamp = timezone.now()
  45. print(f" > Loading normal trace") # NOQA
  46. # Normal trace
  47. create_trace(
  48. slow,
  49. timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)),
  50. timestamp,
  51. generate_user(),
  52. uuid4().hex,
  53. None,
  54. {
  55. "project": frontend_project,
  56. "transaction": "/plants/:plantId/",
  57. "frontend": True,
  58. "errors": 1,
  59. "children": [
  60. {
  61. "project": backend_project,
  62. "transaction": "/api/plants/",
  63. "children": [
  64. {
  65. "project": service_projects[0],
  66. "transaction": "/products/all/",
  67. "children": [],
  68. },
  69. {
  70. "project": service_projects[1],
  71. "transaction": "/analytics/",
  72. "children": [],
  73. },
  74. {
  75. "project": service_projects[2],
  76. "transaction": "tasks.create_invoice",
  77. "children": [],
  78. },
  79. ],
  80. },
  81. ],
  82. },
  83. )
  84. print(f" > Loading orphan data") # NOQA
  85. # Trace only with orphans
  86. create_trace(
  87. slow,
  88. timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)),
  89. timestamp,
  90. generate_user(),
  91. uuid4().hex,
  92. uuid4().hex[:16],
  93. {
  94. "project": frontend_project,
  95. "transaction": "/orphans/:orphanId/",
  96. "frontend": True,
  97. "children": [
  98. {
  99. "project": backend_project,
  100. "transaction": "/api/orphans/",
  101. "errors": 1,
  102. "children": [
  103. {
  104. "project": service_projects[0],
  105. "transaction": "/orphans/all/",
  106. "errors": 1,
  107. "children": [],
  108. },
  109. {
  110. "project": service_projects[1],
  111. "transaction": "/orphan/analytics/",
  112. "children": [],
  113. },
  114. {
  115. "project": service_projects[2],
  116. "transaction": "tasks.invoice_orphans",
  117. "errors": 1,
  118. "children": [],
  119. },
  120. ],
  121. },
  122. ],
  123. },
  124. )
  125. print(f" > Loading trace with many siblings") # NOQA
  126. create_trace(
  127. slow,
  128. timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)),
  129. timestamp,
  130. generate_user(),
  131. uuid4().hex,
  132. None,
  133. {
  134. "project": frontend_project,
  135. "transaction": "/siblings/:count/",
  136. "frontend": True,
  137. "children": [
  138. {
  139. "project": backend_project,
  140. "transaction": f"/api/sibling_{i}/",
  141. "children": [],
  142. }
  143. for i in range(15)
  144. ],
  145. },
  146. )
  147. print(f" > Loading trace with many roots") # NOQA
  148. trace_id = uuid4().hex
  149. for _ in range(15):
  150. create_trace(
  151. slow,
  152. timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)),
  153. timestamp,
  154. generate_user(),
  155. trace_id,
  156. None,
  157. {
  158. "project": frontend_project,
  159. "transaction": "/multiple-root/:root/",
  160. "frontend": True,
  161. "children": [
  162. {
  163. "project": backend_project,
  164. "transaction": "/multiple-root/child/",
  165. "children": [],
  166. }
  167. ],
  168. },
  169. )
  170. print(f" > Loading chained trace with orphans") # NOQA
  171. trace_id = uuid4().hex
  172. create_trace(
  173. slow,
  174. timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)),
  175. timestamp,
  176. generate_user(),
  177. trace_id,
  178. None,
  179. {
  180. "project": frontend_project,
  181. "transaction": "/chained/:login/",
  182. "frontend": True,
  183. "children": [
  184. {
  185. "project": backend_project,
  186. "transaction": "/api/auth/",
  187. "children": [
  188. {
  189. "project": service_projects[0],
  190. "transaction": "/auth/check-login/",
  191. "errors": 1,
  192. "children": [
  193. {
  194. "project": service_projects[1],
  195. "transaction": "/analytics/",
  196. "errors": 1,
  197. "children": [
  198. {
  199. "project": service_projects[2],
  200. "transaction": "tasks.check_login",
  201. "errors": 1,
  202. "children": [],
  203. }
  204. ],
  205. }
  206. ],
  207. },
  208. ],
  209. },
  210. ],
  211. },
  212. )
  213. create_trace(
  214. slow,
  215. timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)),
  216. timestamp,
  217. generate_user(),
  218. trace_id,
  219. uuid4().hex[:16],
  220. {
  221. "project": frontend_project,
  222. "transaction": "/orphans/:orphanId/",
  223. "frontend": True,
  224. "children": [
  225. {
  226. "project": backend_project,
  227. "transaction": "/api/orphans/",
  228. "errors": 1,
  229. "children": [],
  230. }
  231. ],
  232. },
  233. )
  234. print(f" > Loading traces missing instrumentation") # NOQA
  235. create_trace(
  236. slow,
  237. timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)),
  238. timestamp,
  239. generate_user(),
  240. uuid4().hex,
  241. None,
  242. {
  243. "project": frontend_project,
  244. "transaction": "/missing/:frontend/",
  245. "frontend": True,
  246. "children": [],
  247. },
  248. )
  249. create_trace(
  250. slow,
  251. timestamp - timedelta(milliseconds=random_normal(4000, 250, 1000)),
  252. timestamp,
  253. generate_user(),
  254. uuid4().hex,
  255. None,
  256. {
  257. "project": backend_project,
  258. "transaction": "/missing/backend",
  259. "children": [],
  260. },
  261. )
  262. if __name__ == "__main__":
  263. settings.CELERY_ALWAYS_EAGER = True
  264. from optparse import OptionParser
  265. parser = OptionParser()
  266. parser.add_option(
  267. "--slow",
  268. default=False,
  269. action="store_true",
  270. help="sleep between each transaction to let clickhouse rest",
  271. )
  272. (options, args) = parser.parse_args()
  273. try:
  274. main(
  275. slow=options.slow,
  276. )
  277. except Exception:
  278. # Avoid reporting any issues recursively back into Sentry
  279. import sys
  280. import traceback
  281. traceback.print_exc()
  282. sys.exit(1)