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

Charmhub: Request recorder collector #13089

Merged
merged 7 commits into from
Jun 18, 2021

Conversation

SimonRichardson
Copy link
Member

@SimonRichardson SimonRichardson commented Jun 17, 2021

The following wires up the outbound total requests API metrics. It uses
the juju/http request recorder.

We have to be extra careful about what we want to use as labels, we
don't want to log the path or the complete URL for a couple of reasons:

  1. Security around what can be in a URL; auth tokens et al
  2. We don't want to balloon the cardinality of the database.

With this in mind, we want to just request the hostnames for now, which
keeps the cardinality low.

Additionally, we have single responsibility for logging when performing
API requests.

The default HTTP transport will also give you a logging request
recorder, this should aid with always having a request recorder for
making charmhub requests.

As all the above is handled only when trace is enabled shouldn't impact
performance.

QA steps

Setup

$ juju bootstrap lxd test
$ juju switch controller
$ juju add-user prom
$ juju change-user-password prom
# you need the password for later!
$ juju grant prom read controller

Query

Note: you need to query first to show any outbound information. The metrics
are lazily created.

$ juju info mattermost
$ juju info badname
$ juju show-controller test --format=json | jq '.test.details."api-endpoints"[0]' | xargs -I % echo "https://%/introspection/metrics" | xargs curl -k -s -u user-prom:$PASSWORD | grep outbound_

Bug reference

@SimonRichardson SimonRichardson marked this pull request as ready for review June 18, 2021 11:16
This is the initial WIP for passing in the request recorder through the
layers to get metrics from queries.
The following creates a request recorder for the charmhub client. It
doesn't really do much atm, but shows that it is possible from the
facade layers.
The following ensures that we have single responsibility for logging
when performing API requests.

The default HTTP transport will also give you a logging request
recorder, this should aid with always having a request recorder for
making charmhub requests.

As all the above is handled only when trace is enabled shouldn't impact
performance.
The following wires up the outbound total requests API metrics. It uses
the juju/http request recorder.

We have to be extra careful about what we want to use as labels, we
don't want to log the path or the complete URL for a couple of reasons:

 1. Security around what can be in a URL; auth tokens et al
 2. We don't want to balloon the cardinality of the database.

With this in mind, we want to just request the host names for now, which
keeps the cardinality low.
The charms facade also uses the same setup/creation as charmhub facade,
so makes sense to do it in the same PR.
@SimonRichardson SimonRichardson force-pushed the request-recorder-collector branch from ecbae8e to 037c203 Compare June 18, 2021 11:20
Copy link
Member

@manadart manadart left a comment

Choose a reason for hiding this comment

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

Nice feature, but I think there's more we can do while we're in there.

apiserver/root.go Show resolved Hide resolved
apiserver/admin.go Show resolved Hide resolved
func (w httpRequestRecorderWrapper) Record(method string, url *url.URL, res *http.Response, rtt time.Duration) {
// Note: Do not log url.Path as REST queries _can_ include the name of the
// entities (charms, architectures, etc).
w.collector.TotalRequests.WithLabelValues(w.modelUUID, url.Host, strconv.FormatInt(int64(res.StatusCode), 10)).Inc()
Copy link
Member

Choose a reason for hiding this comment

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

I would make helpers for these - uniform access principle. Also means you don't refer to multiple members in a call.

Copy link
Contributor

Choose a reason for hiding this comment

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

Generally agree but in this case (just two call sites) it seems to me like overkill to add helpers.

The newRoot constructor took a various amount of different root types.
Instead of this, we just make apiHandler conform to an interface and
then we can just select the types off of that.

The test version was also easy to construct, just create an empty type
and pass back nil in most cases or a dummy resource container.

This should make the readability of a newRoot type easier to understand.
The following are fixes to linting issues.
@SimonRichardson SimonRichardson changed the title Request recorder collector Charmhub: Request recorder collector Jun 18, 2021
Copy link
Member

@manadart manadart left a comment

Choose a reason for hiding this comment

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

Nice.

@SimonRichardson
Copy link
Member Author

$$merge$$

@jujubot jujubot merged commit efd0260 into juju:2.9 Jun 18, 2021
jujubot added a commit that referenced this pull request Jun 22, 2021
#13094

Merge from 2.9 to bring forward:
- #13093 from manadart/2.9-machine-agent-test-race
- #13092 from hpidcock/fix-1929364
- #13089 from SimonRichardson/request-recorder-collector
- #13088 from SimonRichardson/leadership-context
- #13075 from manadart/2.9-net-get-machine
- #13081 from jujubot/increment-to-2.9.6

Only conflicts were the usual trivial ones in the version files.
@SimonRichardson SimonRichardson deleted the request-recorder-collector branch July 12, 2021 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants