Skip to content
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

feat(metrics_extraction): Always include the environment in the query hash #63774

Merged

Conversation

armenzg
Copy link
Member

@armenzg armenzg commented Jan 24, 2024

Alerts and widgets are colliding since widgets only include the environment in the tags rather than in the query hash.

This change will require 90 days of baking and then we will switch customers over and drop the old spec version.

All widgets will double in number.

@armenzg armenzg self-assigned this Jan 24, 2024
@github-actions github-actions bot added the Scope: Backend Automatically applied to PRs that change backend components label Jan 24, 2024
Copy link

codecov bot commented Jan 24, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (15e26c8) 81.25% compared to head (c1eb2db) 81.25%.
Report is 2 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master   #63774   +/-   ##
=======================================
  Coverage   81.25%   81.25%           
=======================================
  Files        5234     5234           
  Lines      230469   230477    +8     
  Branches    45232    45234    +2     
=======================================
+ Hits       187268   187280   +12     
+ Misses      37362    37358    -4     
  Partials     5839     5839           
Files Coverage Δ
src/sentry/conf/server.py 88.11% <ø> (ø)
src/sentry/features/__init__.py 100.00% <100.00%> (ø)
src/sentry/search/events/builder/metrics.py 88.58% <100.00%> (-0.02%) ⬇️
src/sentry/snuba/metrics/extraction.py 91.05% <100.00%> (+0.10%) ⬆️

... and 11 files with indirect coverage changes

Copy link
Member

@k-fish k-fish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, once you get tests passing then 👍

src/sentry/snuba/metrics/extraction.py Outdated Show resolved Hide resolved
src/sentry/snuba/metrics/extraction.py Outdated Show resolved Hide resolved
@armenzg armenzg changed the title feat(metrics_extraction): New spec version to include environment feat(metrics_extraction): Include environment in query hash for widgets Jan 26, 2024
@armenzg armenzg requested a review from a team as a code owner January 26, 2024 19:20
@armenzg armenzg requested review from k-fish, iambriccardo and obostjancic and removed request for iambriccardo and obostjancic January 26, 2024 19:20
Copy link
Member

@iambriccardo iambriccardo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am lacking context of why we are adding the environment now, but functionally speaking the PR LGTM!

armenzg added a commit that referenced this pull request Jan 30, 2024
…ollision (#64071)

When merging specs, iterate over the widgets first. This will make sure
that when an alert and widget specs collide, we will pick the spec of a
widget which contains the environment in the tags.

The next spec version in #63774 does not have this bug since the widget
will always include the environment in the query hash, thus, it will not
be possible for the alert spec to share the same query hash.

This duplication of specs is the main reason that we still have some
duplicated specs in
[SENTRY-2EAS](https://sentry.sentry.io/issues/4888069767/).
# save us to look where to add this logic again
spec_version = OnDemandMetricSpecVersioning.get_query_spec_version(self.organization_id)
return OnDemandMetricSpec(
return fetch_on_demand_metric_spec(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change will make sure that the tests have the same function to get an OnDemandMetricSpec from a Relay metric spec.

@@ -1430,6 +1444,27 @@ def _parse_query(value: str) -> QueryParsingResult:
raise Exception(f"Invalid search query '{value}' in on demand spec: {e}")


def fetch_on_demand_metric_spec(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can now be used by the tests to have a single entry point to querying the right spec based on feature flags.

Jump to the end of tests/sentry/relay/config/test_metric_extraction.py to see.

field = widget.aggregates[0] if widget.aggregates else ""
return OnDemandMetricSpec(
return fetch_on_demand_metric_spec(
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can now use this shared function to reduce differences between the code and the tests.

assert spec._query_str_for_hash == f"{expected_query_str_hash};['environment']"
assert spec.query_hash == "4fb5a472"
assert spec.spec_version.version == 2
assert spec.spec_version.flags == {"include_environment_tag"}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compare it without having the feature flag (just above):

        spec = _on_demand_spec_from_widget(default_project, widget)
        assert spec.query_hash == "f1353b0f"
        assert spec._query_str_for_hash == expected_query_str_hash
        assert spec.spec_version.version == 1
        assert spec.spec_version.flags == set()

Copy link
Member

@k-fish k-fish left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

Comment on lines +91 to 94
if features.has("organizations:on-demand-metrics-query-spec-version-two", org):
return cls.spec_versions[1]
return cls.spec_versions[0]

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking, but doing this by array lookup is a little strange since that feature flag should only be for SpecVersion(2), I think this can be hardcoded, which will make cleanup more obvious as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I used to have a different approach that did not require any changes.

if (
self.spec_type == MetricSpecType.DYNAMIC_QUERY
and self.spec_version.flags == set()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not blocking; I don't know that we'll need this flag matching, it's pretty complicated, I can't see us needing a lot of individual behaviours and every new ability to a spec version will essentially reset the spec anyway.

exception = capture_exception.call_args.args[0]
assert (
exception.args[0]
== "Spec version 1: Too many (2) on demand metric widgets for org baz"
== "Spec version 2: Too many (2) on demand metric widgets for org baz"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay so both spec version fail here and we're just checking the second one now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of them fail. I couldn't make up my mind. Perhaps I should not even take the version into consideration.


with Feature("organizations:on-demand-metrics-query-spec-version-two"):
spec = _on_demand_spec_from_widget(default_project, widget)
assert spec._query_str_for_hash == f"{expected_query_str_hash};['environment']"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is specifically what we want for the new spec version, so 👍

@armenzg armenzg merged commit 04f031f into master Jan 30, 2024
50 checks passed
@armenzg armenzg deleted the feat/environment_spec_version/metrics_extraction/armenzg branch January 30, 2024 15:38
snigdhas pushed a commit that referenced this pull request Jan 30, 2024
…ollision (#64071)

When merging specs, iterate over the widgets first. This will make sure
that when an alert and widget specs collide, we will pick the spec of a
widget which contains the environment in the tags.

The next spec version in #63774 does not have this bug since the widget
will always include the environment in the query hash, thus, it will not
be possible for the alert spec to share the same query hash.

This duplication of specs is the main reason that we still have some
duplicated specs in
[SENTRY-2EAS](https://sentry.sentry.io/issues/4888069767/).
snigdhas pushed a commit that referenced this pull request Jan 30, 2024
… hash (#63774)

Alerts and widgets are colliding since widgets only include the
environment in the tags rather than in the query hash.

This change will require 90 days of baking and then we will switch
customers over and drop the old spec version.

All widget extraction specs will double in number.
@github-actions github-actions bot locked and limited conversation to collaborators Feb 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Scope: Backend Automatically applied to PRs that change backend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants