@@ -290,6 +290,64 @@ def load_data(
290290 return data
291291
292292
293+ def create_n_plus_one_issue (data ):
294+ timestamp = datetime .fromtimestamp (data ["start_timestamp" ])
295+ n_plus_one_db_duration = timedelta (milliseconds = 100 )
296+ n_plus_one_db_current_offset = timestamp
297+ parent_span_id = data ["spans" ][0 ]["parent_span_id" ]
298+ trace_id = data ["contexts" ]["trace" ]["trace_id" ]
299+ data ["spans" ].append (
300+ {
301+ "timestamp" : (timestamp + n_plus_one_db_duration ).timestamp (),
302+ "start_timestamp" : (timestamp + timedelta (milliseconds = 10 )).timestamp (),
303+ "description" : "SELECT `books_book`.`id`, `books_book`.`title`, `books_book`.`author_id` FROM `books_book` ORDER BY `books_book`.`id` DESC LIMIT 10" ,
304+ "op" : "db" ,
305+ "parent_span_id" : parent_span_id ,
306+ "span_id" : uuid4 ().hex [:16 ],
307+ "hash" : "858fea692d4d93e8" ,
308+ "trace_id" : trace_id ,
309+ }
310+ )
311+ for i in range (200 ):
312+ n_plus_one_db_duration += timedelta (milliseconds = 200 ) + timedelta (milliseconds = 1 )
313+ n_plus_one_db_current_offset = timestamp + n_plus_one_db_duration
314+ data ["spans" ].append (
315+ {
316+ "timestamp" : (
317+ n_plus_one_db_current_offset + timedelta (milliseconds = 200 )
318+ ).timestamp (),
319+ "start_timestamp" : (
320+ n_plus_one_db_current_offset + timedelta (milliseconds = 1 )
321+ ).timestamp (),
322+ "description" : "SELECT `books_author`.`id`, `books_author`.`name` FROM `books_author` WHERE `books_author`.`id` = %s LIMIT 21" ,
323+ "op" : "db" ,
324+ "span_id" : uuid4 ().hex [:16 ],
325+ "parent_span_id" : parent_span_id ,
326+ "hash" : "63f1e89e6a073441" ,
327+ "trace_id" : trace_id ,
328+ }
329+ )
330+ data ["spans" ].append (
331+ {
332+ "timestamp" : (
333+ timestamp + n_plus_one_db_duration + timedelta (milliseconds = 200 )
334+ ).timestamp (),
335+ "start_timestamp" : timestamp .timestamp (),
336+ "description" : "new" ,
337+ "op" : "django.view" ,
338+ "parent_span_id" : uuid4 ().hex [:16 ],
339+ "span_id" : parent_span_id ,
340+ "hash" : "0f43fb6f6e01ca52" ,
341+ "trace_id" : trace_id ,
342+ }
343+ )
344+
345+
346+ PERFORMANCE_ISSUE_CREATORS = {
347+ "n+1" : create_n_plus_one_issue ,
348+ }
349+
350+
293351def create_sample_event (
294352 project ,
295353 platform = None ,
@@ -302,6 +360,7 @@ def create_sample_event(
302360 span_id = None ,
303361 spans = None ,
304362 tagged = False ,
363+ performance_issues = None ,
305364 ** kwargs ,
306365):
307366 if not platform and not default :
@@ -323,6 +382,10 @@ def create_sample_event(
323382 for key in ["parent_span_id" , "hash" , "exclusive_time" ]:
324383 if key in kwargs :
325384 data ["contexts" ]["trace" ][key ] = kwargs .pop (key )
385+ if performance_issues :
386+ for issue in performance_issues :
387+ if issue in PERFORMANCE_ISSUE_CREATORS :
388+ PERFORMANCE_ISSUE_CREATORS [issue ](data )
326389
327390 data .update (kwargs )
328391 return create_sample_event_basic (data , project .id , raw = raw , tagged = tagged )
@@ -413,6 +476,7 @@ def create_trace(slow, start_timestamp, timestamp, user, trace_id, parent_span_i
413476 trace = trace_id ,
414477 spans = spans ,
415478 hash = hash_values ([data ["transaction" ]]),
479+ performance_issues = data .get ("performance_issues" ),
416480 # not the best but just set the exclusive time
417481 # equal to the duration to get some span data
418482 exclusive_time = (timestamp - start_timestamp ).total_seconds (),
0 commit comments