Skip to content

Spark Java Framework Instrumentation#254

Merged
tylerbenson merged 13 commits into
DataDog:masterfrom
JorgenG:feat/add-sparkjava-instrumentation
Apr 26, 2018
Merged

Spark Java Framework Instrumentation#254
tylerbenson merged 13 commits into
DataDog:masterfrom
JorgenG:feat/add-sparkjava-instrumentation

Conversation

@JorgenG
Copy link
Copy Markdown

@JorgenG JorgenG commented Mar 6, 2018

This is a WIP of looking into sparkjava support.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This looks wrong...

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You're also going to want to add instrumentation for spark specifically to set the resource name for a request. This is similar to what I'm doing in the spring web instrumentation. So for example, on this line, the resource name should be GET /param/:param, regardless of what the parameter is.

Unfortunately Spark doesn't seem to be a great spot for this. Maybe getTarget()? When it is called, get the matchUri value? That doesn't have the HTTP method though.

Other ideas?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This doesn't need to be copied in both places. I'd suggest removing this class.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Instead say, sparkjava uses servlet filters under the covers, so we want to include that instrumentation here for verification.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Remove these lines and replace with a dependency on sparkjava (the earliest version the instrumentation supports), then rename the project to match sparkjava-<version>.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Rename class to match.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

While I don't love it, it does seem this is a best way to generically cover what you need. The other option might be to instrument Jetty's Handler.handle interface. Which do you think is better?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Looking at the Jetty handler interface, I like that a lot more. I think that will fit better and have less edge cases like the Filter has.

Should that go in a seperate package "jetty"?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since this span could come from a potentially large number of classes, I'd like to have something to trace it back to the origin. Please add a tag with the class name like so:

      .withTag("span.origin.type", statement.getClass().getName());

Would you mind also adding that to the other servlet-{2,3} instrumentation as well?
Thanks!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

What is statement here? Cannot find it, and nothing logically matches.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Sorry that was copy paste from the statement instrumentation. For jetty instrumentation it would be this.getClass().

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

once you have the instrumentation working, I'd like to see this test suite include deeper verification and some edge cases. Use this for inspiration.

@tylerbenson
Copy link
Copy Markdown
Contributor

Also, it appears spark dropped support for Java 7 in 2.0, so if we don't plan on supporting anything before then, you can exclude the tests from running on java 7 by doing this, except change the check to JavaVersion.current().isJava8Compatible().

@JorgenG
Copy link
Copy Markdown
Author

JorgenG commented Mar 7, 2018

Thanks for the good feedback. I do see that I have messed up a bit, so I want to clear some things up.

I had the impression that blindly adding instrumentation for Filter3 would not be a good solution. So my original intention was to not have Filter3Instrumentation under servlet-3 (Although I managed to commit it).

Does my view match your understanding? Or would having the Filter3Instrumentation be correct at that location, and then add spark specific instrumentation on spark-specific classes?

Right now there are two "identical" files.

EDIT: saw your specific comment about this, will remove!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

What are all these opentracing things used for?

@JorgenG
Copy link
Copy Markdown
Author

JorgenG commented Mar 7, 2018

I have made some changes now.

  • Removed Filter3Instrumentation
  • Added HandlerInstrumentation for Jetty
  • Added RoutesInstrumentation for enriching with match url from SparkJava

Once the overall structure is ok, I'll take another look at the tests etc.

@JorgenG
Copy link
Copy Markdown
Author

JorgenG commented Mar 7, 2018

I have attempted to use google java format in the project, but the verification step still fails. Any tips?

@tylerbenson
Copy link
Copy Markdown
Contributor

There’s a gradle task you can run to format everything. I think it’s googleFormatJava or something like that.

Copy link
Copy Markdown
Contributor

@tylerbenson tylerbenson left a comment

Choose a reason for hiding this comment

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

I am ok with the approach. Needs some polish and more testing on both the jetty and spark side. Let me know if you get stuck. Thanks for working through this. I hope it’s interesting for you.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This part is a bit confusing and poorly documented. We use this to make sure we are only instrumenting classes we expect it to work on. Please update the group and module for jetty. You can remove the legacy part.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I think this jetty hook requires the Async things from servlet?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We might still want to check if there is an active trace and return early to avoid duplicate traces if the existing servlet instrumentation applies.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Change to isJava8Compatible()

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

The main reason for adding this line is to limit the versions of the sparkjava library we try to instrument. This list should match the verifyPresent block in a versionScan in the gradle file.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added version scan for sparkjava as well.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Standard practice. Since this is new instrumentation, can you override the default enabled method to return false? We will change to enabled by default in a future release. Same applies to the spark instrumentation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Any reason this instrumentation wouldn’t work with older versions of jetty? We usually name the instrumentation with the earliest version it can support.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Added support for oldest 8.0.0 where signature is the same for Handler.

@JorgenG
Copy link
Copy Markdown
Author

JorgenG commented Mar 7, 2018

I will work on some tests later this week.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This version range should match the version for the instrumentation, so in this case [ 8.0.0.v20110901,).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This version range should match the version for the instrumentation, so in this case [ 2.5,).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

These classes are probably not what you need, unless 8.0 was the first version to support Servlet 3.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks like that is in fact the case: https://wiki.eclipse.org/Jetty/Starting/Jetty_Version_Comparison_Table. Carry on.

@tylerbenson tylerbenson changed the title WIP: fix: first attempt at sparkjava trace instrumentation Spark Java Framework Instrumentation Mar 8, 2018
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Was this class newly added in 2.5 and available in all following versions?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think I'd like to see this as a setupSpec() method with a corresponding cleanupSpec() method to shut it down. (Is it possible to shut down programmatically?)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this would look nicer if span.context() was declared as a variable and maybe even the tags.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Partially fixed by extracting to a variable.

@tylerbenson
Copy link
Copy Markdown
Contributor

After a clean build, I think this is mostly ready. I'm going to pass over to @realark for secondary review.

@tylerbenson tylerbenson requested a review from realark March 9, 2018 04:59
@JorgenG
Copy link
Copy Markdown
Author

JorgenG commented Mar 9, 2018

My problem right now is that the basic test does not work. I think this is because my understanding of how to activate the instrumentation is wrong.

Since the tests are failing, we can't verify if it works. Since defaultEnabled() returns false, how will it be an active instrumentation in test setting?

@JorgenG
Copy link
Copy Markdown
Author

JorgenG commented Mar 9, 2018

In the latest commit, we can observe that Spark is started in the tests, however no traces are registered, thus our tests don't work. How can we activate tracing for the default disabled instrumentation?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks like this instrumentation is only intended to apply to Java 8 and above, correct? If so, I think we have a problem. Attempting to load a 1.8 class on a 1.7 jvm, will cause an exception to be thrown when we initialize the instrumentation.

@JorgenG There's nothing for you to do about this (unless you can change source and target compatibility to 1.7?). @tylerbenson and I will have to figure out a solution. I'm sure we'll want to do this often, especially as more frameworks are compiled against newer jvms.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe we could configure the tests to be Java 8 but leave the instrumentation at Java 7?

@realark
Copy link
Copy Markdown
Contributor

realark commented Mar 9, 2018

@JorgenG You can enable the instrumentation in the test using a static initializer to set the system property.

Kafka example: https://github.com/DataDog/dd-trace-java/blob/master/dd-java-agent/instrumentation/kafka-clients-0.11/src/test/groovy/KafkaClientTest.groovy#L23-L25

I think you'll want something like this:

  static {
    System.setProperty("dd.integration.sparkjava.enabled", "true")
  }

Copy link
Copy Markdown
Contributor

@realark realark left a comment

Choose a reason for hiding this comment

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

I think the PR looks good once the tests are enabled.

I'm good to merge after we figure out the java 1.7 issue.

@JorgenG
Copy link
Copy Markdown
Author

JorgenG commented Mar 13, 2018

Attempted to add the enabling of instrumentation in tests, not able to get it working. I am leaving for two weeks vacation on thursday, and will be back at beginning of April. Will not be able to do any contributions during this time, so if you are able to provide support on getting the tests running that would be nice.

@realark
Copy link
Copy Markdown
Contributor

realark commented Apr 6, 2018

@JorgenG Thanks for your patience while we work on unblocking you. We're still working on a solution for Java 8 instrumentation, but we'll let you know as soon as we can get this merged.

@tylerbenson tylerbenson added this to the 0.7.0 milestone Apr 26, 2018
and rebase off master.
@tylerbenson tylerbenson added inst: others All other instrumentations tag: community Community contribution labels Apr 26, 2018
import java.lang.reflect.Field

@Timeout(1)
@Timeout(10)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💯

@realark
Copy link
Copy Markdown
Contributor

realark commented Apr 26, 2018

Looks good!

@tylerbenson tylerbenson merged commit fc41529 into DataDog:master Apr 26, 2018
@tylerbenson
Copy link
Copy Markdown
Contributor

@JorgenG Thanks for your contribution. Glad we could finally get this merged. Sorry for the delay.

@JorgenG
Copy link
Copy Markdown
Author

JorgenG commented Apr 27, 2018

Thanks for all the help, and happy to see it getting in. 👍

@JorgenG JorgenG deleted the feat/add-sparkjava-instrumentation branch April 27, 2018 06:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

inst: others All other instrumentations tag: community Community contribution

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants