1
1
from datetime import datetime
2
2
from typing import Any , Dict , List , Optional , Tuple
3
3
4
+ from rest_framework .exceptions import ParseError
4
5
from snuba_sdk import Column , Condition , Entity , Function , Op , Query , Request
5
6
7
+ from sentry import eventstore
6
8
from sentry .search .events .builder import QueryBuilder
7
9
from sentry .search .events .types import ParamsType
8
10
from sentry .snuba .dataset import Dataset , EntityKey
@@ -78,6 +80,7 @@ def get_span_intervals(
78
80
Condition (Column ("timestamp" ), Op .LT , params ["end" ]),
79
81
],
80
82
)
83
+
81
84
request = Request (
82
85
dataset = Dataset .SpansIndexed .value ,
83
86
app_id = "default" ,
@@ -87,17 +90,59 @@ def get_span_intervals(
87
90
"organization_id" : organization_id ,
88
91
},
89
92
)
90
- return raw_snql_query (
93
+ data = raw_snql_query (
91
94
request ,
92
95
referrer = Referrer .API_STARFISH_PROFILE_FLAMEGRAPH .value ,
93
96
)["data" ]
97
+ spans_interval = []
98
+ for row in data :
99
+ start_ns = (int (datetime .fromisoformat (row ["start_timestamp" ]).timestamp ()) * 10 ** 9 ) + (
100
+ row ["start_ms" ] * 10 ** 6
101
+ )
102
+ end_ns = (int (datetime .fromisoformat (row ["end_timestamp" ]).timestamp ()) * 10 ** 9 ) + (
103
+ row ["end_ms" ] * 10 ** 6
104
+ )
105
+ interval = {}
106
+ interval ["transaction_id" ] = row ["transaction_id" ]
107
+ interval ["start_ns" ] = str (start_ns )
108
+ interval ["end_ns" ] = str (end_ns )
109
+ spans_interval .append (interval )
110
+ return spans_interval
111
+
112
+
113
+ def get_span_intervals_from_nodestore (
114
+ project_id : str ,
115
+ span_group : str ,
116
+ transaction_ids : List [str ],
117
+ ) -> List [Dict [str , Any ]]:
118
+ spans_interval = []
119
+ for id in transaction_ids :
120
+ nodestore_event = eventstore .backend .get_event_by_id (project_id , id )
121
+ data = nodestore_event .data
122
+ for span in data .get ("spans" , []):
123
+ if span ["hash" ] == span_group :
124
+
125
+ start_sec , start_us = map (int , str (span ["start_timestamp" ]).split ("." ))
126
+ end_sec , end_us = map (int , str (span ["timestamp" ]).split ("." ))
127
+
128
+ start_ns = (start_sec * 10 ** 9 ) + (start_us * 10 ** 3 )
129
+ end_ns = (end_sec * 10 ** 9 ) + (end_us * 10 ** 3 )
130
+
131
+ interval = {}
132
+ interval ["transaction_id" ] = id
133
+ interval ["start_ns" ] = str (start_ns )
134
+ interval ["end_ns" ] = str (end_ns )
135
+
136
+ spans_interval .append (interval )
137
+ return spans_interval
94
138
95
139
96
140
def get_profile_ids_with_spans (
97
141
organization_id : str ,
98
142
project_id : str ,
99
143
params : ParamsType ,
100
144
span_group : str ,
145
+ backend : str ,
101
146
query : Optional [str ] = None ,
102
147
):
103
148
data = query_profiles_data (
@@ -115,24 +160,29 @@ def get_profile_ids_with_spans(
115
160
row ["id" ]: (row ["profile.id" ], []) for row in data
116
161
}
117
162
118
- data = get_span_intervals (
119
- project_id ,
120
- span_group ,
121
- list (transaction_to_prof .keys ()),
122
- organization_id ,
123
- params ,
124
- )
125
-
126
- for row in data :
127
- start_ns = (int (datetime .fromisoformat (row ["start_timestamp" ]).timestamp ()) * 10 ** 9 ) + (
128
- row ["start_ms" ] * 10 ** 6
163
+ if backend == "nodestore" :
164
+ data = get_span_intervals_from_nodestore (
165
+ project_id ,
166
+ span_group ,
167
+ list (transaction_to_prof .keys ()),
129
168
)
130
- end_ns = (int (datetime .fromisoformat (row ["end_timestamp" ]).timestamp ()) * 10 ** 9 ) + (
131
- row ["end_ms" ] * 10 ** 6
169
+ elif backend == "indexed_spans" :
170
+ data = get_span_intervals (
171
+ project_id ,
172
+ span_group ,
173
+ list (transaction_to_prof .keys ()),
174
+ organization_id ,
175
+ params ,
176
+ )
177
+ else :
178
+ raise ParseError (
179
+ detail = "Backend not supported: choose between 'indexed_spans' or 'nodestore'."
132
180
)
133
- transaction_id = row ["transaction_id" ]
134
181
135
- transaction_to_prof [transaction_id ][1 ].append ({"start" : str (start_ns ), "end" : str (end_ns )})
182
+ for row in data :
183
+ transaction_to_prof [row ["transaction_id" ]][1 ].append (
184
+ {"start" : row ["start_ns" ], "end" : row ["end_ns" ]}
185
+ )
136
186
137
187
profile_ids = [tup [0 ] for tup in transaction_to_prof .values ()]
138
188
spans = [tup [1 ] for tup in transaction_to_prof .values ()]
0 commit comments