Skip to content

Conversation

@SylvainJuge
Copy link
Member

@SylvainJuge SylvainJuge commented Mar 6, 2020

What does this PR do?

This pull-request modifies Servlet plugin instrumentation to make it gracefully ignore Servlet implementations before Servlet API 3.0.

Without this change, users get spammed in application server logs with similar exception (Here on Tomcat 6.x):

java.lang.NoSuchMethodError: javax.servlet.ServletRequest.getDispatcherType()Ljavax/servlet/DispatcherType; at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:181) at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233) at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:610) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:503) at java.lang.Thread.run(Thread.java:748) 

While this change avoids spamming the server logs, there is no explicit warning message from this agent when an unsupported version is being used. Thus from user's perspective it will just make the agent not monitor any HTTP transaction (but JMX metrics will still be properly working as expected).

Checklist

  • My code follows the style guidelines of this project
  • I have rebased my changes on top of the latest master branch
  • I have made corresponding changes to the documentation
  • I have added tests that prove my fix is effective or that my feature works (tested manually)
  • New and existing unit tests pass locally with my changes
  • I have updated CHANGELOG.asciidoc
  • I have updated supported-technologies.asciidoc (no change required, previous versions were not supported).

Author's Checklist

  • Manual testing with Servlet 2.5 container (Tomcat 6.x).
  • Manual testing with Servlet 3.0 container (Tomcat 7.x or later).
  • Decide if we want to have a proper warning when such an incompatible Servlet version is used (currently we silently ignore all transactions).

Related issues

…apm/agent/servlet/AbstractServletInstrumentation.java Co-Authored-By: eyalkoren <41850454+eyalkoren@users.noreply.github.com>
@felixbarny
Copy link
Member

Decide if we want to have a proper warning when such an incompatible Servlet version is used (currently we silently ignore all transactions).

Maybe we can couple this with logging javax.servlet.ServletContext#getServerInfo but that can be done in a separate advice.

@felixbarny
Copy link
Member

Seems like tests fail on Payara

@SylvainJuge
Copy link
Member Author

I've added a quick check on Servlet.init that will output a warning similar to this one

WARN co.elastic.apm.agent.servlet.ServletTransactionHelper - Unsupported servlet version detected: 2.5, no Servlet transaction will be created 
Copy link
Member

@felixbarny felixbarny left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments on the ServletInitInstrumentation but we can also merge the PR without this instrumentation.

@Advice.OnMethodEnter(suppress = Throwable.class)
@SuppressWarnings("Duplicates") // duplication is fine here as it allows to inline code
private static void onEnter(@Advice.This Servlet servlet) {
if (!doLogAndWarn.getAndSet(false)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid a CAS on every invocation

Suggested change
if (!doLogAndWarn.getAndSet(false)) {
if (!doLogAndWarn.get() || !doLogAndWarn.getAndSet(false)) {

maybe rename doLogAndWarn to alreadyLogged to get rid of the negations which are a bit harder to parse?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

definitely agree on having less negations, however doing a double check here seems a bit overkill. I think it's fine to replace this AtomicBoolean with a simple volatile boolean as AtomicBoolean.get does makes a volatile read, thus it won't be more efficient.

@SylvainJuge SylvainJuge merged commit a882c45 into elastic:master Mar 10, 2020
@SylvainJuge SylvainJuge deleted the do-not-instrument-old-servlet branch March 10, 2020 14:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

3 participants