Conversation
Codecov Report
@@ Coverage Diff @@
## master #557 +/- ##
============================================
- Coverage 63.7% 63.03% -0.68%
Complexity 68 68
============================================
Files 189 182 -7
Lines 7431 6836 -595
Branches 871 786 -85
============================================
- Hits 4734 4309 -425
+ Misses 2433 2264 -169
+ Partials 264 263 -1
Continue to review full report at Codecov.
|
...vlet-plugin/src/main/java/co/elastic/apm/agent/servlet/RequestDispatcherInstrumentation.java
Outdated
Show resolved
Hide resolved
...c/main/java/co/elastic/apm/agent/servlet/ForwardIncludeRequestDispatcherInstrumentation.java
Outdated
Show resolved
Hide resolved
...c/main/java/co/elastic/apm/agent/servlet/ForwardIncludeRequestDispatcherInstrumentation.java
Outdated
Show resolved
Hide resolved
...c/main/java/co/elastic/apm/agent/servlet/ForwardIncludeRequestDispatcherInstrumentation.java
Show resolved
Hide resolved
...ent-plugins/apm-servlet-plugin/src/test/java/co/elastic/apm/agent/servlet/ApmFilterTest.java
Outdated
Show resolved
Hide resolved
...c/main/java/co/elastic/apm/agent/servlet/ForwardIncludeRequestDispatcherInstrumentation.java
Show resolved
Hide resolved
...c/main/java/co/elastic/apm/agent/servlet/ForwardIncludeRequestDispatcherInstrumentation.java
Outdated
Show resolved
Hide resolved
...vlet-plugin/src/main/java/co/elastic/apm/agent/servlet/RequestDispatcherInstrumentation.java
Outdated
Show resolved
Hide resolved
...s/application-server-integration-tests/src/test/java/co/elastic/apm/servlet/WebSphereIT.java
Outdated
Show resolved
Hide resolved
...c/main/java/co/elastic/apm/agent/servlet/ForwardIncludeRequestDispatcherInstrumentation.java
Outdated
Show resolved
Hide resolved
|
@felixbarny please check pull request, i deleted instrumentation on RequestDispatcher. |
| String pathInfo = ""; | ||
|
|
||
| if (FORWARD.equalsIgnoreCase(method)) { | ||
| servletPath = (String) httpServletRequest.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH); |
There was a problem hiding this comment.
Didn't you say these properties are not set yet? Or are they only set on the real application servers but were not on the unit tests?
There was a problem hiding this comment.
I tested with Apache Tomcat Version 8.5.5, and those properties were not there.
They were not on the unit tests, too.
I don't know, if I should instrument RequestDispatcher .
There was a problem hiding this comment.
I think there was a confusion here- the attribute RequestDispatcher.FORWARD_SERVLET_PATH provides the servlet path of the original request in the new request created in the new forwarded/included request, but here we are interested in the new request paths. So maybe we can create and activate the span here but set it only when the next service will run simply through HttpServletRequest#getServletPath and HttpServletRequest#getPathInfo.
...n-server-integration-tests/src/test/java/co/elastic/apm/servlet/tests/ServletApiTestApp.java
Show resolved
Hide resolved
|
Some ideas about alternatives which enable the capturing of the path:
Another option is to just omit the path (the current state of the PR). @kananindzya @eyalkoren WDYT? |
eyalkoren
left a comment
There was a problem hiding this comment.
Thanks for your great contribution!
A few comments, mainly about the span naming that seems to include the original path, but we probably prefer using the forwarded/included servlet path and path info.
Also, some notes about start/end and activate/deactivate maintenance.
Without regard, I know you already know our code quite well, but did you see https://www.elastic.co/blog/a-cookbook-for-contributing-a-plugin-to-the-elastic-apm-java-agent? Maybe this can be informative even for you 🙂.
...c/main/java/co/elastic/apm/agent/servlet/ForwardIncludeRequestDispatcherInstrumentation.java
Show resolved
Hide resolved
| if (parent instanceof AbstractSpan) { | ||
| AbstractSpan parentSpan = (AbstractSpan) parent; | ||
| if (parentSpan.getName().toString().equals(span.getName().toString())) { | ||
| return; |
There was a problem hiding this comment.
This is too late- the span is already created and started, just not activated.
This check needs to be done at the beginning of the method, before span creation and start. Then you will have to avoid object allocation for the string creation, so you could use a ThreadLocal StringBuilder for example, or check whether parent span's name contains the pathInfo and servletPath.
@felixbarny do you think scenarios of multiple forwards/includes for same path and servlet are a valid concern?
There was a problem hiding this comment.
Good question. I don't really know. Theoretically, that could happen, although not very likely.
|
|
||
| public class ForwardIncludeRequestDispatcherInstrumentation extends ElasticApmInstrumentation { | ||
|
|
||
| private static final String SPAN_TYPE = "servlet"; |
There was a problem hiding this comment.
@felixbarny the type servlet seems right here, but I wonder if it is a good fit in the overall APM context. All the other span main types are such that we try to keep somewhat aligned between agents and with limited cardinality. I would say sub-type is better to use for Java-specific term, but not sure which major span type is a good fit instead. Any idea?
There was a problem hiding this comment.
I think app might be a good type. For breakdown graphs, the transaction's self-time will also be attributed as app and it's also the default type for the @CaptureSpan annotation.
| } | ||
| } | ||
|
|
||
| span.activate(); |
There was a problem hiding this comment.
If the span is started, it should be activated as well
| @Advice.Thrown @Nullable Throwable t) { | ||
| if (span != null) { | ||
| span.captureException(t) | ||
| .deactivate() |
There was a problem hiding this comment.
This may cause deactivation of non-activated span, which should always be checked against and avoided. I think the code of this method should remain, and the proper way to ensure span activation state correctness is making sure it's either null or non-null-and-activated in beforeExecute
...c/main/java/co/elastic/apm/agent/servlet/ForwardIncludeRequestDispatcherInstrumentation.java
Show resolved
Hide resolved
...c/main/java/co/elastic/apm/agent/servlet/ForwardIncludeRequestDispatcherInstrumentation.java
Show resolved
Hide resolved
| String pathInfo = ""; | ||
|
|
||
| if (FORWARD.equalsIgnoreCase(method)) { | ||
| servletPath = (String) httpServletRequest.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH); |
There was a problem hiding this comment.
I think there was a confusion here- the attribute RequestDispatcher.FORWARD_SERVLET_PATH provides the servlet path of the original request in the new request created in the new forwarded/included request, but here we are interested in the new request paths. So maybe we can create and activate the span here but set it only when the next service will run simply through HttpServletRequest#getServletPath and HttpServletRequest#getPathInfo.
...n-server-integration-tests/src/test/java/co/elastic/apm/servlet/tests/ServletApiTestApp.java
Show resolved
Hide resolved
|
@felixbarny I just saw your comment now. What I thought when reviewing was to create the span as it is created now in this PR with the basic name only, but update its name in the However,
may actually be a better option - you mean that we rely on the
I don't think so. Seems pretty straightforward. |
No, I meant relying on But that can easily become messy - especially when there's a filter chain which may or may not invoke the target servlet and taking into account that there may be multiple forwards/includes. |
|
@kananindzya So let's do this: On method enter and exit, add a WDYT? |
|
@kananindzya we would like to implement that based on the logic described in the last comment. |
closes #384