Skip to content

Commit

Permalink
feat(apis): Pass query source to snuba - phase 2 (#73497)
Browse files Browse the repository at this point in the history
Continuing #73176 to pass query
source to snuba for more debuggability.

OrganizationSpansSamplesEndpoint
OrganizationsEventsMetaEndpoint
OrganizationsEventsStatsEndpoint

---------

Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
  • Loading branch information
sentaur-athena and getsantry[bot] committed Aug 1, 2024
1 parent 20efa11 commit 8732d8c
Show file tree
Hide file tree
Showing 17 changed files with 168 additions and 58 deletions.
10 changes: 10 additions & 0 deletions src/sentry/api/endpoints/organization_events_meta.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
from sentry.api.serializers import serialize
from sentry.api.serializers.models.group import GroupSerializer
from sentry.api.utils import handle_query_errors
from sentry.middleware import is_frontend_request
from sentry.snuba import spans_indexed, spans_metrics
from sentry.snuba.query_sources import QuerySource
from sentry.snuba.referrer import Referrer


Expand All @@ -39,6 +41,10 @@ def get(self, request: Request, organization) -> Response:
params=params,
query=request.query_params.get("query"),
referrer=Referrer.API_ORGANIZATION_EVENTS_META.value,
# TODO: @athena - add query_source when all datasets support it
# query_source=(
# QuerySource.FRONTEND if is_frontend_request(request) else QuerySource.API
# ),
)

return Response({"count": result["data"][0]["count"]})
Expand Down Expand Up @@ -118,6 +124,7 @@ class OrganizationSpansSamplesEndpoint(OrganizationEventsEndpointBase):
snuba_methods = ["GET"]

def get(self, request: Request, organization) -> Response:
is_frontend = is_frontend_request(request)
try:
params = self.get_snuba_params(request, organization)
except NoProjects:
Expand Down Expand Up @@ -148,6 +155,7 @@ def get(self, request: Request, organization) -> Response:
params=params,
query=request.query_params.get("query"),
referrer=Referrer.API_SPAN_SAMPLE_GET_BOUNDS.value,
query_source=(QuerySource.FRONTEND if is_frontend else QuerySource.API),
)
if len(bound_results["data"]) != 1:
raise ParseError("Could not find bounds")
Expand All @@ -169,6 +177,7 @@ def get(self, request: Request, organization) -> Response:
params=params,
query=request.query_params.get("query"),
referrer=Referrer.API_SPAN_SAMPLE_GET_SPAN_IDS.value,
query_source=(QuerySource.FRONTEND if is_frontend else QuerySource.API),
)
span_ids = []
for row in result["data"]:
Expand All @@ -192,5 +201,6 @@ def get(self, request: Request, organization) -> Response:
query=query,
limit=9,
referrer=Referrer.API_SPAN_SAMPLE_GET_SPAN_DATA.value,
query_source=(QuerySource.FRONTEND if is_frontend else QuerySource.API),
)
return Response({"data": result["data"]})
18 changes: 18 additions & 0 deletions src/sentry/api/endpoints/organization_events_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from sentry.api.base import region_silo_endpoint
from sentry.api.bases import OrganizationEventsV2EndpointBase
from sentry.constants import MAX_TOP_EVENTS
from sentry.middleware import is_frontend_request
from sentry.models.dashboard_widget import DashboardWidget, DashboardWidgetTypes
from sentry.models.organization import Organization
from sentry.snuba import (
Expand All @@ -25,6 +26,7 @@
transactions,
)
from sentry.snuba.metrics.extraction import MetricSpecType
from sentry.snuba.query_sources import QuerySource
from sentry.snuba.referrer import Referrer
from sentry.utils.snuba import SnubaError, SnubaTSResult

Expand Down Expand Up @@ -75,6 +77,9 @@
ALLOWED_EVENTS_STATS_REFERRERS: set[str] = {
Referrer.API_ALERTS_ALERT_RULE_CHART.value,
Referrer.API_ALERTS_CHARTCUTERIE.value,
Referrer.API_ENDPOINT_REGRESSION_ALERT_CHARTCUTERIE.value,
Referrer.API_FUNCTION_REGRESSION_ALERT_CHARTCUTERIE.value,
Referrer.DISCOVER_SLACK_UNFURL.value,
Referrer.API_DASHBOARDS_WIDGET_AREA_CHART.value,
Referrer.API_DASHBOARDS_WIDGET_BAR_CHART.value,
Referrer.API_DASHBOARDS_WIDGET_LINE_CHART.value,
Expand Down Expand Up @@ -108,6 +113,14 @@
}


SENTRY_BACKEND_REFERRERS = [
Referrer.API_ALERTS_CHARTCUTERIE.value,
Referrer.API_ENDPOINT_REGRESSION_ALERT_CHARTCUTERIE.value,
Referrer.API_FUNCTION_REGRESSION_ALERT_CHARTCUTERIE.value,
Referrer.DISCOVER_SLACK_UNFURL.value,
]


@region_silo_endpoint
class OrganizationEventsStatsEndpoint(OrganizationEventsV2EndpointBase):
publish_status = {
Expand Down Expand Up @@ -167,6 +180,7 @@ def check_if_results_have_data(self, results: SnubaTSResult | dict[str, SnubaTSR
return has_data

def get(self, request: Request, organization: Organization) -> Response:
query_source = QuerySource.FRONTEND if is_frontend_request(request) else QuerySource.API
with sentry_sdk.start_span(op="discover.endpoint", description="filter_params") as span:
span.set_data("organization", organization)

Expand Down Expand Up @@ -205,6 +219,8 @@ def get(self, request: Request, organization: Organization) -> Response:
if referrer in ALLOWED_EVENTS_STATS_REFERRERS.union(METRICS_ENHANCED_REFERRERS)
else Referrer.API_ORGANIZATION_EVENT_STATS.value
)
if referrer in SENTRY_BACKEND_REFERRERS:
query_source = QuerySource.SENTRY_BACKEND
batch_features = self.get_features(organization, request)
has_chart_interpolation = batch_features.get(
"organizations:performance-chart-interpolation", False
Expand Down Expand Up @@ -281,6 +297,7 @@ def _get_event_stats(
on_demand_metrics_enabled=use_on_demand_metrics,
on_demand_metrics_type=on_demand_metrics_type,
include_other=include_other,
query_source=query_source,
)

return scoped_dataset.timeseries_query(
Expand All @@ -306,6 +323,7 @@ def _get_event_stats(
)
),
on_demand_metrics_type=on_demand_metrics_type,
query_source=query_source,
)

def get_event_stats_factory(scoped_dataset):
Expand Down
2 changes: 2 additions & 0 deletions src/sentry/integrations/slack/unfurl/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from sentry.models.organization import Organization
from sentry.models.user import User
from sentry.search.events.filter import to_list
from sentry.snuba.referrer import Referrer
from sentry.utils.dates import (
get_interval_from_range,
parse_stats_period,
Expand Down Expand Up @@ -235,6 +236,7 @@ def unfurl_discover(
params.setlist("statsPeriod", [stats_period])

endpoint = "events-stats/"
params["referrer"] = Referrer.DISCOVER_SLACK_UNFURL.value

try:
resp = client.get(
Expand Down
7 changes: 5 additions & 2 deletions src/sentry/search/events/builder/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
)
from sentry.snuba.dataset import Dataset
from sentry.snuba.metrics.utils import MetricMeta
from sentry.snuba.query_sources import QuerySource
from sentry.users.services.user.service import user_service
from sentry.utils.dates import outside_retention_with_modified_start
from sentry.utils.env import in_test_environment
Expand Down Expand Up @@ -1509,10 +1510,12 @@ def handle_invalid_float(cls, value: float | None) -> float | None:
return None
return value

def run_query(self, referrer: str | None, use_cache: bool = False) -> Any:
def run_query(
self, referrer: str | None, use_cache: bool = False, query_source: QuerySource | None = None
) -> Any:
if not referrer:
InvalidSearchQuery("Query missing referrer.")
return raw_snql_query(self.get_snql_query(), referrer, use_cache)
return raw_snql_query(self.get_snql_query(), referrer, use_cache, query_source)

def process_results(self, results: Any) -> EventsResponse:
with sentry_sdk.start_span(op="QueryBuilder", description="process_results") as span:
Expand Down
14 changes: 10 additions & 4 deletions src/sentry/search/events/builder/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -1707,7 +1707,9 @@ def get_snql_query(self) -> list[Request]:

return queries

def run_query(self, referrer: str, use_cache: bool = False) -> Any:
def run_query(
self, referrer: str, use_cache: bool = False, query_source: QuerySource | None = None
) -> Any:
if self.use_metrics_layer or self.use_on_demand:
from sentry.snuba.metrics.datasource import get_series
from sentry.snuba.metrics.mqb_query_transformer import (
Expand Down Expand Up @@ -1755,7 +1757,7 @@ def run_query(self, referrer: str, use_cache: bool = False) -> Any:

queries = self.get_snql_query()
if queries:
results = bulk_snuba_queries(queries, referrer, use_cache)
results = bulk_snuba_queries(queries, referrer, use_cache, query_source=query_source)
else:
results = []

Expand Down Expand Up @@ -1965,7 +1967,9 @@ def resolve_top_event_conditions(

return final_condition

def run_query(self, referrer: str, use_cache: bool = False) -> Any:
def run_query(
self, referrer: str, use_cache: bool = False, query_source: QuerySource | None = None
) -> Any:
result = {}
results = []
meta_dict = {}
Expand Down Expand Up @@ -2033,7 +2037,9 @@ def run_query(self, referrer: str, use_cache: bool = False) -> Any:
else:
queries = self.get_snql_query()
if queries:
results = bulk_snuba_queries(queries, referrer, use_cache)
results = bulk_snuba_queries(
queries, referrer, use_cache, query_source=query_source
)

time_map: dict[str, dict[str, Any]] = defaultdict(dict)
for current_result in results:
Expand Down
14 changes: 11 additions & 3 deletions src/sentry/snuba/discover.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
)
from sentry.snuba.dataset import Dataset
from sentry.snuba.metrics.extraction import MetricSpecType
from sentry.snuba.query_sources import QuerySource
from sentry.tagstore.base import TOP_VALUES_DEFAULT_LIMIT
from sentry.utils.math import nice_int
from sentry.utils.snuba import (
Expand Down Expand Up @@ -205,6 +206,7 @@ def query(
on_demand_metrics_type: MetricSpecType | None = None,
dataset: Dataset = Dataset.Discover,
fallback_to_transactions: bool = False,
query_source: QuerySource | None = None,
) -> EventsResponse:
"""
High-level API for doing arbitrary user queries against events.
Expand Down Expand Up @@ -277,7 +279,9 @@ def query(
if extra_columns is not None:
builder.columns.extend(extra_columns)

result = builder.process_results(builder.run_query(referrer))
result = builder.process_results(
builder.run_query(referrer=referrer, query_source=query_source)
)
result["meta"]["tips"] = transform_tips(builder.tips)
return result

Expand All @@ -298,6 +302,7 @@ def timeseries_query(
on_demand_metrics_enabled: bool = False,
on_demand_metrics_type: MetricSpecType | None = None,
dataset: Dataset = Dataset.Discover,
query_source: QuerySource | None = None,
) -> SnubaTSResult:
"""
High-level API for doing arbitrary user timeseries queries against events.
Expand Down Expand Up @@ -369,7 +374,7 @@ def timeseries_query(
query_list.append(comparison_builder)

query_results = bulk_snuba_queries(
[query.get_snql_query() for query in query_list], referrer
[query.get_snql_query() for query in query_list], referrer, query_source=query_source
)

with sentry_sdk.start_span(op="discover.discover", description="timeseries.transform_results"):
Expand Down Expand Up @@ -470,6 +475,7 @@ def top_events_timeseries(
on_demand_metrics_enabled: bool = False,
on_demand_metrics_type: MetricSpecType | None = None,
dataset: Dataset = Dataset.Discover,
query_source: QuerySource | None = None,
) -> dict[str, SnubaTSResult] | SnubaTSResult:
"""
High-level API for doing arbitrary user timeseries queries for a limited number of top events
Expand Down Expand Up @@ -516,6 +522,7 @@ def top_events_timeseries(
include_equation_fields=True,
skip_tag_resolution=True,
dataset=dataset,
query_source=query_source,
)

top_events_builder = TopEventsQueryBuilder(
Expand Down Expand Up @@ -548,9 +555,10 @@ def top_events_timeseries(
result, other_result = bulk_snuba_queries(
[top_events_builder.get_snql_query(), other_events_builder.get_snql_query()],
referrer=referrer,
query_source=query_source,
)
else:
result = top_events_builder.run_query(referrer)
result = top_events_builder.run_query(referrer=referrer, query_source=query_source)
other_result = {"data": []}
if (
not allow_empty
Expand Down
10 changes: 8 additions & 2 deletions src/sentry/snuba/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from sentry.snuba.dataset import Dataset
from sentry.snuba.discover import OTHER_KEY, create_result_key, transform_tips, zerofill
from sentry.snuba.metrics.extraction import MetricSpecType
from sentry.snuba.query_sources import QuerySource
from sentry.utils.snuba import SnubaTSResult, bulk_snuba_queries

is_filter_translation = {}
Expand Down Expand Up @@ -55,6 +56,7 @@ def query(
on_demand_metrics_enabled=False,
on_demand_metrics_type: MetricSpecType | None = None,
fallback_to_transactions=False,
query_source: QuerySource | None = None,
) -> EventsResponse:
if not selected_columns:
raise InvalidSearchQuery("No columns selected")
Expand Down Expand Up @@ -84,7 +86,7 @@ def query(
)
if conditions is not None:
builder.add_conditions(conditions)
result = builder.process_results(builder.run_query(referrer))
result = builder.process_results(builder.run_query(referrer, query_source=query_source))
result["meta"]["tips"] = transform_tips(builder.tips)
return result

Expand All @@ -104,6 +106,7 @@ def timeseries_query(
use_metrics_layer=False,
on_demand_metrics_enabled=False,
on_demand_metrics_type: MetricSpecType | None = None,
query_source: QuerySource | None = None,
):

if len(params) == 0 and snuba_params is not None:
Expand Down Expand Up @@ -144,7 +147,7 @@ def timeseries_query(
query_list.append(comparison_builder)

query_results = bulk_snuba_queries(
[query.get_snql_query() for query in query_list], referrer
[query.get_snql_query() for query in query_list], referrer, query_source=query_source
)

with sentry_sdk.start_span(op="errors", description="timeseries.transform_results"):
Expand Down Expand Up @@ -216,6 +219,7 @@ def top_events_timeseries(
on_demand_metrics_enabled: bool = False,
on_demand_metrics_type: MetricSpecType | None = None,
dataset: Dataset = Dataset.Discover,
query_source: QuerySource | None = None,
) -> dict[str, SnubaTSResult] | SnubaTSResult:
"""
High-level API for doing arbitrary user timeseries queries for a limited number of top events
Expand Down Expand Up @@ -257,6 +261,7 @@ def top_events_timeseries(
use_aggregate_conditions=True,
include_equation_fields=True,
skip_tag_resolution=True,
query_source=query_source,
)

top_events_builder = ErrorsTopEventsQueryBuilder(
Expand Down Expand Up @@ -291,6 +296,7 @@ def top_events_timeseries(
result, other_result = bulk_snuba_queries(
[top_events_builder.get_snql_query(), other_events_builder.get_snql_query()],
referrer=referrer,
query_source=query_source,
)
else:
result = top_events_builder.run_query(referrer)
Expand Down
Loading

0 comments on commit 8732d8c

Please sign in to comment.