|
@@ -32,7 +32,7 @@ from sentry.models import Organization
|
|
|
from sentry.search.events.builder import QueryBuilder
|
|
|
from sentry.snuba import discover
|
|
|
from sentry.utils.numbers import format_grouped_length
|
|
|
-from sentry.utils.snuba import Dataset, SnubaQueryParams, bulk_raw_query, bulk_snql_query
|
|
|
+from sentry.utils.snuba import Dataset, bulk_snql_query
|
|
|
from sentry.utils.validators import INVALID_ID_DETAILS, is_event_id
|
|
|
|
|
|
logger: logging.Logger = logging.getLogger(__name__)
|
|
@@ -206,67 +206,14 @@ def child_sort_key(item: TraceEvent) -> List[int]:
|
|
|
|
|
|
|
|
|
def query_trace_data(
|
|
|
- trace_id: str, params: Mapping[str, str], use_snql: bool = False
|
|
|
+ trace_id: str, params: Mapping[str, str]
|
|
|
) -> Tuple[Sequence[SnubaTransaction], Sequence[SnubaError]]:
|
|
|
- sentry_sdk.set_tag("discover.use_snql", use_snql)
|
|
|
transaction_query: Union[QueryBuilder, discover.PreparedQuery]
|
|
|
error_query: Union[QueryBuilder, discover.PreparedQuery]
|
|
|
- if use_snql:
|
|
|
- transaction_query = QueryBuilder(
|
|
|
- Dataset.Transactions,
|
|
|
- params,
|
|
|
- query=f"trace:{trace_id}",
|
|
|
- selected_columns=[
|
|
|
- "id",
|
|
|
- "transaction.status",
|
|
|
- "transaction.op",
|
|
|
- "transaction.duration",
|
|
|
- "transaction",
|
|
|
- "timestamp",
|
|
|
- "project",
|
|
|
- "project.id",
|
|
|
- "trace.span",
|
|
|
- "trace.parent_span",
|
|
|
- 'to_other(trace.parent_span, "", 0, 1) AS root',
|
|
|
- ],
|
|
|
- # We want to guarantee at least getting the root, and hopefully events near it with timestamp
|
|
|
- # id is just for consistent results
|
|
|
- orderby=["-root", "timestamp", "id"],
|
|
|
- limit=MAX_TRACE_SIZE,
|
|
|
- )
|
|
|
- error_query = QueryBuilder(
|
|
|
- Dataset.Events,
|
|
|
- params,
|
|
|
- query=f"trace:{trace_id}",
|
|
|
- selected_columns=[
|
|
|
- "id",
|
|
|
- "project",
|
|
|
- "project.id",
|
|
|
- "timestamp",
|
|
|
- "trace.span",
|
|
|
- "transaction",
|
|
|
- "issue",
|
|
|
- "title",
|
|
|
- "tags[level]",
|
|
|
- ],
|
|
|
- # Don't add timestamp to this orderby as snuba will have to split the time range up and make multiple queries
|
|
|
- orderby=["id"],
|
|
|
- auto_fields=False,
|
|
|
- limit=MAX_TRACE_SIZE,
|
|
|
- )
|
|
|
- results = bulk_snql_query(
|
|
|
- [transaction_query.get_snql_query(), error_query.get_snql_query()],
|
|
|
- referrer="api.trace-view.get-events.wip-snql",
|
|
|
- )
|
|
|
- transformed_results = [
|
|
|
- discover.transform_results(result, query.function_alias_map, {}, None)["data"]
|
|
|
- for result, query in zip(results, [transaction_query, error_query])
|
|
|
- ]
|
|
|
- return cast(Sequence[SnubaTransaction], transformed_results[0]), cast(
|
|
|
- Sequence[SnubaError], transformed_results[1]
|
|
|
- )
|
|
|
-
|
|
|
- transaction_query = discover.prepare_discover_query(
|
|
|
+ transaction_query = QueryBuilder(
|
|
|
+ Dataset.Transactions,
|
|
|
+ params,
|
|
|
+ query=f"trace:{trace_id}",
|
|
|
selected_columns=[
|
|
|
"id",
|
|
|
"transaction.status",
|
|
@@ -274,8 +221,8 @@ def query_trace_data(
|
|
|
"transaction.duration",
|
|
|
"transaction",
|
|
|
"timestamp",
|
|
|
- # project gets the slug, and project.id gets added automatically
|
|
|
"project",
|
|
|
+ "project.id",
|
|
|
"trace.span",
|
|
|
"trace.parent_span",
|
|
|
'to_other(trace.parent_span, "", 0, 1) AS root',
|
|
@@ -283,13 +230,16 @@ def query_trace_data(
|
|
|
# We want to guarantee at least getting the root, and hopefully events near it with timestamp
|
|
|
# id is just for consistent results
|
|
|
orderby=["-root", "timestamp", "id"],
|
|
|
- params=params,
|
|
|
- query=f"event.type:transaction trace:{trace_id}",
|
|
|
+ limit=MAX_TRACE_SIZE,
|
|
|
)
|
|
|
- error_query = discover.prepare_discover_query(
|
|
|
+ error_query = QueryBuilder(
|
|
|
+ Dataset.Events,
|
|
|
+ params,
|
|
|
+ query=f"trace:{trace_id}",
|
|
|
selected_columns=[
|
|
|
"id",
|
|
|
"project",
|
|
|
+ "project.id",
|
|
|
"timestamp",
|
|
|
"trace.span",
|
|
|
"transaction",
|
|
@@ -299,34 +249,15 @@ def query_trace_data(
|
|
|
],
|
|
|
# Don't add timestamp to this orderby as snuba will have to split the time range up and make multiple queries
|
|
|
orderby=["id"],
|
|
|
- params=params,
|
|
|
- query=f"!event.type:transaction trace:{trace_id}",
|
|
|
auto_fields=False,
|
|
|
+ limit=MAX_TRACE_SIZE,
|
|
|
)
|
|
|
- snuba_params = [
|
|
|
- SnubaQueryParams(
|
|
|
- dataset=Dataset.Discover,
|
|
|
- start=snuba_filter.start,
|
|
|
- end=snuba_filter.end,
|
|
|
- groupby=snuba_filter.groupby,
|
|
|
- conditions=snuba_filter.conditions,
|
|
|
- filter_keys=snuba_filter.filter_keys,
|
|
|
- aggregations=snuba_filter.aggregations,
|
|
|
- selected_columns=snuba_filter.selected_columns,
|
|
|
- having=snuba_filter.having,
|
|
|
- orderby=snuba_filter.orderby,
|
|
|
- limit=MAX_TRACE_SIZE,
|
|
|
- )
|
|
|
- for snuba_filter in [transaction_query.filter, error_query.filter]
|
|
|
- ]
|
|
|
- results = bulk_raw_query(
|
|
|
- snuba_params,
|
|
|
+ results = bulk_snql_query(
|
|
|
+ [transaction_query.get_snql_query(), error_query.get_snql_query()],
|
|
|
referrer="api.trace-view.get-events",
|
|
|
)
|
|
|
transformed_results = [
|
|
|
- discover.transform_results(result, query.fields["functions"], query.columns, query.filter)[
|
|
|
- "data"
|
|
|
- ]
|
|
|
+ discover.transform_results(result, query.function_alias_map, {}, None)["data"]
|
|
|
for result, query in zip(results, [transaction_query, error_query])
|
|
|
]
|
|
|
return cast(Sequence[SnubaTransaction], transformed_results[0]), cast(
|
|
@@ -340,11 +271,6 @@ class OrganizationEventsTraceEndpointBase(OrganizationEventsV2EndpointBase): #
|
|
|
features.has("organizations:performance-view", organization, actor=request.user)
|
|
|
)
|
|
|
|
|
|
- def has_snql_feature(self, organization: Organization, request: HttpRequest) -> bool:
|
|
|
- return bool(
|
|
|
- features.has("organizations:performance-use-snql", organization, actor=request.user)
|
|
|
- )
|
|
|
-
|
|
|
@staticmethod
|
|
|
def serialize_error(event: SnubaError) -> TraceError:
|
|
|
return {
|
|
@@ -421,9 +347,7 @@ class OrganizationEventsTraceEndpointBase(OrganizationEventsV2EndpointBase): #
|
|
|
return Response({"detail": INVALID_ID_DETAILS.format("Event ID")}, status=400)
|
|
|
|
|
|
with self.handle_query_errors():
|
|
|
- transactions, errors = query_trace_data(
|
|
|
- trace_id, params, self.has_snql_feature(organization, request)
|
|
|
- )
|
|
|
+ transactions, errors = query_trace_data(trace_id, params)
|
|
|
if len(transactions) == 0:
|
|
|
return Response(status=404)
|
|
|
self.record_analytics(transactions, trace_id, self.request.user.id, organization.id)
|
|
@@ -774,7 +698,6 @@ class OrganizationEventsTraceMetaEndpoint(OrganizationEventsTraceEndpointBase):
|
|
|
query=f"trace:{trace_id}",
|
|
|
limit=1,
|
|
|
referrer="api.trace-view.get-meta",
|
|
|
- use_snql=self.has_snql_feature(organization, request),
|
|
|
)
|
|
|
if len(result["data"]) == 0:
|
|
|
return Response(status=404)
|