Skip to content

Commit 9b82a01

Browse files
author
Mateusz Rzeszutek
authored
Set up EarlyInitAgentConfig even earlier (#8413)
1 parent 2b7b27b commit 9b82a01

File tree

14 files changed

+120
-91
lines changed

14 files changed

+120
-91
lines changed

javaagent-internal-logging-application/src/main/java/io/opentelemetry/javaagent/logging/application/ApplicationLoggingCustomizer.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
package io.opentelemetry.javaagent.logging.application;
77

88
import com.google.auto.service.AutoService;
9-
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
109
import io.opentelemetry.javaagent.bootstrap.InternalLogger;
1110
import io.opentelemetry.javaagent.bootstrap.logging.ApplicationLoggerBridge;
1211
import io.opentelemetry.javaagent.tooling.LoggingCustomizer;
12+
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
1313

1414
@AutoService(LoggingCustomizer.class)
1515
public final class ApplicationLoggingCustomizer implements LoggingCustomizer {
@@ -20,10 +20,9 @@ public String name() {
2020
}
2121

2222
@Override
23-
public void init() {
23+
public void init(EarlyInitAgentConfig earlyConfig) {
2424
int limit =
25-
ConfigPropertiesUtil.getInt(
26-
"otel.javaagent.logging.application.logs-buffer-max-records", 2048);
25+
earlyConfig.getInt("otel.javaagent.logging.application.logs-buffer-max-records", 2048);
2726
InMemoryLogStore inMemoryLogStore = new InMemoryLogStore(limit);
2827
ApplicationLoggerFactory loggerFactory = new ApplicationLoggerFactory(inMemoryLogStore);
2928
// register a shutdown hook that'll dump the logs to stderr in case something goes wrong

javaagent-internal-logging-simple/src/main/java/io/opentelemetry/javaagent/logging/simple/Slf4jSimpleLoggingCustomizer.java

Lines changed: 3 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import com.google.auto.service.AutoService;
99
import io.opentelemetry.javaagent.bootstrap.InternalLogger;
1010
import io.opentelemetry.javaagent.tooling.LoggingCustomizer;
11-
import java.util.Locale;
11+
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
1212
import org.slf4j.LoggerFactory;
1313

1414
@AutoService(LoggingCustomizer.class)
@@ -31,12 +31,12 @@ public String name() {
3131
}
3232

3333
@Override
34-
public void init() {
34+
public void init(EarlyInitAgentConfig earlyConfig) {
3535
setSystemPropertyDefault(SIMPLE_LOGGER_SHOW_DATE_TIME_PROPERTY, "true");
3636
setSystemPropertyDefault(
3737
SIMPLE_LOGGER_DATE_TIME_FORMAT_PROPERTY, SIMPLE_LOGGER_DATE_TIME_FORMAT_DEFAULT);
3838

39-
if (isDebugMode()) {
39+
if (earlyConfig.getBoolean("otel.javaagent.debug", false)) {
4040
setSystemPropertyDefault(SIMPLE_LOGGER_DEFAULT_LOG_LEVEL_PROPERTY, "DEBUG");
4141
setSystemPropertyDefault(SIMPLE_LOGGER_PREFIX + "okhttp3.internal.http2", "INFO");
4242
}
@@ -63,26 +63,4 @@ private static void setSystemPropertyDefault(String property, String value) {
6363
System.setProperty(property, value);
6464
}
6565
}
66-
67-
/**
68-
* Determine if we should log in debug level according to otel.javaagent.debug
69-
*
70-
* @return true if we should
71-
*/
72-
private static boolean isDebugMode() {
73-
String tracerDebugLevelSysprop = "otel.javaagent.debug";
74-
String tracerDebugLevelProp = System.getProperty(tracerDebugLevelSysprop);
75-
76-
if (tracerDebugLevelProp != null) {
77-
return Boolean.parseBoolean(tracerDebugLevelProp);
78-
}
79-
80-
String tracerDebugLevelEnv =
81-
System.getenv(tracerDebugLevelSysprop.replace('.', '_').toUpperCase(Locale.ROOT));
82-
83-
if (tracerDebugLevelEnv != null) {
84-
return Boolean.parseBoolean(tracerDebugLevelEnv);
85-
}
86-
return false;
87-
}
8866
}

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ public class AgentInstaller {
8080

8181
private static final Map<String, List<Runnable>> CLASS_LOAD_CALLBACKS = new HashMap<>();
8282

83-
public static void installBytebuddyAgent(Instrumentation inst, ClassLoader extensionClassLoader) {
83+
public static void installBytebuddyAgent(
84+
Instrumentation inst, ClassLoader extensionClassLoader, EarlyInitAgentConfig earlyConfig) {
8485
addByteBuddyRawSetting();
8586

8687
Integer strictContextStressorMillis = Integer.getInteger(STRICT_CONTEXT_STRESSOR_MILLIS);
@@ -90,8 +91,7 @@ public static void installBytebuddyAgent(Instrumentation inst, ClassLoader exten
9091
}
9192

9293
logVersionInfo();
93-
EarlyInitAgentConfig agentConfig = EarlyInitAgentConfig.create();
94-
if (agentConfig.getBoolean(JAVAAGENT_ENABLED_CONFIG, true)) {
94+
if (earlyConfig.getBoolean(JAVAAGENT_ENABLED_CONFIG, true)) {
9595
setupUnsafe(inst);
9696
List<AgentListener> agentListeners = loadOrdered(AgentListener.class, extensionClassLoader);
9797
installBytebuddyAgent(inst, extensionClassLoader, agentListeners);

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentStarterImpl.java

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@
66
package io.opentelemetry.javaagent.tooling;
77

88
import io.opentelemetry.context.Context;
9-
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
109
import io.opentelemetry.instrumentation.api.internal.cache.weaklockfree.WeakConcurrentMapCleaner;
1110
import io.opentelemetry.javaagent.bootstrap.AgentInitializer;
1211
import io.opentelemetry.javaagent.bootstrap.AgentStarter;
12+
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
1313
import java.io.File;
1414
import java.lang.instrument.ClassFileTransformer;
1515
import java.lang.instrument.Instrumentation;
@@ -67,9 +67,10 @@ public boolean delayStart() {
6767

6868
@Override
6969
public void start() {
70-
extensionClassLoader = createExtensionClassLoader(getClass().getClassLoader());
70+
EarlyInitAgentConfig earlyConfig = EarlyInitAgentConfig.create();
71+
extensionClassLoader = createExtensionClassLoader(getClass().getClassLoader(), earlyConfig);
7172

72-
String loggerImplementationName = ConfigPropertiesUtil.getString("otel.javaagent.logging");
73+
String loggerImplementationName = earlyConfig.getString("otel.javaagent.logging");
7374
// default to the built-in stderr slf4j-simple logger
7475
if (loggerImplementationName == null) {
7576
loggerImplementationName = "simple";
@@ -91,8 +92,10 @@ public void start() {
9192

9293
Throwable startupError = null;
9394
try {
94-
loggingCustomizer.init();
95-
AgentInstaller.installBytebuddyAgent(instrumentation, extensionClassLoader);
95+
loggingCustomizer.init(earlyConfig);
96+
earlyConfig.logEarlyConfigErrorsIfAny();
97+
98+
AgentInstaller.installBytebuddyAgent(instrumentation, extensionClassLoader, earlyConfig);
9699
WeakConcurrentMapCleaner.start();
97100

98101
// LazyStorage reads system properties. Initialize it here where we have permissions to avoid
@@ -124,9 +127,10 @@ public ClassLoader getExtensionClassLoader() {
124127
return extensionClassLoader;
125128
}
126129

127-
private ClassLoader createExtensionClassLoader(ClassLoader agentClassLoader) {
130+
private ClassLoader createExtensionClassLoader(
131+
ClassLoader agentClassLoader, EarlyInitAgentConfig earlyConfig) {
128132
return ExtensionClassLoader.getInstance(
129-
agentClassLoader, javaagentFile, isSecurityManagerSupportEnabled);
133+
agentClassLoader, javaagentFile, isSecurityManagerSupportEnabled, earlyConfig);
130134
}
131135

132136
private static class LaunchHelperClassFileTransformer implements ClassFileTransformer {

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ExtensionClassLoader.java

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.javaagent.tooling;
77

8+
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
89
import java.io.File;
910
import java.io.FileOutputStream;
1011
import java.io.IOException;
@@ -25,6 +26,7 @@
2526
import java.util.List;
2627
import java.util.jar.JarEntry;
2728
import java.util.jar.JarFile;
29+
import javax.annotation.Nullable;
2830
import net.bytebuddy.dynamic.loading.MultipleParentClassLoader;
2931

3032
/**
@@ -36,8 +38,7 @@
3638
* MultipleParentClassLoader}.
3739
*/
3840
// TODO find a way to initialize logging before using this class
39-
// Used by AgentInitializer
40-
@SuppressWarnings({"unused", "SystemOut"})
41+
@SuppressWarnings("SystemOut")
4142
public class ExtensionClassLoader extends URLClassLoader {
4243
public static final String EXTENSIONS_CONFIG = "otel.javaagent.extensions";
4344

@@ -51,22 +52,19 @@ public class ExtensionClassLoader extends URLClassLoader {
5152
}
5253

5354
public static ClassLoader getInstance(
54-
ClassLoader parent, File javaagentFile, boolean isSecurityManagerSupportEnabled) {
55+
ClassLoader parent,
56+
File javaagentFile,
57+
boolean isSecurityManagerSupportEnabled,
58+
EarlyInitAgentConfig earlyConfig) {
5559
List<URL> extensions = new ArrayList<>();
5660

57-
includeEmbeddedExtensionsIfFound(parent, extensions, javaagentFile);
61+
includeEmbeddedExtensionsIfFound(extensions, javaagentFile);
5862

59-
extensions.addAll(
60-
parseLocation(
61-
System.getProperty(EXTENSIONS_CONFIG, System.getenv("OTEL_JAVAAGENT_EXTENSIONS")),
62-
javaagentFile));
63+
extensions.addAll(parseLocation(earlyConfig.getString(EXTENSIONS_CONFIG), javaagentFile));
6364

6465
extensions.addAll(
6566
parseLocation(
66-
System.getProperty(
67-
"otel.javaagent.experimental.extensions",
68-
System.getenv("OTEL_JAVAAGENT_EXPERIMENTAL_EXTENSIONS")),
69-
javaagentFile));
67+
earlyConfig.getString("otel.javaagent.experimental.extensions"), javaagentFile));
7068

7169
// TODO when logging is configured add warning about deprecated property
7270

@@ -81,8 +79,7 @@ public static ClassLoader getInstance(
8179
return new MultipleParentClassLoader(parent, delegates);
8280
}
8381

84-
private static void includeEmbeddedExtensionsIfFound(
85-
ClassLoader parent, List<URL> extensions, File javaagentFile) {
82+
private static void includeEmbeddedExtensionsIfFound(List<URL> extensions, File javaagentFile) {
8683
try {
8784
JarFile jarFile = new JarFile(javaagentFile, false);
8885
Enumeration<JarEntry> entryEnumeration = jarFile.entries();
@@ -132,7 +129,7 @@ private static URLClassLoader getDelegate(
132129
}
133130

134131
// visible for testing
135-
static List<URL> parseLocation(String locationName, File javaagentFile) {
132+
static List<URL> parseLocation(@Nullable String locationName, File javaagentFile) {
136133
if (locationName == null) {
137134
return Collections.emptyList();
138135
}

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/LoggingCustomizer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
package io.opentelemetry.javaagent.tooling;
77

8+
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
89
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
910

1011
// only one LoggingCustomizer is allowed, and its presence will suppress the
@@ -21,7 +22,7 @@ public interface LoggingCustomizer {
2122
// note that if this throws an exception, it will end up calling onStartupFailure, because
2223
// otherwise that exception will bubble up to OpenTelemetryAgent where a distro cannot control the
2324
// logging of it.
24-
void init();
25+
void init(EarlyInitAgentConfig earlyConfig);
2526

2627
/**
2728
* Register a callback which will be called on synchronous startup success.
@@ -34,7 +35,7 @@ public interface LoggingCustomizer {
3435

3536
/**
3637
* Register a callback which will be called on synchronous startup failure (including if {@link
37-
* #init()} fails).
38+
* #init(EarlyInitAgentConfig)} fails).
3839
*
3940
* <p>Synchronous startup may or may not include running {@link
4041
* io.opentelemetry.javaagent.extension.AgentListener#afterAgent(

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/NoopLoggingCustomizer.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
package io.opentelemetry.javaagent.tooling;
77

88
import com.google.auto.service.AutoService;
9+
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
910

1011
@AutoService(LoggingCustomizer.class)
1112
public final class NoopLoggingCustomizer implements LoggingCustomizer {
@@ -16,7 +17,7 @@ public String name() {
1617
}
1718

1819
@Override
19-
public void init() {}
20+
public void init(EarlyInitAgentConfig earlyConfig) {}
2021

2122
@Override
2223
@SuppressWarnings("SystemOut")
Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@
88
import static java.util.Collections.emptyMap;
99
import static java.util.logging.Level.SEVERE;
1010

11-
import com.google.auto.service.AutoService;
1211
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
13-
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
14-
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
1512
import java.io.File;
1613
import java.io.FileInputStream;
1714
import java.io.FileNotFoundException;
@@ -22,22 +19,20 @@
2219
import java.util.Properties;
2320
import java.util.logging.Logger;
2421
import java.util.stream.Collectors;
22+
import javax.annotation.Nullable;
2523

26-
@AutoService(AutoConfigurationCustomizerProvider.class)
27-
public final class ConfigurationFileLoader implements AutoConfigurationCustomizerProvider {
28-
29-
private static final Logger logger = Logger.getLogger(ConfigurationFileLoader.class.getName());
24+
final class ConfigurationFile {
3025

3126
static final String CONFIGURATION_FILE_PROPERTY = "otel.javaagent.configuration-file";
3227

3328
private static Map<String, String> configFileContents;
3429

35-
@Override
36-
public void customize(AutoConfigurationCustomizer autoConfiguration) {
37-
autoConfiguration.addPropertiesSupplier(ConfigurationFileLoader::getConfigFileContents);
38-
}
30+
// this class is used early, and must not use logging in most of its methods
31+
// in case any file loading/parsing error occurs, we save the error message and log it later, when
32+
// the logging subsystem is initialized
33+
@Nullable private static String fileLoadErrorMessage;
3934

40-
static Map<String, String> getConfigFileContents() {
35+
static Map<String, String> getProperties() {
4136
if (configFileContents == null) {
4237
configFileContents = loadConfigFile();
4338
}
@@ -59,7 +54,7 @@ static Map<String, String> loadConfigFile() {
5954
// Configuration properties file is optional
6055
File configurationFile = new File(configurationFilePath);
6156
if (!configurationFile.exists()) {
62-
logger.log(SEVERE, "Configuration file \"{0}\" not found.", configurationFilePath);
57+
fileLoadErrorMessage = "Configuration file \"" + configurationFilePath + "\" not found.";
6358
return emptyMap();
6459
}
6560

@@ -68,21 +63,24 @@ static Map<String, String> loadConfigFile() {
6863
new InputStreamReader(new FileInputStream(configurationFile), StandardCharsets.UTF_8)) {
6964
properties.load(reader);
7065
} catch (FileNotFoundException fnf) {
71-
logger.log(SEVERE, "Configuration file \"{0}\" not found.", configurationFilePath);
66+
fileLoadErrorMessage = "Configuration file \"" + configurationFilePath + "\" not found.";
7267
} catch (IOException ioe) {
73-
logger.log(
74-
SEVERE,
75-
"Configuration file \"{0}\" cannot be accessed or correctly parsed.",
76-
configurationFilePath);
68+
fileLoadErrorMessage =
69+
"Configuration file \""
70+
+ configurationFilePath
71+
+ "\" cannot be accessed or correctly parsed.";
7772
}
7873

7974
return properties.entrySet().stream()
8075
.collect(Collectors.toMap(e -> e.getKey().toString(), e -> e.getValue().toString()));
8176
}
8277

83-
@Override
84-
public int order() {
85-
// make sure it runs after all the user-provided customizers
86-
return Integer.MAX_VALUE;
78+
static void logErrorIfAny() {
79+
if (fileLoadErrorMessage != null) {
80+
Logger.getLogger(ConfigurationPropertiesSupplier.class.getName())
81+
.log(SEVERE, fileLoadErrorMessage);
82+
}
8783
}
84+
85+
private ConfigurationFile() {}
8886
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.tooling.config;
7+
8+
import com.google.auto.service.AutoService;
9+
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
10+
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
11+
12+
@AutoService(AutoConfigurationCustomizerProvider.class)
13+
public final class ConfigurationPropertiesSupplier implements AutoConfigurationCustomizerProvider {
14+
15+
@Override
16+
public void customize(AutoConfigurationCustomizer autoConfiguration) {
17+
autoConfiguration.addPropertiesSupplier(ConfigurationFile::getProperties);
18+
}
19+
20+
@Override
21+
public int order() {
22+
// make sure it runs after all the user-provided customizers
23+
return Integer.MAX_VALUE;
24+
}
25+
}

0 commit comments

Comments
 (0)