-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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 client doesn't support POST method for Query/QueryRange #428
Comments
What about a fourth option: the user intent is already clear (query a given PromQL expression with a given time range), so can we just either determine automatically whether we need GET or POST (from some maximum length that GET args can have?), or alternatively always use POST? |
(the one thing against always using POST is that POST support was only introduced <1y ago, so probably some auto-detection would be best that just goes to POST for long queries) |
I think that's a great idea. How about I add an option to the client Config which is MaxHeaderSize, if that is set it'll switch to POST for queries that would be larger. That way if you don't define the max size in the config, it will always do GET. This also means the interface can remain the same. |
Is it the HTTP headers in total that are size-limited, or the URL (that contains GET parameters) specifically? |
the HTTP headers themselves. I looked into adding it there, but the issue is that the client.Config struct isn't exposed to the API client since it takes a |
I want to understand this better. prometheus/prometheus#3072 was about URL size limits, not about HTTP headers in general. Browsers have URL size limits (like https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers), but here already the client is not a browser anymore, but a Go HTTP client. So we only ever need to switch to POST in case there are also size limitations in either the Go HTTP client (used in this client lib) or in the Go HTTP server (used by the Prometheus server that handles the requests generated here). I just tried it out and I only seem to be hitting a limit (that causes a connection reset by peer) around the 1MB URL size, which I don't expect any PromQL query to ever hit. So maybe we actually never need to use Of course there might also be HTTP proxies in the middle, but not sure what the common URL size limits are on those... |
The issue reported was about browser limits, but those don't apply too much to this client interface since we are talking from go. In this case the main limitation is the server itself. Go's server struct has an option called Assuming this is still something we want, I think having an option for setting a limit and then having the client work around that limit would be good. That way if you do have proxies in the middle we can swap to using POST etc. |
I'm just unsure about the situation where an older server doesn't support POST yet and the client lib still switches to it because the query size is too large. It would result in a |
Thanks, @juliusv for chiming in. Assigning this to @krasi-georgiev as per https://github.com/prometheus/client_golang/blob/master/MAINTAINERS.md for shepherding. |
This is why I'd leave the default config option for |
I don't think it'd be unreasonable to make the client lib explicitly aware of the version of the Prometheus server on the other side. The API user will have to know the Prometheus version in any case to make use of the new It's a question of how high- or low-level we want this control knob to be, and whether we'll want to do more future version-dependent switches. From the user's perspective, which explanation would be more straightforward: how But honestly, I would love to hear someone else's opinion on this too. |
I prefer the more direct control (in this case the MaxHeaderBytes). The main reason being we don't know how they'll use the client. For example, if they where to talk to prom behind some proxy they'd need to set their own header limit which is independent of the prom version. I'm also fine to get some other opinions in here, but to me it seems that we at lest want this option. IMO if we're going down the route of differing the client based on version we may want to create separate interfaces for that -- as APIs come and go across prom versions (instead of a single API interface, have the various sub-versions). |
what about using compatbility matrix , similar to the k8s client |
so nothing special in code , just always use post and in the readme mention that client version 0.9.1 and above works with prometheus version .... |
That would work assuming the maintainers are okay with managing N versions for support, otherwise this client will immediately kick off anyone <2.2 (and similarly for other changes in the future). That is really a question of what the support and compatibility guarantees are on this library. |
I don't think anyone here is up for managing client library versions to that degree and so I think just dropping support for older 2.x Proms in newer versions of this library is definitely not a good idea. The case about proxy servers requiring a smaller |
I see what you mean. Basically if there is a bug in the client lib and the user is still using a Prom version that doesn't support POST we would need to backport the fix. I agree that few more if statements based on provided Prom version to the client would require least maintenance. @jacksontj I am happy to review a PR if you have the time. |
My thinking would be that the default of this off stays GETs forever, and we document that setting this option will only work for prom v2.x and up. So by you the client setting that option you are saying you are at least that version. This seems like the least maintenance to me, especially since the difference goes away after prom 1.x support is dropped. If we want to add switching based on the prom version, the idea is that we'd unconditionally do GET/POST based soely on the version? |
How about using POST and falling back to GET if we get that the method isn't supported? |
that is a good idea as well. |
POST first and GET as fallback sounds good to me too, slight preference from my side to do it unconditionally, then we don't even need the |
Any progress on this issue? |
Assigning to @krasi-georgiev for tracking. |
Happy to review a PR , but don't think I will have time to do the actual implementation so contributions are welcome. |
@jacksontj Any chance for a PR? I think we have a pretty good plan for action here so I can review it quickly. |
Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com> Fixes prometheus#428
Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com> Fixes prometheus#428
Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com> Fixes prometheus#428
Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com> Fixes prometheus#428
Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com> Fixes prometheus#428
Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com> Fixes prometheus#428
Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com> Fixes prometheus#428
Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com> Fixes prometheus#428
Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com> Fixes prometheus#428
The upstream prometheus HTTP API supports POSTS for these methods (the same as Query and QueryRange). Similar to the original issue (prometheus#428) we can hit 414 errors with these other APIs. This change simply duplicates the logic to these other endpoints Related to: jacksontj/promxy#588 Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com>
The upstream prometheus HTTP API supports POSTS for these methods (the same as Query and QueryRange). Similar to the original issue (prometheus#428) we can hit 414 errors with these other APIs. This change simply duplicates the logic to these other endpoints
…lback (#1252) The upstream prometheus HTTP API supports POSTS for these methods (the same as Query and QueryRange). Similar to the original issue (#428) we can hit 414 errors with these other APIs. This change simply duplicates the logic to these other endpoints Related to: jacksontj/promxy#588 Signed-off-by: Thomas Jackson <jacksontj.89@gmail.com>
POST support was added to query/query_range API endpoints in prometheus with prometheus/prometheus#3322. This client currently only sends GET requests, which means that it isn't won't work for large query string values. As the API stands today:
There isn't really a place to put it, so I see a couple options:
NewPOSTAPI
method to return anhttpAPI
instance with a flag to use POST for both query and query_range (this would be done by setting an option in thehttpAPI
struct-- to be added).METHOD
argument to Query and QueryRangeI'm not sure what the compatibility guarantees are on this client interface, so I'm not sure how we want to proceed. I'm leaning towards 1 or 2 (probably in that order)
cc @juliusv
The text was updated successfully, but these errors were encountered: