Skip to content

Commit 3115f58

Browse files
authored
feat(eap): Return bytes scanned for eap queries (#102075)
This returns bytes scanned for all eap queries.
1 parent 9acaf68 commit 3115f58

File tree

9 files changed

+42
-25
lines changed

9 files changed

+42
-25
lines changed

src/sentry/api/bases/organization_events.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,7 @@ def handle_results_with_meta(
370370
isMetricsExtractedData = meta.pop("isMetricsExtractedData", False)
371371
discoverSplitDecision = meta.pop("discoverSplitDecision", None)
372372
full_scan = meta.pop("full_scan", None)
373+
bytes_scanned = meta.pop("bytes_scanned", None)
373374
debug_info = meta.pop("debug_info", None)
374375
fields, units = self.handle_unit_meta(fields_meta)
375376
meta = {
@@ -392,6 +393,9 @@ def handle_results_with_meta(
392393
# If this key isn't in meta there wasn't any sampling and we can assume all the data was scanned
393394
meta["dataScanned"] = "full"
394395

396+
if bytes_scanned is not None:
397+
meta["bytesScanned"] = bytes_scanned
398+
395399
# Only appears in meta when debug is passed to the endpoint
396400
if debug_info:
397401
meta["debug_info"] = debug_info

src/sentry/search/eap/sampling.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@
22
DownsampledStorageConfig,
33
DownsampledStorageMeta,
44
)
5+
from sentry_protos.snuba.v1.request_common_pb2 import ResponseMeta
56

67
from sentry.exceptions import InvalidSearchQuery
78
from sentry.search.eap.constants import SAMPLING_MODE_MAP
8-
from sentry.search.events.types import SAMPLING_MODES
9+
from sentry.search.events.types import SAMPLING_MODES, EventsMeta
910

1011

1112
def handle_downsample_meta(meta: DownsampledStorageMeta) -> bool:
@@ -19,3 +20,13 @@ def validate_sampling(sampling_mode: SAMPLING_MODES | None) -> DownsampledStorag
1920
raise InvalidSearchQuery(f"sampling mode: {sampling_mode} is not supported")
2021
else:
2122
return DownsampledStorageConfig(mode=SAMPLING_MODE_MAP[sampling_mode])
23+
24+
25+
def events_meta_from_rpc_request_meta(meta: ResponseMeta) -> EventsMeta:
26+
return EventsMeta(
27+
fields={},
28+
full_scan=handle_downsample_meta(meta.downsampled_storage_meta),
29+
bytes_scanned=(
30+
sum(info.stats.progress_bytes for info in meta.query_info) if meta.query_info else None
31+
),
32+
)

src/sentry/search/events/types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class EventsMeta(TypedDict):
7474
# only returned when debug=True
7575
debug_info: NotRequired[dict[str, Any]]
7676
full_scan: NotRequired[bool]
77+
bytes_scanned: NotRequired[int | None]
7778

7879

7980
class EventsResponse(TypedDict):

src/sentry/snuba/ourlogs.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from sentry.search.eap import constants
88
from sentry.search.eap.ourlogs.definitions import OURLOG_DEFINITIONS
99
from sentry.search.eap.resolver import SearchResolver
10-
from sentry.search.eap.sampling import handle_downsample_meta
10+
from sentry.search.eap.sampling import events_meta_from_rpc_request_meta
1111
from sentry.search.eap.types import AdditionalQueries, EAPResponse, SearchResolverConfig
1212
from sentry.search.events.types import SAMPLING_MODES, EventsMeta, SnubaParams
1313
from sentry.snuba import rpc_dataset_common
@@ -112,10 +112,7 @@ def run_timeseries_query(
112112

113113
"""Process the results"""
114114
result = rpc_dataset_common.ProcessedTimeseries()
115-
final_meta: EventsMeta = EventsMeta(
116-
fields={},
117-
full_scan=handle_downsample_meta(rpc_response.meta.downsampled_storage_meta),
118-
)
115+
final_meta: EventsMeta = events_meta_from_rpc_request_meta(rpc_response.meta)
119116
for resolved_field in aggregates + groupbys:
120117
final_meta["fields"][resolved_field.public_alias] = resolved_field.search_type
121118

src/sentry/snuba/rpc_dataset_common.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
)
4848
from sentry.search.eap.constants import DOUBLE, MAX_ROLLUP_POINTS, VALID_GRANULARITIES
4949
from sentry.search.eap.resolver import SearchResolver
50-
from sentry.search.eap.sampling import handle_downsample_meta
50+
from sentry.search.eap.sampling import events_meta_from_rpc_request_meta
5151
from sentry.search.eap.types import (
5252
CONFIDENCES,
5353
AdditionalQueries,
@@ -364,10 +364,7 @@ def process_table_response(
364364
"""Process the results"""
365365
final_data: SnubaData = []
366366
final_confidence: ConfidenceData = []
367-
final_meta: EventsMeta = EventsMeta(
368-
fields={},
369-
full_scan=handle_downsample_meta(rpc_response.meta.downsampled_storage_meta),
370-
)
367+
final_meta: EventsMeta = events_meta_from_rpc_request_meta(rpc_response.meta)
371368
# Mapping from public alias to resolved column so we know type etc.
372369
columns_by_name = {col.public_alias: col for col in table_request.columns}
373370

@@ -767,10 +764,7 @@ def run_top_events_timeseries_query(
767764
"""Process the results"""
768765
map_result_key_to_timeseries = defaultdict(list)
769766

770-
final_meta: EventsMeta = EventsMeta(
771-
fields={},
772-
full_scan=handle_downsample_meta(rpc_response.meta.downsampled_storage_meta),
773-
)
767+
final_meta: EventsMeta = events_meta_from_rpc_request_meta(rpc_response.meta)
774768

775769
if params.debug:
776770
set_debug_meta(final_meta, rpc_response.meta, rpc_request)

src/sentry/snuba/spans_rpc.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from sentry.exceptions import InvalidSearchQuery
1010
from sentry.search.eap.constants import DOUBLE, INT, STRING
1111
from sentry.search.eap.resolver import SearchResolver
12-
from sentry.search.eap.sampling import handle_downsample_meta
12+
from sentry.search.eap.sampling import events_meta_from_rpc_request_meta
1313
from sentry.search.eap.spans.definitions import SPAN_DEFINITIONS
1414
from sentry.search.eap.types import AdditionalQueries, EAPResponse, SearchResolverConfig
1515
from sentry.search.events.types import SAMPLING_MODES, EventsMeta, SnubaParams
@@ -91,10 +91,7 @@ def run_timeseries_query(
9191
rpc_response = snuba_rpc.timeseries_rpc([rpc_request])[0]
9292
"""Process the results"""
9393
result = rpc_dataset_common.ProcessedTimeseries()
94-
final_meta: EventsMeta = EventsMeta(
95-
fields={},
96-
full_scan=handle_downsample_meta(rpc_response.meta.downsampled_storage_meta),
97-
)
94+
final_meta: EventsMeta = events_meta_from_rpc_request_meta(rpc_response.meta)
9895
if params.debug:
9996
set_debug_meta(final_meta, rpc_response.meta, rpc_request)
10097
for resolved_field in aggregates + groupbys:

src/sentry/snuba/trace_metrics.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
from sentry.search.eap import constants
88
from sentry.search.eap.resolver import SearchResolver
9-
from sentry.search.eap.sampling import handle_downsample_meta
9+
from sentry.search.eap.sampling import events_meta_from_rpc_request_meta
1010
from sentry.search.eap.trace_metrics.definitions import TRACE_METRICS_DEFINITIONS
1111
from sentry.search.eap.types import AdditionalQueries, EAPResponse, SearchResolverConfig
1212
from sentry.search.events.types import SAMPLING_MODES, EventsMeta, SnubaParams
@@ -104,10 +104,7 @@ def run_timeseries_query(
104104

105105
"""Process the results"""
106106
result = rpc_dataset_common.ProcessedTimeseries()
107-
final_meta: EventsMeta = EventsMeta(
108-
fields={},
109-
full_scan=handle_downsample_meta(rpc_response.meta.downsampled_storage_meta),
110-
)
107+
final_meta: EventsMeta = events_meta_from_rpc_request_meta(rpc_response.meta)
111108
for resolved_field in aggregates + groupbys:
112109
final_meta["fields"][resolved_field.public_alias] = resolved_field.search_type
113110

tests/snuba/api/endpoints/test_organization_events_ourlogs.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -888,3 +888,17 @@ def test_high_accuracy_flex_time_without_feature_flag(self):
888888

889889
response = self.do_request(request)
890890
assert response.status_code == 400
891+
892+
def test_bytes_scanned(self):
893+
self.store_ourlogs([self.create_ourlog({"body": "log"}, timestamp=self.ten_mins_ago)])
894+
895+
request = {
896+
"field": ["timestamp", "message"],
897+
"orderby": "-timestamp",
898+
"project": self.project.id,
899+
"dataset": self.dataset,
900+
}
901+
902+
response = self.do_request(request)
903+
assert response.status_code == 200
904+
assert response.data["meta"]["bytesScanned"] > 0

tests/snuba/api/endpoints/test_organization_events_span_indexed.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,7 @@ def _test_simple_measurements(self, keys):
684684
)
685685
assert response.status_code == 200, response.content
686686
expected = {
687+
"bytesScanned": mock.ANY,
687688
"dataScanned": "full",
688689
"dataset": mock.ANY,
689690
"datasetReason": "unchanged",
@@ -1902,6 +1903,7 @@ def test_span_data_fields_http_resource(self) -> None:
19021903
},
19031904
]
19041905
expected = {
1906+
"bytesScanned": mock.ANY,
19051907
"dataScanned": "full",
19061908
"dataset": mock.ANY,
19071909
"datasetReason": "unchanged",

0 commit comments

Comments
 (0)