-
Notifications
You must be signed in to change notification settings - Fork 149
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
Improve rack middlewares #32
Conversation
def init_request_metrics | ||
@requests = @registry.counter( | ||
:http_server_requests_total, | ||
'The total number of HTTP requests handled by the Rack application.', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's from rack, then the metric name should contain "rack"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rack is the de facto standard interface for ruby HTTP servers. It can be implemented by many different servers (unicorn, thin, puma, ...). I thought about including it, but concluded after some discussions that including it in the metric name is neither expected nor helpful.
Thanks a lot for improving the Rack middleware. As a novice Prometheus user providing data from a Rack app, it was nice to see a middleware. As I got it up and presenting data, I later learned that the "summary" metric was wrong for what we'd tried to use it for. We now find ourselves in the wrong column of table "Histogram vs Summary". Can we move this forward in any way? Are all of the understanding-improving/renaming comments blocking a merge? |
That, but mostly it's me traveling for the last couple of months. I'll have
some time between Christmas and new year's and it's on my list to get this
rolling again.
…On Tue, Dec 20, 2016, 06:37 Olle Jonsson ***@***.***> wrote:
Thanks a lot for improving the Rack middleware.
As a novice Prometheus user providing data from a Rack app, it was nice to
see a middleware.
As I got it up and presenting data, I later learned that the "summary"
metric was wrong for what we'd tried to use it for. We now find ourselves
in the wrong column of table "Histogram vs Summary"
<https://prometheus.io/docs/practices/histograms/#quantiles>.
Can we move this forward in any way? Are all of the
understanding-improving/renaming comments blocking a merge?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#32 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAANaMMyMQWpyK8Ce5uCHmYMXEjV7WA5ks5rJ8v6gaJpZM4J5bUy>
.
|
@grobie - any updates on this one? |
I've been traveling in the Amazon jungle for the last few weeks, but will have more internet connections during the next couple of days. I'll try to pick this up again. |
271d793
to
26b229e
Compare
2 similar comments
26b229e
to
2caa1bf
Compare
3 similar comments
2caa1bf
to
ac14e38
Compare
3 similar comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright, I finally addressed almost all of the feedback. The only outstanding issues is how to handle the response code label.
The term request
is pretty overloaded and I always understood it to describe here the full cycle of a HTTP request and response. For example the latency metric measures the full round-trip and not just the time until the request reaches a server (which would be very hard to define anyway).
It's a very common need to have a metric broken out by request method, path and response code. Neither http_request_...
nor http_response_...
metrics would include all three. I'm open to suggestions, but the current approach seems to be the best option IMHO.
As these metrics were implemented based on client_golang
, I'd like to get @beorn7's and @juliusv's input as well.
ac14e38
to
9e03c52
Compare
The metrics generated by the included HTTP tracer would look like this:
|
And still it's commonly understood that a statement "The request latency was 400ms" includes both the time to sent a HTTP request and receive a HTTP response without the need to say something like "The request and response latency was ...".
As commented earlier, I had already dropped the code label from the latency histogram. Following your argumentation, a I understand the naming isn't perfect and remember the same discussion with Matt years ago. Considering the colloquial use of the term Are there other committers voting to change the naming? @beorn7 @juliusv |
The naming used by https://godoc.org/github.com/prometheus/client_golang/prometheus#InstrumentHandler in client_golang should not serve as a role model in any way. It's strongly deprecated (and coming up with a replacement that doesn't immediately run into similar or other problems turns out to be hard). The problem with the metric name
Thus, the name should include some kind of subsystem. (In this case, perhaps The discussion around |
While I've heard about the |
Regarding the inclusion of
That's the reason this PR changes the metric names from
Rack is really just an interface definition and not an implementation in its own. Literally every ruby server uses rack these days, so that servers (unicorn, thin, ...), frameworks (sinatra, rails, ...) and plugins (rack middlewares) can be freely used together. It does not provide any additional information to include |
The reasoning about the name appears sound to me. However, it also proves how difficult generic naming is. My current plan for the HTTP instrumentation helpers in client_golang is to always let the user provide a name, without default. But as said, we are still in exploration state there. |
They are not independent. The response means nothing without the request, and the request has no result without the response. In an ideal nanoservice world, where each binary does exactly one thing, the responses may make sense without further context, but out here in the real world we need the response breakdown by (method,path,status). We actively graph and alert this, as otherwise high-volume low-value endpoints swamp out signal from low-volume high-value ones. Consider a CRUD service – if the R request rate is 1000x the CUD rate (not uncommon in consumer websites cough), and a 0.1% error rate on reads is acceptable, it is impossible to detect a completely failing C/U/D endpoint without method and path. |
In order to unblock this PR, I'd ask for a vote how to proceed here. Arguments against and for Summary of the changes in this PR:
The newly generated metrics look like this:
Please vote with 👍 / 👎 if you agree with these changes. @brian-brazil @beorn7 @juliusv @matthiasr |
👍 |
Slightly different note: We often use |
I'm totally in favor of using the more common one. Will change!
…On Tue, Feb 21, 2017, 09:15 Björn Rabenstein ***@***.***> wrote:
Slightly different note: We often use …_duration_seconds instead of
…_latency_seconds. I would prefer if one was used consistently (or there
are rules when to use what). Does anybody have thoughts about this?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#32 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAANaAmtzN9p5EdjsqRQpt63dD14XGnDks5reuNkgaJpZM4J5bUy>
.
|
But is |
I don't think there's a clear convention there, I'd say follow whatever the Go client has. |
As of now, the Go client has |
9e03c52
to
43f01b1
Compare
Ok, I changed latency to duration. |
* Move from prometheus/client/rack/* to rack/middleware/* * Use histogram instead of summary in collector middleware * Spepicfy collector metrics by changing the prefix to http_server_* * Remove HTTP Host header from default label builder
3 similar comments
👍 from a pure "how the metrics look like" perspective. |
|
||
def call(env) | ||
if env['PATH_INFO'] == @path | ||
format = negotiate(env['HTTP_ACCEPT'], @acceptable) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it will be more efficient to fetch a key from env
, like env.fetch('HTTP_ACCEPT', '')
and assume that in negotiate
method we will always get a string in accept
argument.
Then we can improve negotiate
method and replace accept.to_s.empty?
on accept.empty?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the idea to set default value here, but it can also be a strategy – always provide accept
argument, then it could be env.fetch('HTTP_ACCEPT', '*/*')
or something like env.fetch('HTTP_ACCEPT', DEFAULT_HTTP_ACCEPT)
, but I'm afraid then it will shift responsibilities of negotiation a bit here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@grobie copy, I hope that I will have a chance to contribute more in next few months 👍
end | ||
|
||
def parse(header) | ||
header.to_s.split(/\s*,\s*/).map do |type| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is used only by negotiate
and we will never pass header
as non-string value, so we can omit to_s
here
43f01b1
to
5c38163
Compare
Fixes #27.
@tmc and @mikeurbach as users of the library.
@brian-brazil for comments on the default metrics names and help strings.
I was thinking about removing
http_server_requests_total
as it's included in the histogram, but I've seen beginners to be heavily confused usinghttp_server_request_latency_seconds_count
as counter. I guess it's not too harmful.