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

Add the route ID to uuid #3372

Merged
merged 7 commits into from
Sep 29, 2023
Merged

Add the route ID to uuid #3372

merged 7 commits into from
Sep 29, 2023

Conversation

qinxx108
Copy link
Contributor

@qinxx108 qinxx108 commented May 31, 2023

Adding a UUID to identify the route in general
The route can be UUID by itself matchers+parents matchers + itself position

                                                                         route1(matcher="1")
         
                    route2(matcher="1")                   route3(matcher="1")           route4(matcher="1")

route5(matcher="1")      route6(matcher="1")            

For example to UUID route 6, it will be (matcher="1")/(matcher="1")/(matcher="1")/1

@qinxx108 qinxx108 force-pushed the add-route-id branch 2 times, most recently from 259ad9f to 4d2bc69 Compare May 31, 2023 18:07
@@ -180,6 +180,29 @@ func (r *Route) Key() string {
return b.String()
}

// ID returns a key for the route. It should uniquely identify the route in general.
Copy link
Contributor

@rohang98 rohang98 May 31, 2023

Choose a reason for hiding this comment

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

Should we include a line about how it's different than Key(), so something like, ID returns a unique key for the route. It is different than Key() as it adds the position in the list of parent routes.?

Copy link
Member

@simonpasquier simonpasquier left a comment

Choose a reason for hiding this comment

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

I'm missing the context about this change. Is it linked to the pagination API?

@@ -853,3 +853,78 @@ routes:
}
}
}

func TestRouteID(t *testing.T) {
Copy link
Member

Choose a reason for hiding this comment

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

if we're only testing the top-level routes, there's no need for having sub-routes?
also it might be good to have routes with same key but different ids?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

"I'm missing the context about this change. Is it linked to the pagination API?"

-> It is related as we need to UUID an aggregation group, aggregation group can be uuid by group_labels + routeId

Copy link
Contributor Author

Choose a reason for hiding this comment

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

=> if we're only testing the top-level routes, there's no need for having sub-routes?
also it might be good to have routes with same key but different ids?

Added the test

Comment on lines 183 to 184
// ID returns a key for the route. It should uniquely identify the route in general,
// it is different than Key() as it adds the route's position on its parent's children.
Copy link
Member

Choose a reason for hiding this comment

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

(nit) not sure if we need to go into the implementation details here.

Suggested change
// ID returns a key for the route. It should uniquely identify the route in general,
// it is different than Key() as it adds the route's position on its parent's children.
// ID returns a unique identifier for the route, unlike Key().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@gotjosh
Copy link
Member

gotjosh commented Jun 8, 2023

Overall direction looks good, but I have a couple of pieces of feedback:

  1. I think we should directly make the ID an attribute of the Route struct. Routes structs are only created once once the Alertmanager starts or its configuration its updated and computing the IDs every single time is not needed as they don't change.

  2. I think using the string representation of matches + position is a bit less human-friendly and provide poor UX. In particular, because we expect these to be used in URL that are meant to be be copy / pasteable by users. I suggest we do the following (and use a fnv hash on its hex representation)

// ID returns a unique identifier for the route, unlike Key().
func (r *Route) ID() string {
	hash := fnv.New64()

	var position *int
	if r.parent != nil {
		// Find the position in the same level leaf.
		for i, cr := range r.parent.Routes {
			if cr == r {
				position = &i
				break
			}
		}
	}

	_, _ = hash.Write([]byte(r.Key()))

	if position != nil {
		_, _ = hash.Write([]byte("/"))
		_, _ = hash.Write([]byte(fmt.Sprint(*position)))
	}

	return fmt.Sprintf("%016x", hash.Sum64())
}
  1. I have a few comments on the readability of the test, but let's tackle the other two first, and then we can move into the test (which it's 👍 at an assertion level) later as those are mostly nits.

@qinxx108
Copy link
Contributor Author

qinxx108 commented Jul 5, 2023

Overall direction looks good, but I have a couple of pieces of feedback:

  1. I think we should directly make the ID an attribute of the Route struct. Routes structs are only created once once the Alertmanager starts or its configuration its updated and computing the IDs every single time is not needed as they don't change.
  2. I think using the string representation of matches + position is a bit less human-friendly and provide poor UX. In particular, because we expect these to be used in URL that are meant to be be copy / pasteable by users. I suggest we do the following (and use a fnv hash on its hex representation)
// ID returns a unique identifier for the route, unlike Key().
func (r *Route) ID() string {
	hash := fnv.New64()

	var position *int
	if r.parent != nil {
		// Find the position in the same level leaf.
		for i, cr := range r.parent.Routes {
			if cr == r {
				position = &i
				break
			}
		}
	}

	_, _ = hash.Write([]byte(r.Key()))

	if position != nil {
		_, _ = hash.Write([]byte("/"))
		_, _ = hash.Write([]byte(fmt.Sprint(*position)))
	}

	return fmt.Sprintf("%016x", hash.Sum64())
}
  1. I have a few comments on the readability of the test, but let's tackle the other two first, and then we can move into the test (which it's 👍 at an assertion level) later as those are mostly nits.
  1. I think we should directly make the ID an attribute of the Route struct.
    => When a route gets created, we don't know its position as the other route in the same level in the tree hasn't finished creation yet. Add some comments about the ID function

  2. use a fnv hash on its hex representation
    I will convert this to use hash before using it in the api, i was thinking about more readable for coding perspective before returning to customer: https://github.com/prometheus/alertmanager/pull/3364/files#diff-2ec4e2e390946f66324eb00bb9e735280a4d018e65de41e64bebac8bebebd23b. But i am find using hash in here as well, please let me know your thought

@gotjosh
Copy link
Member

gotjosh commented Aug 10, 2023

@qinxx108 if I remember correctly, this is the first PR that we're suppose to merge as part of the API - right? If so, could you rebase to fix the diff?

Thanks!

@qinxx108
Copy link
Contributor Author

@gotjosh Yes this is the change
Rebased !

Thank you!

Copy link
Member

@gotjosh gotjosh left a comment

Choose a reason for hiding this comment

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

LGTM

Thank you very much for your contribution! I have addressed my own feedback.

@qinxx108
Copy link
Contributor Author

@gotjosh wonder if we can merge this pr?

@gotjosh
Copy link
Member

gotjosh commented Sep 13, 2023

Yep, we can. Thanks again @qinxx108! Can you please rebase to fix added commits?

qinxx108 and others added 7 commits September 21, 2023 03:27
Signed-off-by: Yijie Qin <qinyijie@amazon.com>
Signed-off-by: Yijie Qin <qinyijie@amazon.com>
Signed-off-by: Yijie Qin <qinyijie@amazon.com>
Signed-off-by: Yijie Qin <qinyijie@amazon.com>
Signed-off-by: Yijie Qin <qinyijie@amazon.com>
- use `require.ElementsMatch` instead of `deepequal`. The feedback on what's missing is much better.
- remove spaces from the example configuration to make it easier to read.

Signed-off-by: gotjosh <josue.abreu@gmail.com>
Signed-off-by: gotjosh <josue.abreu@gmail.com>
@gotjosh gotjosh merged commit 57fdd13 into prometheus:main Sep 29, 2023
1 check passed
alexweav pushed a commit to grafana/prometheus-alertmanager that referenced this pull request Oct 27, 2023
* Add the route ID to uuid

Signed-off-by: Yijie Qin <qinyijie@amazon.com>
---------

Signed-off-by: Yijie Qin <qinyijie@amazon.com>
@grobinson-grafana
Copy link
Contributor

Hi! 👋 I found a bug where route.ID() can return conflicting IDs. I've opened an issue here #3802.

SuperQ added a commit that referenced this pull request Oct 16, 2024
* [CHANGE] Deprecate and remove api/v1/ #2970
* [CHANGE] Remove unused feature flags #3676
* [CHANGE] Newlines in smtp password file are now ignored #3681
* [CHANGE] Change compat metrics to counters #3686
* [CHANGE] Do not register compat metrics in amtool #3713
* [CHANGE] Remove metrics from compat package #3714
* [CHANGE] Mark muted alerts #3793
* [FEATURE] Add metric for inhibit rules #3681
* [FEATURE] Support UTF-8 label matchers #3453, #3507, #3523, #3483, #3567, #3568, #3569, #3571, #3595, #3604, #3619, #3658, #3659, #3662, #3668, 3572
* [FEATURE] Add counter to track alerts dropped outside of time_intervals #3565
* [FEATURE] Add date and tz functions to templates #3812
* [FEATURE] Add limits for silences #3852
* [FEATURE] Add time helpers for templates #3863
* [FEATURE] Add auto GOMAXPROCS #3837
* [FEATURE] Add auto GOMEMLIMIT #3895
* [FEATURE] Add Jira receiver integration #3590
* [ENHANCEMENT] Add the receiver name to notification metrics #3045
* [ENHANCEMENT] Add the route ID to uuid #3372
* [ENHANCEMENT] Add duration to the notify success message #3559
* [ENHANCEMENT] Implement webhook_url_file for discord and msteams #3555
* [ENHANCEMENT] Add debug logs for muted alerts #3558
* [ENHANCEMENT] API: Allow the Silences API to use their own 400 response #3610
* [ENHANCEMENT] Add summary to msteams notification #3616
* [ENHANCEMENT] Add context reasons to notifications failed counter #3631
* [ENHANCEMENT] Add optional native histogram support to latency metrics #3737
* [ENHANCEMENT] Enable setting ThreadId for Telegram notifications #3638
* [ENHANCEMENT] Allow webex roomID from template #3801
* [BUGFIX] Add missing integrations to notify metrics #3480
* [BUGFIX] Add missing ttl in pushhover #3474
* [BUGFIX] Fix scheme required for webhook url in amtool #3409
* [BUGFIX] Remove duplicate integration from metrics #3516
* [BUGFIX] Reflect Discord's max length message limits #3597
* [BUGFIX] Fix nil error in warn logs about incompatible matchers #3683
* [BUGFIX] Fix a small number of inconsistencies in compat package logging #3718
* [BUGFIX] Fix log line in featurecontrol #3719
* [BUGFIX] Fix panic in acceptance tests #3592
* [BUGFIX] Fix flaky test TestClusterJoinAndReconnect/TestTLSConnection #3722
* [BUGFIX] Fix crash on errors when url_file is used #3800
* [BUGFIX] Fix race condition in dispatch.go #3826
* [BUGFIX] Fix race conditions in the memory alerts store #3648
* [BUGFIX] Hide config.SecretURL when the URL is incorrect. #3887
* [BUGFIX] Fix invalid silence causes incomplete updates #3898
* [BUGFIX] Fix leaking of Silences matcherCache entries #3930
* [BUGFIX] Close SMTP submission correctly to handle errors #4006

Signed-off-by: SuperQ <superq@gmail.com>
@SuperQ SuperQ mentioned this pull request Oct 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants