Skip to content
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

Binary execution support #903

Merged
merged 59 commits into from
Jan 8, 2020

Conversation

theobisproject
Copy link
Contributor

@theobisproject theobisproject commented Oct 25, 2019

Support for calls to external binaries. Fixes #767.

Code is currently a little messy but the commons-exec library works.
@felixbarny @eyalkoren I need some help with the Java APIs. Even removing all ignores from the Agent the classes where not instrumented. Maybe I have done something wrong?
Integration Tests for the Java API still has to be created. Any advice on this? Currently I'm using a REST-Resource deployed on Wildfly to test this change.

Checklist

Open for discussion

  • Module name
  • Module structure (All apis in the same package, own package per API)
  • Need some way to add the exit value of the process and the process arguments to the span. What has to be done for this?

Copy link
Contributor

@eyalkoren eyalkoren left a comment

Choose a reason for hiding this comment

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

Thanks a lot!! This is great stuff!

I didn't really review, as this is still marked WIP. Only looked for general stuff, mainly trying to answer why the core java stuff is not instrumented (not sure if you mean it doesn't work in the unit tests or the WildFly test).
So, first you need to add an exception for the instrumented types to where we say java. package should be ignored. Also, see the review comments- make sure the instrumentation classes are properly listed in the services file and that you are not filtering out the classes you want instrumented, eg the class loading filter.
Use DEBUG log level to see which advices are applied and whether there were type matches and method matches.

More general things- any instrumentation that looks for implementations of interfaces or sub-classes of types should contain a "cheap" implementation of getTypeMatcherPreFilter() (eg based on class name), otherwise startup times will be greatly affected.
Apart from that- the extraction of common code is great, but I would separate classes so that each API is handled through a different instrumentation class.

Lastly- what you did for testing with WildFly is a valid option, but you can also use a basic Java image with a basic Java application that starts transactions through the agent APIs and executes commands as spans.

@SylvainJuge
Copy link
Member

Hi @theobisproject this is a great PR, I'd like to give a hand to move this forward.

As there are quite a few things to change, I think the best way to proceed would be to submit a PR against your fork branch. I will try to make the commits as self explanatory as possible. Are you OK with that ?

I have a question regarding commons-exec library (which I'm not very familiar with), as it relies on java.lang.Process that would probably be better to only instrument that part. Is there something that is provided by this library that would not be visible to a java.lang.Process instrumentation ?

One extra benefit of only instrumenting java.lang.Process would be to not having to check for nested method calls, for example when commons-exec calls java.lang.Process span should be created at commons-exec leven, and when java.lang.Process is used without span should be created.

@theobisproject
Copy link
Contributor Author

Hi @SylvainJuge I'm okay with PR's against my branch.

I'm currently quite stuck with the insturmentation of the Java API's and are happy to get some help. Here ist the latest patch of me trying to get the Java process builder api to work Latest_work_for_supporting_Java_process_builder_api.patch.txt.

Support of commons-exec is mainly motivated because we use it heavily in our application and the Java API intrumentation didn't work. I would be ok to insturment commons-exec via the java.lang.Process instrumentation because we do not use custom executors. But for those who have custom executors which use a different api this would be a benefit.

@SylvainJuge
Copy link
Member

@theobisproject I have pushed a PR to your fork (theobisproject#1), I've tried to make the commit history intelligible, but don't hesitate to ask if you have any questions.

Instrumentation is now in the incubating group, thus you have to set disable_instrumentations to an empty string to enable it (incubating features are disabled by default).

It was definitely more tricky than expected, and we found a few things to improve to help further contributions, thus definitely worth to push forward !

@theobisproject
Copy link
Contributor Author

@SylvainJuge I tried your change and the Java APIs + commons exec synchronous API works. Great job! Will have a look at the code later.
Just noticed the async commons exec API is currently not tracked. See this example

Executor executor = new DefaultExecutor();
DefaultExecuteResultHandler handler = new DefaultExecuteResultHandler();
executor.execute(new CommandLine("java").addArgument("-version"), handler);
handler.waitFor();

What would be the plan going forward from here? I initially planned to also get the arguments of the call as well as the return code of the process. Should we separate this from the changes here?

@SylvainJuge
Copy link
Member

Thanks for checking on your side.

I will try to reproduce the issue with asynchronous execution with commons-exec to see where the problem is.

One limitation of the current implementation is that we don't instrument java.lang.Process.toHandle(), but here it's not the case.

What is likely to happen, is that the java.lang.Process or java.lang.ProcessBuilder instance is created in a separate thread than the transaction by commons-exec, thus the span is not being linked to the active transaction. This kind of issue is often referred as "context propagation" and is sometimes tricky to implement.

I will need to investigate a bit to see how we could provide dedicated support for this with commons-exec.

@theobisproject
Copy link
Contributor Author

@SylvainJuge Have you planned to do the proposed changes in another pull request against my branch. I ask because I won't be that much available from Monday on until next year.

@eyalkoren Would it be possible to merge the current state (including the incubating status) and improve the functionality by additional pull requests?

@SylvainJuge
Copy link
Member

SylvainJuge commented Dec 13, 2019 via email

@SylvainJuge
Copy link
Member

jenkins, please run the tests

@eyalkoren eyalkoren force-pushed the binary-execution-support branch from 95a26df to 41b55db Compare January 8, 2020 06:27
@eyalkoren eyalkoren merged commit c18e1f1 into elastic:master Jan 8, 2020
@zube zube bot removed the [zube]: Done label Oct 13, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Create spans for calls to external binaries
5 participants