Skip to content

Commit

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

OrganizationEventsTraceBaseEndpoint
OrganizationsEventsNewTrendsStatsEndpoint
OrganizationsEventsEndpoint
  • Loading branch information
sentaur-athena committed Aug 15, 2024
1 parent 616ef95 commit f24f9d5
Show file tree
Hide file tree
Showing 14 changed files with 135 additions and 30 deletions.
19 changes: 16 additions & 3 deletions src/sentry/api/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@
from sentry.apidocs.hooks import HTTP_METHOD_NAME
from sentry.auth import access
from sentry.auth.staff import has_staff_option
from sentry.middleware import is_frontend_request
from sentry.models.environment import Environment
from sentry.organizations.absolute_url import generate_organization_url
from sentry.ratelimits.config import DEFAULT_RATE_LIMIT_CONFIG, RateLimitConfig
from sentry.silo.base import SiloLimit, SiloMode
from sentry.snuba.query_sources import QuerySource
from sentry.types.ratelimit import RateLimit, RateLimitCategory
from sentry.utils.audit import create_audit_entry
from sentry.utils.cursors import Cursor
Expand Down Expand Up @@ -221,9 +223,11 @@ class Endpoint(APIView):

owner: ApiOwner = ApiOwner.UNOWNED
publish_status: dict[HTTP_METHOD_NAME, ApiPublishStatus] = {}
rate_limits: RateLimitConfig | dict[str, dict[RateLimitCategory, RateLimit]] | Callable[
..., RateLimitConfig | dict[str, dict[RateLimitCategory, RateLimit]]
] = DEFAULT_RATE_LIMIT_CONFIG
rate_limits: (
RateLimitConfig
| dict[str, dict[RateLimitCategory, RateLimit]]
| Callable[..., RateLimitConfig | dict[str, dict[RateLimitCategory, RateLimit]]]
) = DEFAULT_RATE_LIMIT_CONFIG
enforce_rate_limit: bool = settings.SENTRY_RATELIMITER_ENABLED
snuba_methods: list[HTTP_METHOD_NAME] = []

Expand Down Expand Up @@ -582,6 +586,15 @@ def paginate(
self.add_cursor_headers(request, response, cursor_result)
return response

def get_request_source(self, request: Request) -> QuerySource:
"""
This is an estimate of query source. Treat it more like a good guess and
don't write logic that depends on it. Used for monitoring only atm.
"""
if is_frontend_request(request):
return QuerySource.FRONTEND
return QuerySource.API


class EnvironmentMixin:
def _get_environment_func(self, request: Request, organization_id):
Expand Down
2 changes: 2 additions & 0 deletions src/sentry/api/endpoints/organization_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,7 @@ def get(self, request: Request, organization) -> Response:
referrer = Referrer.API_ORGANIZATION_EVENTS.value

def _data_fn(scoped_dataset, offset, limit, query) -> dict[str, Any]:
query_source = self.get_request_source(request)
return scoped_dataset.query(
selected_columns=self.get_field_list(organization, request),
query=query,
Expand All @@ -415,6 +416,7 @@ def _data_fn(scoped_dataset, offset, limit, query) -> dict[str, Any]:
use_metrics_layer=batch_features.get("organizations:use-metrics-layer", False),
on_demand_metrics_enabled=on_demand_metrics_enabled,
on_demand_metrics_type=on_demand_metrics_type,
query_source=query_source,
)

@sentry_sdk.tracing.trace
Expand Down
3 changes: 1 addition & 2 deletions src/sentry/api/endpoints/organization_events_stats.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
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.search.events.types import SnubaParams
Expand Down Expand Up @@ -182,7 +181,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
query_source = self.get_request_source(request)
with sentry_sdk.start_span(op="discover.endpoint", description="filter_params") as span:
span.set_data("organization", organization)

Expand Down
Loading

0 comments on commit f24f9d5

Please sign in to comment.