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 collection-interval to metrics-generator user-configurable overrides #2899

Merged
merged 8 commits into from
Sep 13, 2023

Conversation

rlankfo
Copy link
Member

@rlankfo rlankfo commented Sep 6, 2023

What this PR does:

Extends the user-configurable overrides added in #2543 with collection_interval override.

New JSON payload:

{
    "forwarders": [],
    "metrics_generator": {
        "processors": [
            "service-graphs",
            "span-metrics"
        ],
        "disable_collection": false,
        "collection_interval": "60s",
        "processor": {
            "service_graphs": {
                "dimensions": [
                    "service.namespace"
                ],
                "enable_client_server_prefix": true,
                "peer_attributes": [
                    "peer.service",
                    "db.name",
                    "db.system",
                    "db.url"
                ]
            },
            "span_metrics": {
                "dimensions": [
                    "service.namespace"
                ],
                "enable_target_info": true
            }
        }
    }
}

Which issue(s) this PR fixes:
Fixes #

Checklist

  • Tests updated
  • Documentation added
  • CHANGELOG.md updated - the order of entries should be [CHANGE], [FEATURE], [ENHANCEMENT], [BUGFIX]

@CLAassistant
Copy link

CLAassistant commented Sep 6, 2023

CLA assistant check
All committers have signed the CLA.

DisableCollection *bool `json:"disable_collection,omitempty"`
Processors listtomap.ListToMap `json:"processors,omitempty"`
DisableCollection *bool `json:"disable_collection,omitempty"`
CollectionInterval *time.Duration `json:"collection_interval,omitempty"`
Copy link
Member Author

Choose a reason for hiding this comment

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

The json decoder expects time.Duration fields to be passed in nanoseconds. This means 60s is represented as 60000000000. This seemed like an acceptable trade-off and cleaner than making this a string and calling time.ParseDuration.

Copy link
Member

Choose a reason for hiding this comment

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

This should be fine, we use time.Duration in a lot of configuration structs and it will automatically parse durations formatted like 15s or 1m.

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 believe that will work when unmarshaling yaml because it's handled here:
https://github.com/go-yaml/yaml/blob/v3.0.1/decode.go#L647-L653

The json decoder won't accept a non numeric value, such as "60s". So I think here we'll either have to use nanoseconds as I pointed out, or this would need to be a string and we'd have to figure out the best place to run time.ParseDuration.

Copy link
Member Author

@rlankfo rlankfo Sep 7, 2023

Choose a reason for hiding this comment

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

Another option could be to change the JSON field to "collection_interval_seconds" and return *l.CollectionInterval * time.Second in GetCollectionInterval

Copy link
Member

Choose a reason for hiding this comment

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

Oh I see, it's an oversight of the json decoder to not use time.ParseDuration. I'd prefer to implement our own unmarshaler in that case so we can use 15s and 1m etc. That is easier to use and consistent with configuration in the configmap.

There are articles explaining how to implement the unmarshaler interface: https://biscuit.ninja/posts/go-unmarshalling-json-into-time-duration/

Copy link
Member Author

Choose a reason for hiding this comment

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

thanks @kvrhdn. I implemented the custom marshal/unmarshal and added some tests. Let me know what you think!

Copy link
Member

@kvrhdn kvrhdn left a comment

Choose a reason for hiding this comment

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

The changes look good, thanks!

Can you add some validation around collection interval? While users are free to set their preferred interval, we have to make sure they don't break anything or stress Tempo too much.
We have a validator for the overrides in this file: https://github.com/grafana/tempo/blob/main/cmd/tempo/app/overrides_validation.go

Right now people could post negative values which might lead to a panic. I think it's reasonable to say collection interval must be a value between 15s and 5m?

DisableCollection *bool `json:"disable_collection,omitempty"`
Processors listtomap.ListToMap `json:"processors,omitempty"`
DisableCollection *bool `json:"disable_collection,omitempty"`
CollectionInterval *time.Duration `json:"collection_interval,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

This should be fine, we use time.Duration in a lot of configuration structs and it will automatically parse durations formatted like 15s or 1m.

modules/overrides/userconfigurable/client/limits.go Outdated Show resolved Hide resolved
@rlankfo
Copy link
Member Author

rlankfo commented Sep 7, 2023

Right now people could post negative values which might lead to a panic. I think it's reasonable to say collection interval must be a value between 15s and 5m?

Thanks for the review @kvrhdn. I've added validation for this, please take a look.

@rlankfo rlankfo self-assigned this Sep 7, 2023
@rlankfo rlankfo requested a review from kvrhdn September 11, 2023 20:14
Copy link
Member

@kvrhdn kvrhdn left a comment

Choose a reason for hiding this comment

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

LGTM, works as expected 👍🏻 Just a slight comment about file structure.

Comment on lines 32 to 34
type Duration struct {
time.Duration
}
Copy link
Member

Choose a reason for hiding this comment

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

Mostly a nitpick: I think it would be cleaner to move the Duration struct into a separate file:

  • this file (unfortunately) already has a lot of boilerplate making it difficult to read
  • keeping it in a separate file will make it easier to reuse later, we can just move the file to shared package when we need it

What do you think of moving this struct and the corresponding test functions into duration.go?

Copy link
Member Author

Choose a reason for hiding this comment

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

Makes sense to me. I moved the code. Thanks!

@rlankfo rlankfo requested a review from kvrhdn September 12, 2023 21:42
Copy link
Member

@kvrhdn kvrhdn left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@kvrhdn kvrhdn merged commit f07ef96 into grafana:main Sep 13, 2023
14 checks passed
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.

3 participants