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

agent/metrics: allow preinitializing supported metrics to zero #312

Merged
merged 1 commit into from
Aug 24, 2023

Conversation

roobre
Copy link
Collaborator

@roobre roobre commented Aug 22, 2023

Description

With the introduction of metrics in #213, we missed an important misbehavior: If a proxy never calls Inc on a metric, it is impossible to tell whether the metric is zero, or is not supported by the proxy. To fix this, this PR give proxies the ability to pre-initialize supported metrics to zero.

This PR also introduces a workaround: As the HTTP proxy is not directly testable, the handler is, the test for the handler needs to duplicate this initialization. This workaround should be removed when testing for the HTTP proxy is improved.

Checklist:

  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works.
  • I have run linter locally (make lint) and all checks pass.
  • I have run tests locally (make test) and all tests pass.
  • I have run relevant e2e test locally (make e2e-xxx for agent, disruptors, kubernetes or cluster related changes)
  • Any dependent changes have been merged and published in downstream modules

@roobre roobre changed the title agent/metrics: allow preinitializing supporting metrics to zero agent/metrics: allow preinitializing supported metrics to zero Aug 22, 2023
@roobre roobre force-pushed the proxy-metrics-uninitialized branch from 046ee66 to a8662fd Compare August 22, 2023 13:16
@pablochacin
Copy link
Collaborator

pablochacin commented Aug 23, 2023

@roobre seems we don't have an issue for tracking this. Mind opening one?

As the HTTP proxy is not directly testable, the handler is, the test for the handler needs to duplicate this initialization. This workaround should be removed when testing for the HTTP proxy is improved.

mm := protocol.NewMetricMap(foo)
fooMetric, hasFoo := mm.Map()[foo]
if !hasFoo {
t.Fatalf("foo should be explicitly set")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Minor thing: I find this message confusing because foo was explicitly set. Maybe "foo should exist" makes clear why it failed.

// supportedMetrics is a helper function that returns the metrics that the http proxy supports and thus should be
// pre-initialized to zero. This function exists as a workaround, as currently the handler tests need to initialize the
// MetricMap. It should not be needed when metric tests are moved from the handler to the proxy.
func supportedMetrics() []string {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I do not agree with this comment. Moreover, I think this method should be public as part of the contract of the Proxy.

Copy link
Collaborator Author

@roobre roobre Aug 23, 2023

Choose a reason for hiding this comment

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

I like more declaring which metrics are supported by making them available in the map returned by Metrics, rather than exposing that list directly.

In my view, consumers of the Proxy interface should not be interested on the "list of metrics this proxy supports", which would be this method, but rather on "is this metric supported?". I believe this question is answered better by the Metrics method containing or not a particular metric.

As an example, the way a user would ask the proxy if it has a metric would be this:

requests, hasMetric := d.proxy.Metrics()[MetricRequests]
if hasMetric && requests == 0 {
    return fmt.Errorf("disruptor did not receive any request")
}

If the supported list of metrics was part of the contract, I think the code would look more verbose:

supportedMetrics := d.proxy.SupportedMetrics()
if slices.contains(supportedMetrics, MetricRequests) && d.proxy.Metrics()[MetricRequests] == 0 {
    return fmt.Errorf("disruptor did not receive any request")
}

I think the first way leverages the built-in existence check on maps to convey this meaning, while the latter reimplements is as a is-contained-in-separate slice which I like a bit less.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't see why having the list of metrics available should change the code for checking the metric, therefore I don't think the "verbosity" argument is valid.

In any case, my point was that having the proxy to know the supported list of metrics is not in my opinion a hack around the limitations of testing but something we expect it to know. The hack, in any case, is testing this at the handler level and not the proxy level. Maybe this should be stated more clearly in the comment.

Regarding exposing it or not in the API, it is secondary. But I think it is valid because it is not immediately evident that the proxy.Metrics() method will return all supported metrics regardless of whether they have a non-zero value or not. We should make this more explicit in the documentation:

// Metrics returns a map of counter-type metrics. Implementations may return zero or more of the metrics defined
// below, as well as any number of implementation-defined metrics.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

These are good points, I've clarified both comments to state more clearly how supported metrics are exposed and the purpose of supportedMetrics. LMK if these look better to you 🙂

Copy link
Collaborator

@pablochacin pablochacin left a comment

Choose a reason for hiding this comment

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

In general, I think the approach is a reasonable solution until the underlying problem is addressed. I Only made two minor non-blocking comments.

@roobre
Copy link
Collaborator Author

roobre commented Aug 23, 2023

Issue regarding HTTP proxy testability open here: #314

@roobre roobre force-pushed the proxy-metrics-uninitialized branch from 8546a46 to 13afce5 Compare August 24, 2023 10:23
@roobre roobre merged commit daa6376 into main Aug 24, 2023
7 checks passed
@roobre roobre deleted the proxy-metrics-uninitialized branch August 24, 2023 11:32
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.

None yet

2 participants