Skip to content

Commit 73b6262

Browse files
authored
Add bootstrap check for disabling agent when required (#2951)
1 parent 5be1521 commit 73b6262

File tree

89 files changed

+672
-130
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+672
-130
lines changed

CHANGELOG.asciidoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ endif::[]
3333
[float]
3434
===== Features
3535
* Add experimental log sending from the agent with `log_sending` - {pull}2694[#2694]
36+
* Add bootstrap checks that enable <<jvm-filtering>> on startup - {pull}2951[#2951]
3637
3738
[float]
3839
===== Bug fixes

apm-agent-attach/src/main/java/co/elastic/apm/attach/ElasticApmAttacher.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
package co.elastic.apm.attach;
2020

2121
import co.elastic.apm.agent.common.util.ResourceExtractionUtil;
22+
import co.elastic.apm.agent.common.util.SystemStandardOutputLogger;
2223
import net.bytebuddy.agent.ByteBuddyAgent;
2324

2425
import javax.annotation.Nullable;
@@ -83,7 +84,7 @@ private static Map<String, String> loadPropertiesFromClasspath(String properties
8384
}
8485
}
8586
} catch (IOException e) {
86-
e.printStackTrace();
87+
SystemStandardOutputLogger.printStackTrace(e);
8788
}
8889
return propertyMap;
8990
}
@@ -124,7 +125,7 @@ static File createTempProperties(Map<String, String> configuration, @Nullable Fi
124125
properties.store(outputStream, null);
125126
}
126127
} catch (IOException e) {
127-
e.printStackTrace();
128+
SystemStandardOutputLogger.printStackTrace(e);
128129
}
129130
}
130131
return tempFile;
@@ -170,11 +171,11 @@ private static void attachWithFallback(File agentJarFile, String pid, String age
170171
ByteBuddyAgent.attach(agentJarFile, pid, agentArgs, ElasticAttachmentProvider.getFallback());
171172
} catch (RuntimeException e2) {
172173
// output the two exceptions for debugging
173-
System.err.println("Unable to attach with fallback provider:");
174-
e2.printStackTrace();
174+
SystemStandardOutputLogger.stdErrInfo("Unable to attach with fallback provider:");
175+
SystemStandardOutputLogger.printStackTrace(e2);
175176

176-
System.err.println("Unable to attach with regular provider:");
177-
e1.printStackTrace();
177+
SystemStandardOutputLogger.stdErrInfo("Unable to attach with regular provider:");
178+
SystemStandardOutputLogger.printStackTrace(e1);
178179
}
179180
}
180181
}

apm-agent-common/src/main/java/co/elastic/apm/agent/common/JvmRuntimeInfo.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
*/
1919
package co.elastic.apm.agent.common;
2020

21+
import co.elastic.apm.agent.common.util.SystemStandardOutputLogger;
22+
2123
import javax.annotation.Nullable;
2224

2325
public class JvmRuntimeInfo {
@@ -111,7 +113,7 @@ private int getUpdateVersion(String version) {
111113
}
112114

113115
if (updateVersion < 0) {
114-
System.err.println("[elastic-apm-agent] WARN Unsupported format of the java.version system property - " + version);
116+
SystemStandardOutputLogger.stdErrWarn("Unsupported format of the java.version system property - " + version);
115117
}
116118
return updateVersion;
117119
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package co.elastic.apm.agent.common.util;
20+
21+
import java.util.ArrayList;
22+
import java.util.List;
23+
24+
public class StringUtils {
25+
26+
/**
27+
* Copied from https://github.com/apache/commons-lang/blob/master/src/main/java/org/apache/commons/lang3/StringUtils.java
28+
*
29+
* <p>Splits the provided text into an array, separator specified.
30+
* This is an alternative to using StringTokenizer.</p>
31+
*
32+
* <p>The separator is not included in the returned String array.
33+
* Adjacent separators are treated as one separator.
34+
* For more control over the split use the StrTokenizer class.</p>
35+
*
36+
* <p>A {@code null} input String returns {@code null}.</p>
37+
*
38+
* <pre>
39+
* StringUtils.split(null, *) = null
40+
* StringUtils.split("", *) = []
41+
* StringUtils.split("a.b.c", '.') = ["a", "b", "c"]
42+
* StringUtils.split("a..b.c", '.') = ["a", "b", "c"]
43+
* StringUtils.split("a:b:c", '.') = ["a:b:c"]
44+
* StringUtils.split("a b c", ' ') = ["a", "b", "c"]
45+
* </pre>
46+
*
47+
* @param str the String to parse, may be null
48+
* @param separatorChar the character used as the delimiter
49+
* @return an array of parsed Strings, {@code null} if null String input
50+
*/
51+
public static String[] split(final String str, final char separatorChar) {
52+
if (str == null) {
53+
return null;
54+
}
55+
final int len = str.length();
56+
if (len == 0) {
57+
return new String[0];
58+
}
59+
final List<String> list = new ArrayList<String>();
60+
int i = 0, start = 0;
61+
boolean match = false;
62+
while (i < len) {
63+
if (str.charAt(i) == separatorChar) {
64+
if (match) {
65+
list.add(str.substring(start, i));
66+
match = false;
67+
}
68+
start = ++i;
69+
continue;
70+
}
71+
match = true;
72+
i++;
73+
}
74+
if (match) {
75+
list.add(str.substring(start, i));
76+
}
77+
return list.toArray(new String[list.size()]);
78+
}
79+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* Licensed to Elasticsearch B.V. under one or more contributor
3+
* license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright
5+
* ownership. Elasticsearch B.V. licenses this file to you under
6+
* the Apache License, Version 2.0 (the "License"); you may
7+
* not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
package co.elastic.apm.agent.common.util;
20+
21+
import java.security.AccessController;
22+
import java.security.PrivilegedAction;
23+
24+
/**
25+
* A utility for writing to System standard output and standard error output streams.
26+
* Prints can be disabled through the {@code elastic.apm.system_output_disabled} system property or the corresponding
27+
* {@code ELASTIC_APM_SYSTEM_OUTPUT_DISABLED} environment variable.
28+
*/
29+
public class SystemStandardOutputLogger {
30+
private static final String DISABLED_SYSTEM_PROPERTY = "elastic.apm.system_output_disabled";
31+
private static final String DISABLED_ENV_VARIABLE = "ELASTIC_APM_SYSTEM_OUTPUT_DISABLED";
32+
33+
private static final String LINE_PREFIX = "[elastic-apm-agent]";
34+
35+
private static final boolean disabled;
36+
37+
static {
38+
if (System.getSecurityManager() == null) {
39+
disabled = isDisabledThroughConfiguration();
40+
} else {
41+
disabled = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
42+
@Override
43+
public Boolean run() {
44+
return isDisabledThroughConfiguration();
45+
}
46+
});
47+
}
48+
}
49+
50+
public static boolean isDisabled() {
51+
return disabled;
52+
}
53+
54+
private static boolean isDisabledThroughConfiguration() {
55+
return System.getProperty(DISABLED_SYSTEM_PROPERTY) != null || System.getenv(DISABLED_ENV_VARIABLE) != null;
56+
}
57+
58+
public static void printStackTrace(Throwable throwable) {
59+
if (!disabled) {
60+
throwable.printStackTrace();
61+
}
62+
}
63+
64+
private static void printToStdOut(String level, String message) {
65+
if (!disabled) {
66+
System.out.printf("%s %s %s%n", LINE_PREFIX, level, message);
67+
}
68+
}
69+
70+
private static void printToStdErr(String level, String message) {
71+
if (!disabled) {
72+
System.err.printf("%s %s %s%n", LINE_PREFIX, level, message);
73+
}
74+
}
75+
76+
public static void stdOutInfo(String message) {
77+
printToStdOut("INFO", message);
78+
}
79+
80+
public static void stdOutWarn(String message) {
81+
printToStdOut("WARN", message);
82+
}
83+
84+
public static void stdOutError(String message) {
85+
printToStdOut("ERROR", message);
86+
}
87+
88+
public static void stdErrInfo(String message) {
89+
printToStdErr("INFO", message);
90+
}
91+
92+
public static void stdErrWarn(String message) {
93+
printToStdErr("WARN", message);
94+
}
95+
96+
public static void stdErrError(String message) {
97+
printToStdErr("ERROR", message);
98+
}
99+
}

apm-agent-core/src/main/java/co/elastic/apm/agent/matcher/WildcardMatcher.java renamed to apm-agent-common/src/main/java/co/elastic/apm/agent/common/util/WildcardMatcher.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,7 @@
1616
* specific language governing permissions and limitations
1717
* under the License.
1818
*/
19-
package co.elastic.apm.agent.matcher;
20-
21-
import org.stagemonitor.util.StringUtils;
19+
package co.elastic.apm.agent.common.util;
2220

2321
import javax.annotation.Nullable;
2422
import java.util.ArrayList;
@@ -46,7 +44,7 @@
4644

4745
/**
4846
* This matcher is used in for example to disable tracing for certain URLs.
49-
* The advantage of this class compared to alternatives is is that {@linkplain #matches(CharSequence) matching} strings is completely allocation free.
47+
* The advantage of this class compared to alternatives is that {@linkplain #matches(CharSequence) matching} strings is completely allocation free.
5048
* <p>
5149
* The wildcard matcher supports the {@code *} wildcard which matches zero or more characters.
5250
* By default, matches are a case insensitive.

apm-agent-core/src/main/java/co/elastic/apm/agent/bci/ElasticApmAgent.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import co.elastic.apm.agent.bci.bytebuddy.SimpleMethodSignatureOffsetMappingFactory;
3232
import co.elastic.apm.agent.bci.classloading.ExternalPluginClassLoader;
3333
import co.elastic.apm.agent.common.ThreadUtils;
34+
import co.elastic.apm.agent.common.util.SystemStandardOutputLogger;
3435
import co.elastic.apm.agent.configuration.CoreConfiguration;
3536
import co.elastic.apm.agent.impl.ElasticApmTracer;
3637
import co.elastic.apm.agent.impl.ElasticApmTracerBuilder;
@@ -243,7 +244,7 @@ private static synchronized void initInstrumentation(final ElasticApmTracer trac
243244
}
244245
System.setProperty("net.bytebuddy.dump", bytecodeDumpDir.getPath());
245246
} catch (Exception e) {
246-
System.err.println("[elastic-apm-agent] WARN Failed to create directory to dump instrumented bytecode: " + e.getMessage());
247+
SystemStandardOutputLogger.stdErrWarn("Failed to create directory to dump instrumented bytecode: " + e.getMessage());
247248
}
248249
}
249250
}

apm-agent-core/src/main/java/co/elastic/apm/agent/bci/bytebuddy/CustomElementMatchers.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
package co.elastic.apm.agent.bci.bytebuddy;
2020

2121
import co.elastic.apm.agent.matcher.AnnotationMatcher;
22-
import co.elastic.apm.agent.matcher.WildcardMatcher;
22+
import co.elastic.apm.agent.common.util.WildcardMatcher;
2323
import co.elastic.apm.agent.sdk.weakconcurrent.WeakConcurrent;
2424
import co.elastic.apm.agent.sdk.weakconcurrent.WeakMap;
2525
import co.elastic.apm.agent.util.ClassLoaderUtils;

apm-agent-core/src/main/java/co/elastic/apm/agent/collections/NullCheck.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package co.elastic.apm.agent.collections;
2020

21+
import co.elastic.apm.agent.common.util.SystemStandardOutputLogger;
2122
import co.elastic.apm.agent.sdk.logging.Logger;
2223
import co.elastic.apm.agent.sdk.logging.LoggerFactory;
2324

@@ -32,8 +33,8 @@ public class NullCheck {
3233
try {
3334
logger = LoggerFactory.getLogger(NullCheck.class);
3435
} catch (Throwable throwable) {
35-
System.err.println("[elastic-apm-agent] WARN Failed to initialize logger for the NullCheck class: " + throwable.getMessage());
36-
throwable.printStackTrace();
36+
SystemStandardOutputLogger.stdErrWarn("Failed to initialize logger for the NullCheck class: " + throwable.getMessage());
37+
SystemStandardOutputLogger.printStackTrace(throwable);
3738
}
3839
}
3940

apm-agent-core/src/main/java/co/elastic/apm/agent/configuration/CoreConfiguration.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
import co.elastic.apm.agent.impl.transaction.Span;
2828
import co.elastic.apm.agent.matcher.MethodMatcher;
2929
import co.elastic.apm.agent.matcher.MethodMatcherValueConverter;
30-
import co.elastic.apm.agent.matcher.WildcardMatcher;
30+
import co.elastic.apm.agent.common.util.WildcardMatcher;
3131
import co.elastic.apm.agent.matcher.WildcardMatcherValueConverter;
3232
import co.elastic.apm.agent.sdk.logging.Logger;
3333
import co.elastic.apm.agent.sdk.logging.LoggerFactory;

0 commit comments

Comments
 (0)