issue-557 added automatically span creation for DispatcherTypes: FORWARD, INCLUDE, ERROR#1212
Conversation
9dfa4cc to
e33b14d
Compare
|
|
with last fix, now I have problem with |
|
@felixbarny, I noticed that for some Jetty application container span of DispatcherType.ERROR created, but for example websphere, widlfy, tomcat - not. |
722d42a to
99a0789
Compare
|
when we call |
6eef95e to
db73c87
Compare
|
Sometimes spans from one test can leak to another test. Not sure what the best solution for that is. Maybe to make sure to wait until all expected spans have arrived in each test so that they can't leak into others. |
0894c24 to
ede2933
Compare
eyalkoren
left a comment
There was a problem hiding this comment.
Awesome job!
Please see the few comments.
Thanks!
| String spanAction = null, spanName = null; | ||
| if (dispatcherType == DispatcherType.FORWARD) { | ||
| String pathInfo = request.getPathInfo(); | ||
| spanName = FORWARD + SPACE + request.getServletPath() + (pathInfo != null ? pathInfo : EMPTY); |
There was a problem hiding this comment.
This is allocating four String objects every time. Please use the AbstractSpan#appendToName() API instead (create it before).
Same for the other ones.
There was a problem hiding this comment.
repalced with appendToName
| servletTransactionHelper.fillRequestContext(transaction, request.getProtocol(), request.getMethod(), request.isSecure(), | ||
| request.getScheme(), request.getServerName(), request.getServerPort(), request.getRequestURI(), request.getQueryString(), | ||
| request.getRemoteAddr(), request.getHeader("Content-Type")); | ||
| } else if (transaction == null && servletRequest instanceof HttpServletRequest) { |
There was a problem hiding this comment.
This else statement looks misplaced. Its content should go inside the if above and you can do else with the servletRequest.getDispatcherType() == DispatcherType.REQUEST check.
| spanAction = INCLUDE_SPAN_ACTION; | ||
| isAllowedType = true; | ||
| } else if (dispatcherType == DispatcherType.ERROR) { | ||
| spanName = ERROR + SPACE + request.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH); |
There was a problem hiding this comment.
Why using RequestDispatcher.FORWARD_SERVLET_PATH in this case? I think we want the error page path. The transaction will contain the original servlet path.
There was a problem hiding this comment.
changed to getting
Object servletPath = request.getServletPath();
| } else if (dispatcherType == DispatcherType.ERROR) { | ||
| spanName = ERROR + SPACE + request.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH); | ||
| spanAction = ERROR_SPAN_ACTION; | ||
| isAllowedType = true; |
There was a problem hiding this comment.
Please check if you already get the Exception object stored in the RequestDispatcher.ERROR_EXCEPTION attribute somewhere else. If not, let's create and send an error here with captureException through the parent span.
| for (JsonNode span : test.getReportedSpans()) { | ||
| String spanType = span.get("type").textValue(); | ||
| if ("servlet.request-dispatcher.forward".equals(spanType)) { | ||
| isExistForwardSpan = true; | ||
| assertThat(span.get("name").textValue()).isEqualTo("FORWARD /servlet"); | ||
| } else if ("db.h2.query".equals(spanType)) { | ||
| isExistDbH2QuerySpan = true; | ||
| } | ||
| } |
There was a problem hiding this comment.
You need to assert that exactly the expected spans are captured. Potentially, this can pass if two non-related spans are captured.
You can filter the span collection for each and assert you get exactly one that contains the required info.
There was a problem hiding this comment.
added filter before assert.
...-plugins/apm-servlet-plugin/src/main/java/co/elastic/apm/agent/servlet/ServletApiAdvice.java
Outdated
Show resolved
Hide resolved
| servletTransactionHelper.fillRequestContext(transaction, request.getProtocol(), request.getMethod(), request.isSecure(), | ||
| request.getScheme(), request.getServerName(), request.getServerPort(), request.getRequestURI(), request.getQueryString(), | ||
| request.getRemoteAddr(), request.getHeader("Content-Type")); | ||
| } else if (transaction == null) { |
There was a problem hiding this comment.
Why is the transaction == null required here? Seems it will always be null
There was a problem hiding this comment.
i changed here condition to ->
servletRequest.getDispatcherType() != DispatcherType.ASYNC
...-plugins/apm-servlet-plugin/src/main/java/co/elastic/apm/agent/servlet/ServletApiAdvice.java
Outdated
Show resolved
Hide resolved
| boolean isSpannableDispatcherType = false; | ||
| span = parent.createSpan() | ||
| .withType(SPAN_TYPE) | ||
| .withSubtype(SPAN_SUBTYPE); |
There was a problem hiding this comment.
Do not create a span unless you know we need one. Currently these spans can leak. You must always end a span you created, like you must always deactivate a span you activated (which you did).
In rare cases (this is not one), you may create a span and then requestDiscarding it, but you still must end it.
| span.withAction(ERROR_SPAN_ACTION); | ||
| isSpannableDispatcherType = true; | ||
| } | ||
| if (isSpannableDispatcherType && !parent.getNameAsString().equals(span.getNameAsString())) { |
There was a problem hiding this comment.
getNameAsString is allocating a String objects (so two in this comparison).
There are better ways to avoid creation of same nested spans. For example, before creating a span, see if the parent span has the same type, subtype and action.
What cases are you trying to prevent with this comparison?
…ARD, INCLUDE, ERROR minor fixes with creating span that has same names added path info for span name of FORWARD, INCLUDE dispatcher types. delete testTransactionReportingWithErrorHandling test Update apm-agent-plugins/apm-servlet-plugin/src/main/java/co/elastic/apm/agent/servlet/ServletApiAdvice.java Co-authored-by: eyalkoren <41850454+eyalkoren@users.noreply.github.com> Update apm-agent-plugins/apm-servlet-plugin/src/main/java/co/elastic/apm/agent/servlet/ServletApiAdvice.java Co-authored-by: eyalkoren <41850454+eyalkoren@users.noreply.github.com>
b5267a3 to
e77603e
Compare
|
@kananindzya thanks for taking this back. What's the state of this PR? Is it ready for another review? |
I updated yesterday as per the new changes. But there was a problem with integration tests, the isntrumentation for some reason not working. Today I will try to find the reason. |
eyalkoren
left a comment
There was a problem hiding this comment.
Thanks @kananindzya, looking good!
I started commenting but decided it's easier to code instead 🙂 .
Please see my suggested changes and if you feel it doesn't contradict anything you intended to do, please merge.
I mainly moved a couple of things around, saving some allocations.
I also removed a crash report you accidentally pushed but I wonder - does this need to trouble us? Do you know what caused this crash?
Great! Thanks you. I added exception handling. |
No it shouldn't trouble you. Next time I will be more attentive before pushing changes. |
…pans-request-dispatcher-forward-include
eyalkoren
left a comment
There was a problem hiding this comment.
Looking at your addition, I decided to cancel this error reporting. Assuming that the parent of such spans is the transaction, we will get the error reported by the transaction anyway.
I also added a test to demonstrate that.
| } else { | ||
| if (Boolean.TRUE.equals(isExceptionAttributeCaptured.get())) { | ||
| t2 = null; | ||
| } |
There was a problem hiding this comment.
No, we can't do that as we don't know if it's the same exception or not.
Thanks you |
…orward-include Also apply few minor changes
|
Is there any way to disable these spans? They are taking a toll on our Elastic storage and we do not actually need them. I tried using the |
|
Can you share numbers? How many such spans do you get per transaction? |
|
Hi @eyalkoren. We get from only a couple to more than a hundred. We had the same issue with spring-view-render and we were forced to stop instrumenting it. Once we did, the amount of used storage decreased to ~20GB per day, which was manageable. But now we have 140GB a day again, mostly jsp includes. It is worth mentioning that we have lots of traffic. I think the quick solution would be to downgrade to release 1.17.0 which was working fine for us. |
|
@Purdel please try this snapshot with adding |
|
@eyalkoren wow, that was fast! Trying it out. |
|
@eyalkoren looks good |
|
Awesome, thanks for verifying. #1448 is now merged. |
|
@eyalkoren great, thank you very much! Any idea when the next release will come? |
|
I can't say exactly, but probably within a couple of weeks frame. You can register for notifications from our repo only on new releases. |
closes #557
reopened from #557
closes #384