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

Metric refactor #242

Merged
merged 20 commits into from
Jun 2, 2021
Merged

Metric refactor #242

merged 20 commits into from
Jun 2, 2021

Conversation

pradnic
Copy link
Contributor

@pradnic pradnic commented Apr 9, 2021

As requested here.

In the current version of the system metric production is done ad hoc to comply with specific requirements, Scopes are initialized in service components, Ex: 1, 2, 3; and metrics are directly set by all components as well Ex: 1, 2.

This makes adding service-wide configurations to metric generation (such as Detailed Metrics) particularly difficult. In order to accommodate this feature, we made the following refactor.

This PR refactors metric handling in the ratelimit service, namely:

  • Adds stats.Manager structure.
  • Centralizes metric creation in the stats.Manager.
  • Removes, where possible, metric scope handling from the other service's components.

pradnic added 7 commits March 17, 2021 16:40
Signed-off-by: Pablo Radnic <[email protected]>
Signed-off-by: Pablo Radnic <[email protected]>
Signed-off-by: Pablo Radnic <[email protected]>
Signed-off-by: Pablo Radnic <[email protected]>
Signed-off-by: Pablo Radnic <[email protected]>
@mattklein123 mattklein123 self-assigned this Apr 9, 2021
@mattklein123
Copy link
Member

cc @nezdolik @ysawa0 would either of you be willing to help review this?

@nezdolik
Copy link
Member

@mattklein123 I can help review this Friday

Copy link
Member

@nezdolik nezdolik left a comment

Choose a reason for hiding this comment

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

Does extending existing settings with option to include detailed stats come in separate PR?

@@ -56,5 +47,5 @@ type RateLimitConfigLoader interface {
// @param statsScope supplies the stats scope to use for limit stats during runtime.
Copy link
Member

Choose a reason for hiding this comment

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

nit: update function documentation with new parameter

config RateLimitConfigToLoad, parentKey string, descriptors []yamlDescriptor,
statsScope stats.Scope) {
// @param manager that owns the stats.Scope.
func (this *rateLimitDescriptor) loadDescriptors(config RateLimitConfigToLoad, parentKey string, descriptors []yamlDescriptor, manager stats.Manager) {
Copy link
Member

Choose a reason for hiding this comment

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

nit: rename arg name manager ->statsManager

@@ -268,13 +235,12 @@ func (this *rateLimitConfigImpl) GetLimit(
}

if descriptor.GetLimit() != nil {
rateLimitKey := domain + "." + this.descriptorToKey(descriptor)
rateLimitKey := stats.DescriptorKey(domain, descriptor)
Copy link
Member

Choose a reason for hiding this comment

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

what is the reasoning behind moving descriptorToKey function to stats package?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to client package (where it is used currently).

@@ -316,9 +282,9 @@ func (this *rateLimitConfigImpl) GetLimit(
// @param stats supplies the stats scope to use for limit stats during runtime.
// @return a new config.
func NewRateLimitConfigImpl(
configs []RateLimitConfigToLoad, statsScope stats.Scope) RateLimitConfig {
configs []RateLimitConfigToLoad, manager stats.Manager) RateLimitConfig {
Copy link
Member

Choose a reason for hiding this comment

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

nit: same as above, rename manager to smth like statsManager

dummyStats := stats.NewStore(stats.NewNullSink(), false)
config.NewRateLimitConfigImpl(allConfigs, dummyStats)
settingStruct := settings.NewSettings()
manager := stats.NewStatManager(gostats.NewStore(gostats.NewNullSink(), false), settingStruct)
Copy link
Member

Choose a reason for hiding this comment

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

nit: inline creation of settings here instead

logger "github.com/sirupsen/logrus"
)

func NewStatManager(store gostats.Store, s settings.Settings) *ManagerImpl {
Copy link
Member

Choose a reason for hiding this comment

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

renaming s settings would probably clash with settings package, but it could have improved readability

}

func (this *ManagerImpl) NewShouldRateLimitStats() ShouldRateLimitStats {
s := this.serviceStatsScope.Scope("call.should_rate_limit")
Copy link
Member

Choose a reason for hiding this comment

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

nit: s-> scope

//todo: Ideally the gostats package fields should be unexported
// the inner value could be interacted with via getters such as rlStats.TotalHits() uint64
// This ensures that setters such as Inc() and Add() can only be managed by ManagerImpl.
type RateLimitStats struct {
Copy link
Member

Choose a reason for hiding this comment

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

could be better to group all those struct definitions together either in top of this file or pull them out into manager.go file

rlStatsScope: serviceScope.Scope("rate_limit"),
legacyStatsScope: serviceScope.Scope("call.should_rate_limit_legacy"),
serviceStatsScope: serviceScope,
detailedMetricsScope: serviceScope.Scope("rate_limit").Scope("detailed"),
Copy link
Member

Choose a reason for hiding this comment

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

should this scope be initialised only if detailed is set to true?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed all mentions of detailedMetrics they will be added on the DetailedMetrics PR

legacyStatsScope gostats.Scope
serviceStatsScope gostats.Scope
detailedMetricsScope gostats.Scope
detailed bool
Copy link
Member

Choose a reason for hiding this comment

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

how is this field currently used?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed all mentions of detailedMetrics they will be added on the DetailedMetrics PR

@pradnic
Copy link
Contributor Author

pradnic commented Apr 19, 2021

Thank you @nezdolik for the review.

Finished working on the requested changes. Alongside the nit's these are the most important points:

  • Renamed stats.Manager variables to statsManager in order to improve clarity.
  • Added documentation on manager.go types and methods.
  • Moved type definitions from manager_impl.go to manager.go

Copy link
Member

@nezdolik nezdolik left a comment

Choose a reason for hiding this comment

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

PR looks good to me. @mattklein123 @dweitzman would you take a look?

import stats "github.com/lyft/gostats"
import gostats "github.com/lyft/gostats"

// Manager is the interface that wraps initialization of stat structures
Copy link
Member

Choose a reason for hiding this comment

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

nit: add '.' in the end of each doc sentence

nezdolik
nezdolik previously approved these changes Apr 23, 2021
@pradnic
Copy link
Contributor Author

pradnic commented Apr 27, 2021

Hi @mattklein123 let me know if we need any more work on this PR or if we can go forwards with the next steps in order to add detailed-metrics feature.

@pradnic
Copy link
Contributor Author

pradnic commented May 26, 2021

Hi @mattklein123 what are the next steps you suggest in order to get this feature merged in upstream?

@mattklein123
Copy link
Member

Merge main, and then I will take a look.

/wait

@mattklein123
Copy link
Member

Please check CI

/wait

Signed-off-by: Pablo Radnic <[email protected]>
@pradnic pradnic force-pushed the metric-refactor branch from 70f3800 to feaa224 Compare June 2, 2021 16:13
Signed-off-by: Pablo Radnic <[email protected]>
func([]config.RateLimitConfigToLoad, stats.Scope) {
barrier.signal()
func([]config.RateLimitConfigToLoad, stats.Manager) {
defer barrier.signal()
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@mattklein123 I believe the CI build failed because of a race-condition in this test. The scenario is similar to the one fixed in this recently merged PR.
I believe the issue should be resolved with this change.

Copy link
Member

@mattklein123 mattklein123 left a comment

Choose a reason for hiding this comment

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

Thanks! Just to make sure I understand, there should be no functional change for this PR, right? In a future PR you will add the ability to have detailed stats?

/wait-any

@pradnic
Copy link
Contributor Author

pradnic commented Jun 2, 2021

Thanks! Just to make sure I understand, there should be no functional change for this PR, right? In a future PR you will add the ability to have detailed stats?

Correct! This changeset holds no functional changes. The opt-in Detailed Metrics feature will come in the next PR.

@mattklein123 mattklein123 merged commit 6aaad7c into envoyproxy:main Jun 2, 2021
@dweitzman
Copy link
Contributor

@dweitzman would you take a look?

I didn't read all the code, but the overall goal makes sense to me. I'm in favor of anything that isolates the github.com/lyft/gostats imports so they can more easily be wrapped in or replaced by a more modern, flexible, or expressive way to tracking metrics.

zdmytriv pushed a commit to verygoodsecurity/ratelimit that referenced this pull request Aug 2, 2021
@jdamata jdamata mentioned this pull request Mar 18, 2022
timcovar pushed a commit to goatapp/ratelimit that referenced this pull request Jan 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.

4 participants