-
Notifications
You must be signed in to change notification settings - Fork 323
Binary execution support #903
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
Merged
eyalkoren
merged 59 commits into
elastic:master
from
theobisproject:binary-execution-support
Jan 8, 2020
Merged
Changes from all commits
Commits
Show all changes
59 commits
Select commit
Hold shift + click to select a range
107a604
Support commons-exec synchronous api
theobisproject 2e6b42e
Fix ClassNotFound exception when attaching agent to wildfly
theobisproject dab2b98
Add draft implementation for commons-exec async, process builder and …
theobisproject 948e3dc
Use the ExecuteHelper in the Java Runtime instrumentation
theobisproject e8f0a6f
Working commons-exec async instrumentation
theobisproject c2a97f7
Fix nullpointer
theobisproject 165d81f
Remove redundant checks which ExecuteHelper.createAndActivateSpan alr…
theobisproject 2535e68
Class of EndProcessInstrumentation will be loaded by the bootstrap cl…
theobisproject 3e949c4
add few notes (wip commit)
SylvainJuge 6dd2b0b
allow java.lang.Process{,Builder} instrumentation
SylvainJuge 993fde8
allow java.lang.*Process* instrumentation
SylvainJuge b670401
add command test servlet
SylvainJuge 4471503
use simple java.lang.Process instrumentation
SylvainJuge 424ee86
deprecate initial implementation
SylvainJuge 179292b
post quick review changes
SylvainJuge 66e03d4
add ProcessHelper test
SylvainJuge 94bedfd
add simple integration test
SylvainJuge 5caf2c5
mark plugin as incubating & deprecate old impl
SylvainJuge 85355af
remove initial implementation
SylvainJuge 45ea4fd
rename package for consistency
SylvainJuge 6bf30bd
fix minor leak
SylvainJuge 408e858
make it java7 compliant
SylvainJuge a23a0c0
fix licence headers
SylvainJuge c4b6087
update doc with 'process' incubating feature
SylvainJuge b7299c4
fix process start instrument ProcessBuilder
SylvainJuge 3d60c16
enable all instrumentations for integration tests
SylvainJuge 2759090
make test app java7 compatible
SylvainJuge ac0a679
improve instrumentation test error msg
SylvainJuge 52a357f
remove useless annotation
SylvainJuge 36fb020
fix active span leak + shorter naming
SylvainJuge b96124c
test for short span naming & detect active span leaks
SylvainJuge 3da3bed
code cleanup
SylvainJuge 16e38f2
rename plugin 'cmd' -> 'process'
SylvainJuge 5f1d800
add Readme for plugin
SylvainJuge 2dae898
fix plugin renamed maven module
SylvainJuge c78abc4
properly rename artifact name
SylvainJuge ec3c2fc
post PR review changes
SylvainJuge 7c37322
add support for commons-exec async process
SylvainJuge ba79491
minor fixes + update readme
SylvainJuge 8f15e57
update doc
SylvainJuge f8200f7
Bump process plugin version to current snapshot
theobisproject 28ca9bf
fix generated config asciidoc
SylvainJuge 83a3b9c
replace todo with link to issue
SylvainJuge 380f6c2
post review changes
SylvainJuge 0aa056e
add check for no leaked transaction
SylvainJuge 509a457
add multiple process exec strategies
SylvainJuge 4e5b37e
rename process end helper
SylvainJuge a8b4936
report exceptions on process start
SylvainJuge 1b53813
terminate process span on 'destroy'
SylvainJuge e5c4922
faster class matching for instrumentation
SylvainJuge 27052f4
Merge branch 'master' into binary-execution-support
SylvainJuge 6a49a2e
update doc
SylvainJuge 60248a0
update supported technologies
SylvainJuge 0a4c4e3
minor changes from PR review
SylvainJuge 6238402
use inline weak map cleanup
SylvainJuge 44bb215
Remove diamond operator
eyalkoren 912a9c4
Merge remote-tracking branch 'upstream/master' into binary-execution-…
eyalkoren 41b55db
Updating configuration.asciidoc
eyalkoren e7c27b8
Reducing apache scope to test
eyalkoren File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
# Process plugin | ||
|
||
This plugin creates spans for external processes executed by the JVM, which use the `java.lang.Process` class. | ||
|
||
[Apache commons-exec](https://commons.apache.org/proper/commons-exec/) library support is included. | ||
|
||
## Limitations | ||
|
||
`java.lang.ProcessHandler` and `java.lang.Process.toHandle()` introduced in java 9 are not | ||
instrumented. As a result, process execution using this API is not yet supported. | ||
|
||
## Implementation Notes | ||
|
||
Instrumentation of classes in `java.lang.*` that are loaded in the bootstrap classloader can't | ||
be tested with unit tests due to the fact that agent is loaded in application/system classloader | ||
for those tests. | ||
|
||
Thus, using integration tests is required to test the instrumentation end-to-end. | ||
Also, in order to provide a good test of this feature without testing everything in integration tests, we | ||
- delegate most of the advice code to helper classes | ||
- test extensively those classes with regular unit tests |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
<parent> | ||
<artifactId>apm-agent-plugins</artifactId> | ||
<groupId>co.elastic.apm</groupId> | ||
<version>1.12.1-SNAPSHOT</version> | ||
</parent> | ||
<modelVersion>4.0.0</modelVersion> | ||
|
||
<properties> | ||
<apm-agent-parent.base.dir>${project.basedir}/../..</apm-agent-parent.base.dir> | ||
</properties> | ||
|
||
<artifactId>apm-process-plugin</artifactId> | ||
<name>${project.groupId}:${project.artifactId}</name> | ||
|
||
<dependencies> | ||
<dependency> | ||
<groupId>org.apache.commons</groupId> | ||
<artifactId>commons-exec</artifactId> | ||
<version>1.3</version> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
</project> |
48 changes: 48 additions & 0 deletions
48
...process-plugin/src/main/java/co/elastic/apm/agent/process/BaseProcessInstrumentation.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/*- | ||
* #%L | ||
* Elastic APM Java agent | ||
* %% | ||
* Copyright (C) 2018 - 2019 Elastic and contributors | ||
* %% | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
* #L% | ||
*/ | ||
package co.elastic.apm.agent.process; | ||
|
||
import co.elastic.apm.agent.bci.ElasticApmInstrumentation; | ||
import net.bytebuddy.matcher.ElementMatcher; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collection; | ||
|
||
import static net.bytebuddy.matcher.ElementMatchers.isBootstrapClassLoader; | ||
|
||
public abstract class BaseProcessInstrumentation extends ElasticApmInstrumentation { | ||
|
||
@Override | ||
public final ElementMatcher.Junction<ClassLoader> getClassLoaderMatcher() { | ||
// java.lang.* is loaded from bootstrap classloader | ||
return isBootstrapClassLoader(); | ||
} | ||
|
||
@Override | ||
public final Collection<String> getInstrumentationGroupNames() { | ||
return Arrays.asList("process", "incubating"); | ||
} | ||
|
||
} |
101 changes: 101 additions & 0 deletions
101
...ss-plugin/src/main/java/co/elastic/apm/agent/process/CommonsExecAsyncInstrumentation.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
/*- | ||
* #%L | ||
* Elastic APM Java agent | ||
* %% | ||
* Copyright (C) 2018 - 2019 Elastic and contributors | ||
* %% | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
* #L% | ||
*/ | ||
package co.elastic.apm.agent.process; | ||
|
||
import co.elastic.apm.agent.bci.ElasticApmInstrumentation; | ||
import net.bytebuddy.asm.Advice; | ||
import net.bytebuddy.description.NamedElement; | ||
import net.bytebuddy.description.method.MethodDescription; | ||
import net.bytebuddy.description.type.TypeDescription; | ||
import net.bytebuddy.matcher.ElementMatcher; | ||
|
||
import java.util.Arrays; | ||
import java.util.Collection; | ||
|
||
import static net.bytebuddy.matcher.ElementMatchers.hasSuperClass; | ||
import static net.bytebuddy.matcher.ElementMatchers.nameContains; | ||
import static net.bytebuddy.matcher.ElementMatchers.named; | ||
import static net.bytebuddy.matcher.ElementMatchers.takesArgument; | ||
|
||
/** | ||
* Provides context propagation for apache commons-exec library that delegates to a background thread for | ||
* asynchronous process execution. Synchronous execution is already covered with {@link Process} instrumentation. | ||
* <p> | ||
* Instruments {@code org.apache.commons.exec.DefaultExecutor#createThread(Runnable, String)} and any direct subclass | ||
* that overrides it. | ||
*/ | ||
public class CommonsExecAsyncInstrumentation extends ElasticApmInstrumentation { | ||
|
||
private static final String DEFAULT_EXECUTOR_CLASS = "org.apache.commons.exec.DefaultExecutor"; | ||
// only known subclass of default implementation | ||
private static final String DAEMON_EXECUTOR_CLASS = "org.apache.commons.exec.DaemonExecutor"; | ||
|
||
@Override | ||
public ElementMatcher<? super NamedElement> getTypeMatcherPreFilter() { | ||
// Most implementations are likely to have 'Executor' in their name, which will work most of the time | ||
// while not perfect this allows to avoid the expensive 'hasSuperClass' in most cases | ||
return nameContains("Executor"); | ||
} | ||
|
||
@Override | ||
public ElementMatcher<? super TypeDescription> getTypeMatcher() { | ||
// instrument default implementation and direct subclasses | ||
return named(DEFAULT_EXECUTOR_CLASS) | ||
.or(named(DAEMON_EXECUTOR_CLASS)) | ||
// this super class check is expensive | ||
.or(hasSuperClass(named(DEFAULT_EXECUTOR_CLASS))); | ||
SylvainJuge marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
@Override | ||
public ElementMatcher<? super MethodDescription> getMethodMatcher() { | ||
return named("createThread") | ||
.and(takesArgument(0, Runnable.class)); | ||
} | ||
|
||
@Override | ||
public Collection<String> getInstrumentationGroupNames() { | ||
// part of 'process' group, as usage is not relevant without it, relies on generic Process instrumentation | ||
return Arrays.asList("apache-commons-exec", "process", "incubating"); | ||
} | ||
|
||
@Override | ||
public Class<?> getAdviceClass() { | ||
return CommonsExecAdvice.class; | ||
} | ||
|
||
public static final class CommonsExecAdvice { | ||
|
||
@Advice.OnMethodEnter(suppress = Throwable.class) | ||
private static void onEnter(@Advice.Argument(value = 0, readOnly = false) Runnable runnable) { | ||
if (tracer == null || tracer.getActive() == null) { | ||
return; | ||
} | ||
// context propagation is done by wrapping existing runnable argument | ||
|
||
//noinspection UnusedAssignment | ||
runnable = tracer.getActive().withActive(runnable); | ||
} | ||
} | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.