-
Notifications
You must be signed in to change notification settings - Fork 840
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
proxy timings#1717
proxy timings #1717
Conversation
5703a0f
to
cc3ae87
Compare
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.
Thank you for working on this. I like the general approach proposed by the PR.
IIRC, the outcome of our discussion was that we will simply emit timing information of the upstream side (i.e. h2o acting as a client), rather than trying to build a generic framework to handle timing information. However, I see some part of the code trying to provide abstraction that seems to contradict with the decision.
Could you please clarify why they are necessary?
include/h2o.h
Outdated
*/ | ||
struct { | ||
h2o_proxy_log_data_t *proxy; | ||
} handler_log_data; |
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.
Two questions here:
- does
proxy
need to be a pointer? - do we need to wrap
h2o_proxy_log_data_t
with a struct namedhandler_log_data
? I'd assume that the timing information we will be logging directly in h2o to be i) when the information is sent to the client and ii) when the information is generated by the generator. If my assumption is true, then we will have nothing other thanproxy
.
include/h2o/http1client.h
Outdated
uint64_t request_end_at; | ||
uint64_t response_start_at; | ||
uint64_t response_end_at; | ||
} h2o_http1client_timings_t; |
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.
LGTM.
lib/core/logconf.c
Outdated
LAST_ELEMENT()->data.handler_cb = cb; | ||
goto MAP_EXT_Found; | ||
} | ||
|
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.
Can't we simply add ELEMENT_TYPE_PROXY_PROCESS_TIME
etc. due to the same reason stated above?
Thank you for your comment. As you said I added a little abstraction because
|
Thank you for the answer. The problem as I see is that the abstraction is incomplete. For example, existence of handler-specific type (i.e. I also wonder it would be the right approach to let the handler define a dedicated callback for each log specifier would be the right approach for a genenic mechanism. For example, you might want to generate an arbitrary-named property in the mruby handler. But you cannot dynamically create a callback that binds to the named property. In other words, I am backwards against trying to design a framework at the moment when there is no clear need for one. |
I agree, it's sort of like result of compromise. I don't have objection to removing
In such a case, for example, mruby handler can catch |
@kazuho I addressed the issues and add tests. |
include/h2o.h
Outdated
/** | ||
* proxy log data | ||
*/ | ||
h2o_http1client_timings_t *proxy_timings; |
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.
Thank you for the changes.
How about adding h2o_http1client_timings_t
(not a pointer) as a member of h2o_req_t::timestamps
?
By doing so, I believe that we can drastically reduce the changes. For example, there would be no need for new functions like h2o_proxy_time_compute_...
. All we need to do in core is to support new variables in logconf.c.
@kazuho Thank you for your comment. I addressed the issues. |
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.
Thank you for the changes. Aside from the comment below I think that the code is ready for merge.
lib/core/util.c
Outdated
DELIMITER ELEMENT_LONGEST_STR("process") DELIMITER ELEMENT_LONGEST_STR("proxy-idle") \ | ||
DELIMITER ELEMENT_LONGEST_STR("proxy-connect") DELIMITER ELEMENT_LONGEST_STR("proxy-request-header") \ | ||
DELIMITER ELEMENT_LONGEST_STR("proxy-request-body") DELIMITER ELEMENT_LONGEST_STR("proxy-request-total") \ | ||
DELIMITER ELEMENT_LONGEST_STR("proxy-first-byte") |
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.
Do these field names match those that are actually being emitted?
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.
lib/core/util.c
Outdated
prefix_len + suffix_len + sizeof(ELEMENT_LONGEST_STR(response) DELIMITER ELEMENT_LONGEST_STR(total))); | ||
value.base = h2o_mem_alloc_pool(&req->pool, *value.base, | ||
prefix_len + suffix_len + | ||
sizeof(ELEMENT_LONGEST_STR("response") DELIMITER ELEMENT_LONGEST_STR("total"))); |
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.
Do we have enough space here now that we might also be sending timings for proxy-response and proxy-total?
Thank you for the changes. Merged to master. |
Add a logging feature to log access timings to upstream servers
%{proxy-idle-time}x
%{proxy-connect-time}x
%{proxy-request-header-time}x
%{proxy-request-body-time}x
%{proxy-request-total-time}x
%{proxy-first-byte-time}x
%{proxy-response-time}x
%{proxy-total-time}x
TODO: