-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ref(generic-metrics): Migrate UseCaseKey to UseCaseID for organization metrics #51776
Conversation
95c2068
to
3e2179c
Compare
Codecov Report
Additional details and impacted files@@ Coverage Diff @@
## master #51776 +/- ##
==========================================
- Coverage 79.32% 77.59% -1.73%
==========================================
Files 4909 4909
Lines 205933 205995 +62
Branches 35187 35193 +6
==========================================
- Hits 163364 159851 -3513
- Misses 37574 41092 +3518
- Partials 4995 5052 +57
|
This reverts commit 1c40763.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work! I have left a few comments that I think should be addressed iff we know that UseCaseID.SPANS
will use the generic_metrics
dataset. If not then just remove any check for SPANS
in the code (limiting it to only TRANSACTIONS
and SESSIONS
), since we might have to support spans for the metrics layer in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, will wait for @RaduW's double check here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really nice PR, thank you for doing it.
Let's please clarify the endpoint issue (below) .
One big concern I have is regarding changing the input/output of endpoints from "performance", "release-health" to "transactions" and "sessions".
I think we can't do that in one go.
If we want to do it we would have to:
- first support both as input (in the endpoints)
- change UI to send UseCaseIDs and accept both UseCaseIDs and UseCaseKeys
- change endpoints to only accept UseCaseIDs and send UseCaseIDs
- change UI to accept only UseCaseIDs
One small concern: I think we should not accept both UseCaseID and UseCaseKey in the sentry_metrics.utils
.
I think you already handled all cases already so there is no need to keep the mess around.
try: | ||
return UseCaseKey(request.GET.get("useCase", "release-health")) | ||
return UseCaseID(request.GET.get("useCase", "sessions")) | ||
except ValueError: | ||
raise ParseError( | ||
detail=f"Invalid useCase parameter. Please use one of: {[uc.value for uc in UseCaseKey]}" | ||
detail=f"Invalid useCase parameter. Please use one of: {[uc.value for uc in UseCaseID]}" | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we want to do this in one shot (i.e. the UI will still use the strings "performance" and "release-health"
at least in the beginning).
We should convert the query params here from UseCaseKey to UseCaseID in here,
something like:
# at the top of the file
from sentry.sentry_metrics.indexer.base import to_use_case_id
...
try:
use_case_key = UseCaseKey(request.GET.get("useCase", "release-health"))
return to_use_case_id(use_case_key)
except ValueError:
raise ParseError(
detail=f"Invalid useCase parameter. Please use one of: {[uc.value for uc in UseCaseKey]}"
)```
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean our API should accept the following for now
strings it accept | enum it maps to |
---|---|
"performance" |
UseCaseID.TRANSACTIONS |
"transactions" |
UseCaseID.TRANSACTIONS |
"sessions" |
UseCaseID.SESSIONS |
"release-health" |
UseCaseID.SESSIONS |
Once this pr is deployed, and the front end changes made, we will change the API again so that it will accept:
strings it accept | enum it maps to |
---|---|
"transactions" |
UseCaseID.TRANSACTIONS |
"sessions" |
UseCaseID.SESSIONS |
How does that sound?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey John,
If it was up to me I would just keep the external interface fixed ( i.e. emit and accept the strings "performance" and "release-health" .
What you propose is much cleaner, and also harder.
If we change our endpoint to also accept "transactions" and "sessions" there is no harm done, we are still backward compatible.
At that point in time we can also change the UI to both accept and send "transactions" and "sessions".
Changing the backend to emit (in the response) "transactions" and "sessions" or stop accepting "release-health" and "performance" in its parameters breaks backward compatibility and I'm not quite sure what is our policy on that.
We need to take in account that we potentially have external users that are using the API (all our endpoints are considered public API) and if we do that we'll break them ( for no good reason IMO).
Before breaking compatibility we should check if that's acceptable (not sure who we should ask).
As a compromise we could make the Backend accept "transactions" and "sessions" ( in addition to "release-health" and "performance" ) and maybe make the UI send "transactions" and "sessions" and also accept "transactions" and "sessions" in addition to "release-health" and "performance".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see, thanks!
def reverse_resolve_tag_value( | ||
use_case_id: UseCaseKey, org_id: int, index: Union[int, str, None], weak: bool = False | ||
use_case_id: Union[UseCaseID, UseCaseKey], | ||
org_id: int, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not do it here ( but at the call site... as high as possible).
I would leave reverse_resolve_tag_value
, reverse_resolve
, reverse_resolve_weak
, resolve
... to take only UseCaseID
.
If we allow them to take either UseCaseKey or UseCaseID we just moved the problem from the indexer here ( an improvment but not by much).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @RaduW on this. I would prefer to have all the downstream methods accept UseCaseId
and perform coercions at top level if we don't want to also refactor there.
@@ -341,7 +340,7 @@ def validate_end(self) -> None: | |||
def validate_granularity(self) -> None: | |||
# Logic specific to how we handle time series in discover in terms of granularity and interval | |||
if ( | |||
self.use_case_key == UseCaseKey.PERFORMANCE | |||
self.use_case_id == UseCaseID.TRANSACTIONS |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@iambriccardo I'm not sure what are you suggesting ( at this level we shouldn't see a UseCaseKey
anymore, everything should be UseCaseID, if we don't support spans here we should make it explicit).
@@ -70,7 +70,7 @@ def test_incorrect_use_case_id_value(self): | |||
assert response.status_code == 400 | |||
assert ( | |||
response.json()["detail"] | |||
== "Invalid useCase parameter. Please use one of: ['release-health', 'performance']" | |||
== f"Invalid useCase parameter. Please use one of: {[uc.value for uc in UseCaseID]}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(as commented in the endpoint)
I don't think we should change the inputs of endpoints at this time.
@RaduW and @iambriccardo do you guys mind giving me a hand with this single test that is failing?
I think I might have missed something really obvious but can't figure out why :( |
@john-z-yang |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left some minor nits
@@ -196,11 +196,11 @@ def _get_entity_of_metric_mri( | |||
raise InvalidParams | |||
|
|||
entity_keys_set: frozenset[EntityKey] | |||
if use_case_id == UseCaseKey.PERFORMANCE: | |||
if use_case_id is UseCaseID.TRANSACTIONS: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why somewhere we are using ==
and here is
? I would keep ==
, what do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess different people changed it in different ways.
I generally use ==
with the exception of when I check against None
where I always try to use is
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Exactly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is UseCaseId.Transaction
is the correct usage according to PEP 8:
Comparisons to singletons like None should always be done with is or is not, never the equality operators.
https://peps.python.org/pep-0008/#programming-recommendations
def reverse_resolve_tag_value( | ||
use_case_id: UseCaseKey, org_id: int, index: Union[int, str, None], weak: bool = False | ||
use_case_id: Union[UseCaseID, UseCaseKey], | ||
org_id: int, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @RaduW on this. I would prefer to have all the downstream methods accept UseCaseId
and perform coercions at top level if we don't want to also refactor there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 🚢
Refactoring usages of
UseCaseKey
intoUseCaseID
After recent changes to the metrics platform, we are no longer using
UseCaseKey
to represent the use case of a metrics and are transitioning toUseCaseID
.This pr refactors instances of
UseCaseKey
so that in the future it can be deleted/deprecated (see pr 46575)