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

Ignore accept header in requests to metrics service #1345

Merged
merged 4 commits into from
Aug 27, 2020

Conversation

ajsutton
Copy link
Contributor

PR description

The metrics HTTP service only has one supported representation for content but is applying overly strict content type negotiation and refusing to return any content if the Accept header is present and set to anything other than text/plain; version=0.0.4; charset=utf-8. This makes it incompatible with tools like DataDog which specify Accept: text/plain.

Fixed Issue(s)

Consensys/teku#2678

Changelog

Signed-off-by: Adrian Sutton <[email protected]>
Signed-off-by: Adrian Sutton <[email protected]>
Copy link
Contributor

@mbaxter mbaxter left a comment

Choose a reason for hiding this comment

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

LGTM

@shemnon
Copy link
Contributor

shemnon commented Aug 27, 2020

Has this been field tested against a Prometheus instance? IIRC when I first implemented this Prometheus was very particular about their content-type header.

Is there a way to produce this content type without vertx automatically freaking out about the accepts header not matching perfectly?

Copy link
Contributor

@shemnon shemnon left a comment

Choose a reason for hiding this comment

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

Looks like we can still send whatever Content-Type we want regardless of the accept header. But I think we should assert for it (see my suggestion).


// We should have JVM metrics already loaded, verify a simple key.
assertThat(props).containsKey("jvm_threads_deadlocked");
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
}
// Assert we still get the Content-Type Prometheus likes
assertThat(resp.header("Content-Type")).isEqualTo(TextFormat.CONTENT_TYPE_004);
}

You will also need import io.prometheus.client.exporter.common.TextFormat; but GitHub won't let me suggest that far our of the code diff.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

.method(HttpMethod.GET)
.produces(TextFormat.CONTENT_TYPE_004)
.handler(this::metricsRequest);
router.route("/metrics").method(HttpMethod.GET).handler(this::metricsRequest);
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe just check for "text/plain" instead of completely dropping Prometheus' very specific version?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Given we only have one representation to offer we shouldn't be doing any content negotiation (which is what the Accept header is for). If we had multiple representations, then yes filtering to a particular Accept makes sense but if there's a default version, it should just be returned even if it doesn't match Accept.

For example this works fine:

curl --fail -v -H 'Accept: foo/foo' https://www.google.com/

The caller can then decide if they want to process the response based on the Content-Type header.

@ajsutton ajsutton merged commit 80173d6 into hyperledger:master Aug 27, 2020
@ajsutton ajsutton deleted the metrics-ignore-accept branch August 27, 2020 22:12
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

3 participants