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

api: reorganize API package and add label values endpoint implementation #291

Merged
merged 11 commits into from
Apr 25, 2017

Conversation

andrestc
Copy link
Contributor

This adds a client side implementation for fetching label values from prometheus api.

Would love to get some review on this as this is my first contribution here. Some design questions i may have oversimplified:

  1. return a more descriptive value instead of []string? Maybe model.LabelValues?
  2. create a separated interface for metadata api(following the separation on the docs)?

Related to #290.

This commit adds a client side implementation for fetching label values
from prometheus api.
Copy link
Member

@juliusv juliusv left a comment

Choose a reason for hiding this comment

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

Thanks, looks good besides comments!

QueryRange(ctx context.Context, query string, r Range) (model.Value, error)
// QueryLabelValues performs a query for the values of the given label.
QueryLabelValues(ctx context.Context, label string) ([]string, error)
Copy link
Member

Choose a reason for hiding this comment

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

To be more consistent with naming we have elsewhere, maybe omit the Query and just call this LabelValues.

Copy link
Member

Choose a reason for hiding this comment

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

And yeah, this should be model.LabelValues, since we're using the other model types in here as well.


func (h *httpQueryAPI) QueryLabelValues(ctx context.Context, label string) ([]string, error) {
u := h.client.url(epLabelValues, map[string]string{"name": label})
req, _ := http.NewRequest(http.MethodGet, u.String(), nil)
Copy link
Member

Choose a reason for hiding this comment

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

Never ignore returned errors.

@andrestc
Copy link
Contributor Author

andrestc commented Apr 1, 2017

@juliusv, addressed your comments. Thanks for the quick review!

QueryRange(ctx context.Context, query string, r Range) (model.Value, error)
// LabelValues performs a query for the values of the given label.
LabelValues(ctx context.Context, label string) (model.LabelValues, error)
Copy link
Member

Choose a reason for hiding this comment

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

So, I always understood this interface to only include /api/v1/query* endpoints. With that, we'd end up with QueryAPI, LabelsAPI, AlertmanagerAPI, etc. interfaces.

I'd say we should either do that, or rename this interface to something like APIv1 (or a better name). Adding all current v1 functions in a QueryAPI interface doesn't make sense though, as not all are about querying.

Copy link
Member

Choose a reason for hiding this comment

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

Valid concern, and one that we are violating by the page menu hierarchy under which https://prometheus.io/docs/querying/api/ is embedded as well.

I don't like the idea of QueryAPI, LabelsAPI, etc. much, but if we also want to add Alertmanager API functionality here eventually, then maybe Prometheus and Alertmanager? I'm not even sure whether we should keep the ...API suffix. Or alternatively, ...Client instead of ...API.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I guess Prometheus and Alertmanager makes sense since there aren't that many endpoints to justify doing QueryAPI, LabelsAPI etc.

@grobie
Copy link
Member

grobie commented Apr 3, 2017 via email

@juliusv
Copy link
Member

juliusv commented Apr 4, 2017

Yet? ;) Alertmanager is difficult though, as there are alertmanager related endpoints in the Prometheus API and the Alertmanager API itself.

There are alert-related endpoints in Prometheus, but are there Alertmanager-related ones in Prometheus as well?

Agree on versioning, but that should happen for each of {Alertmanager, Prometheus, ...}, as their APIs are versioned separately. Maybe use a package for versioning, like the InfluxDB client does? https://godoc.org/github.com/influxdata/influxdb/client/v2

@grobie
Copy link
Member

grobie commented Apr 4, 2017

Check /api/v1/alertmanagers in https://prometheus.io/docs/querying/api/#alertmanagers. That's what I was referring to above as well, basically either we have one interface per /api/v1/<group> thing, or we only have one per API. An interface called Interface in a prometheus/v1 package describing all functions of the API might be enough for now?

@andrestc
Copy link
Contributor Author

andrestc commented Apr 4, 2017

Looks good... I'm not so sure about the Interface name, maybe name the Interface API on prometheus/v1.

@juliusv
Copy link
Member

juliusv commented Apr 4, 2017

Check /api/v1/alertmanagers in https://prometheus.io/docs/querying/api/#alertmanagers.

That's fine though, it's Prometheus's view of what Alertmanagers there are. It's not "an Alertmanager API", or part of it. It's just part of the Prometheus API. I'd be for prometheus/v1 (grouping all functionality under Prometheus's /api/v1/... endpoints) and alertmanager/vXXX (same for AM) packages. The two binaries are separate components with separate APIs and URLs.

In each package, I would expect an API type that gives access to all the endpoints of one particular binary. The httpClient and maybe even the apiClient wrapper around it could be shared between Prometheus and Alertmanager API packages.

@andrestc
Copy link
Contributor Author

andrestc commented Apr 5, 2017 via email

@grobie
Copy link
Member

grobie commented Apr 11, 2017

Completely cool with that. I don't care about a new PR or continue using this one (but changing the name). Just make sure to use separate commits to first change the package structure and then another one to add your new feature/endpoint.

@juliusv
Copy link
Member

juliusv commented Apr 11, 2017

@andrestc Oh yeah sorry, I meant to reply to this PR saying that we should wait until @grobie is back from his hiking to give him chance to object, but I forgot. Now we know he's fine with it, so go ahead :)

@grobie
Copy link
Member

grobie commented Apr 16, 2017

@andrestc Are you cool with the changes? This should unblock #248 as well.

@andrestc
Copy link
Contributor Author

Yeah! I will update the PR with those, i'll probably have time for that on the next few days

This commit creates a new package to hold the prometheus
v1 API interface. This interface will contain all the funcionality
exposed by Prometheus v1 HTTP API.

The underlying http client is kept on the api package since it
may be reused across diferent API versions and also by the Alertmanager
api package (to come.)
@andrestc
Copy link
Contributor Author

andrestc commented Apr 19, 2017

Hey @juliusv, @grobie. I've pushed some of the changes we discussed.

I've left the http client on a separated package so it can be reused across Prometheus and Alertmanagers APIs(including future versions?).

Once you guys are OK with the changes I can rebase and make sure this last change comes before the label values query change.

Copy link
Member

@grobie grobie left a comment

Choose a reason for hiding this comment

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

Sorry, now you'll get a code review for code you didn't even write.

Looks good in general, due to the changes to the context and http packages, we can greatly simplify the client implementation.

api/client.go Outdated
"strings"
"time"

"golang.org/x/net/context"
Copy link
Member

Choose a reason for hiding this comment

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

The context package has been integrated into the stdlib, let's use that instead.

api/client.go Outdated
"time"

"golang.org/x/net/context"
"golang.org/x/net/context/ctxhttp"
Copy link
Member

Choose a reason for hiding this comment

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

Not longer necessary, the stdlib http package has native support for context now.

api/client.go Outdated

// CancelableTransport is like net.Transport but provides
// per-request cancelation functionality.
type CancelableTransport interface {
Copy link
Member

Choose a reason for hiding this comment

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

Not longer necessary with the new http package. Will also fix #292.

api/client.go Outdated
}

func (c *httpClient) Do(ctx context.Context, req *http.Request) (*http.Response, []byte, error) {
resp, err := ctxhttp.Do(ctx, &http.Client{Transport: c.transport}, req)
Copy link
Member

Choose a reason for hiding this comment

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

I think we'll now have to use context.WithCancel here. I guess we should leave that to the user.

This commit removes the now unnecessary CancelableTransport and rely on
the net/http context support.
@andrestc
Copy link
Contributor Author

@grobie I've addressed your comments by removing the CancelableTransport and by passing down the ctx to the request (should I create a child context?).

We will need to drop go 1.6.x from travis and add go 1.8.x.

@grobie
Copy link
Member

grobie commented Apr 22, 2017

We will need to drop go 1.6.x from travis and add go 1.8.x.

Oh, @beorn7 will need to say if that's actually acceptable as requirement for client_golang users. What's the go1.8 feature? The new context package in stdlib and request.WithCancel() was added in go1.7 I thought?

Copy link
Member

@grobie grobie left a comment

Choose a reason for hiding this comment

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

LGTM

@andrestc
Copy link
Contributor Author

Oh, I said to add go 1.8 just to keep the last two major versions on travis, we are fine on 1.7+.

@beorn7
Copy link
Member

beorn7 commented Apr 22, 2017

@grobie We are talking only about the api package here, which is not widely used (and arguably experimental/unmaintained). the client_galang/prometheus/... packages should still be fine with older Go versions.

@grobie
Copy link
Member

grobie commented Apr 22, 2017 via email

@beorn7
Copy link
Member

beorn7 commented Apr 22, 2017

OK, I see.

Yeah, that would be bad if the tests for an experimental package had an impact on the ones for a production package in frequent use.

Can we use build tags to not run the api tists on older go versions?

@grobie
Copy link
Member

grobie commented Apr 22, 2017 via email

@grobie grobie mentioned this pull request Apr 24, 2017
@grobie grobie changed the title api: adds label values query implementation api: reorganize API package and add label values endpoint implementation Apr 24, 2017
@andrestc
Copy link
Contributor Author

I've pushed the change that includes the build tag to the api package files.

Copy link
Member

@grobie grobie left a comment

Choose a reason for hiding this comment

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

Thanks! One last comment, but looks great!

api/client.go Outdated
// New returns a new Client.
//
// It is safe to use the returned Client from multiple goroutines.
func New(cfg Config) (Client, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Actually I think we should call this NewClient now, as the package is called API but we're not returning a type called api.

@andrestc
Copy link
Contributor Author

Done! @grobie @juliusv

Copy link
Member

@grobie grobie left a comment

Choose a reason for hiding this comment

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

Thank you!

I'll leave it to @juliusv to change his review status and to @beorn7 to merge the PR.

Copy link
Member

@juliusv juliusv left a comment

Choose a reason for hiding this comment

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

Good to go after two last nits :) Thanks!

api/client.go Outdated

// +build go1.7

// Package api provides clients the HTTP API's.
Copy link
Member

Choose a reason for hiding this comment

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

API's -> APIs

clients the -> clients for the

@@ -234,6 +70,16 @@ type Range struct {
Step time.Duration
}

// API provides bindings the Prometheus's v1 API.
Copy link
Member

Choose a reason for hiding this comment

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

bindings the -> bindings for

@andrestc
Copy link
Contributor Author

Done, @juliusv

@juliusv
Copy link
Member

juliusv commented Apr 25, 2017

Thanks!

@juliusv juliusv merged commit 7d94842 into prometheus:master Apr 25, 2017
@tboerger
Copy link

tboerger commented May 9, 2017

The build tag prevents the usage with go 1.8 :(

@grobie
Copy link
Member

grobie commented May 9, 2017

@tboerger Are you sure that's the problem? The documentation explicitly states - "go1.7", from Go version 1.7 onward https://golang.org/pkg/go/build/.

@tboerger
Copy link

tboerger commented May 9, 2017

I have created #298 now to allow go 1.8 as well.

@andrestc andrestc deleted the query-label-values branch July 31, 2017 18:28
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.

5 participants