-
Notifications
You must be signed in to change notification settings - Fork 992
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
Initial Jetty 12 server support #4753
Initial Jetty 12 server support #4753
Conversation
@joakime Please sign the Contributor License Agreement! Click here to manually synchronize the status of this Pull Request. See the FAQ for frequently asked questions. |
@joakime Thank you for signing the Contributor License Agreement! |
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 pull request. I was looking at the existing TimedHandler for Jetty 11 and see it has logic to support async requests. I didn't notice anything for async in this pull request. Does it not support instrumenting async requests?
The build failure is due to the build trying to check for API compatibility in the previous version but there is no previous version of micrometer-jetty12
. You can add micrometer-jetty12
to here so this check is skipped:
Line 340 in c69180d
if (!(project.name in ['micrometer-jakarta9', 'micrometer-java11'])) { // add projects here that do not exist in the previous minor so should be excluded from japicmp |
Async requests is a Servlet concept. Starting in Jetty 12, the core level behaviors no longer use Servlet. If you want to instrument Async, then a unique micrometer layer for each Environment would need to be created.
This means the following artifacts ..
Or if micrometer already has a
Thanks, that failure was unclear. |
@shakuzen JettyStatisticsMetrics had "jetty.responses" among other stats. TimedHandler for jetty 11 and below does not have it anymore. Any particular reason why it was removed? It would be nice to have those statistics back (among other stats that can be translated from jetty's StatisticsHandler) I'm open to contribute code either under this PR or a new one to bring back stats that were available in JettyStatisticsMetrics. Thanks. |
Here's the events that we could build against.
From these we can show ..
|
And for jetty.responses, we can aggregate status codes in onResponseBegin similar to StatisticsHandler: |
These are Jetty core specific. "jetty.requests", "Request duration" Note that "Request duration" is imprecise and vague. Also "jetty.responses.size" is highly dependent on where the StatisticsHandler is in the handler tree. The following are Servlet specific and would be numbers that would be isolated to each Environment that supports Servlet. "jetty.dispatched", "Dispatch duration" Also of note, we are working on Cross Context Dispatch support at the moment, each of those will be counted as a nested request/response. |
Regarding EE statistics. Yes they should be servlet specific. |
Because the TimedHandler has the same information and more in @wojtassi could you be more specific about what is missing? It's wasteful to have multiple metrics for the same thing coming from different sources (TimedHandler and StatisticsHandler). As explained above,
That's already done in |
@joakime We do have instrumentation for async now, so not including it is offering less instrumentation than we had with Jetty 11, but due to the restructuring, it's unavoidable I suppose. I think my biggest concern, though, is that the instrumentation in this pull request doesn't break (or leak things) when the request Jetty core receives is an async request from a servlet environment. Or will the instrumentation in this pull request not even be called when handling an async request in a servlet on Jetty? |
For async, you would need a new handler that is unique for each environment. Those can exist entirely independently from the Jetty Core TimedHandler in this PR and collect different metrics into the registry. If you choose to use a servlet level handler, it's metrics would not depend on the TimedHandler metrics you see in this PR. There are a growing number of projects that use Jetty 12 core exclusively, with no Servlets at all. Keep in mind that Async on servlet was entirely optional, even back in Jetty 9 thru Jetty 11 days. Also the original assumption that things are either blocking or async was bad as well. InputStream input = Content.Source.asInputStream(request); Or they want to use reactive like APIs for the request. Flow.Publisher<Chunk> publisher = Content.Source.asPublisher(request); This is just a small handful of the ways the user can choose to read from the request, or write to the response. When the request reaches a Servlet environment, the Async processing is unique for that one environment and one handling. Note: things like servlet async timeouts happen entirely within that environment, and core has no knowledge of this layer's chosen threading or behaviors. One thing to also consider, if the handling (even servlet) results in one (or more) rehandles (eg request dispatching) back into the handler tree, each of those can be on core and/or an environment (even different ones) and using any of the above read/write techniques - plain content.source, plain content.sink, inputstream, outputstream, channels, flow api, servlet api (and blocking and asynccontext within that), etc.. This also means each sub-request is another request in your metrics. The rehandle and subsequent TimedHandler handle would have no way to identify what state the previous request handling was in (eg: down in the environment), only the handlers down at the environment would have that information, and they would be blind to any actions happening in another environment (or core). There are 2 things this PR does.
|
Thanks for the explanation @joakime. Let's separate out the servlet async instrumentation as an enhancement outside the scope of this pull request. We'll wait to hear from users about the need for it before we prioritize that work. With that, I think this pull request is good to go. I just have a few polishing things I can deal with when merging. One long-standing gap we've had between our Jetty server instrumentation and other web server instrumentation is lack of ability to tag with low cardinality URIs. It doesn't need to be addressed for this pull request because this is the status quo. But I figured while I have you here, if you have any ideas to tag some info about the URI to better identify request metrics while avoiding cardinality explosion, we'd love to hear. With Jersey or Spring WebMVC/WebFlux we're relying on URI patterns/templates that have path variables to avoid cardinality explosion. As far as I understand, such a concept in Jetty server (beside context paths?) is up to user's custom handler logic. I looked through the docs but only saw URI templates mentioned in the WebSocket section. |
If you choose to use the PathMappingsHandler, you can map an incoming path to a specific Handler using any PathSpec implementation (we ship with ServletPathSpec, RegexPathSpec, and UriTemplatePathSpec) This is available on Jetty 12 core. |
Thanks for the explanation.
My bad. I didn't realize that responses are now part of jetty.server.request. Once I dived into the implementation, I can see how it is done in TimedHandler. In my case, a reason for using jetty.responses would be backward compatibility to dashboards and alarms that expect jetty.responses but since jetty.responses (as part of JettyStatisticsMetrics) was depreciated, its on me (and not micrometer) to make it work. |
We are mindful of backward compatibility, and that's why |
This is pretty much our plan. Use custom JettyStatisticsMetrics that uses Jetty's StatisticsHandler for now (Basically we need to support Jetty 12 and cannot wait until May). Once this PR is merged and released in May, add TimedHandler in parallel to JettyStatisticsMetrics. Switch over our dashboards and alarms and eventually remove JettyStatisticsMetrics. As far as making migration easier, I don't think you could have done anything different since JettyStatisticsHandler was depreciated 4 years ago so it is on us for not replacing it sooner. |
Makes the Jetty server dependency optional. We plan to add Jetty client instrumentation and users may be use only one or the other, so micrometer-jetty12 should not pull in both dependencies. It will be up to users to separately have a dependency on Jetty server or client. Updated copyright years and since tags. Removed incubating annotations.
This is a first implementation of Jetty 12 integration with the Jetty core layer (no servlets, as those only exists in the environments).
Fixes: #4261