Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
package io.opentelemetry.javaagent.logging.application;

import com.google.auto.service.AutoService;
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
import io.opentelemetry.javaagent.bootstrap.InternalLogger;
import io.opentelemetry.javaagent.bootstrap.logging.ApplicationLoggerBridge;
import io.opentelemetry.javaagent.tooling.LoggingCustomizer;
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;

@AutoService(LoggingCustomizer.class)
public final class ApplicationLoggingCustomizer implements LoggingCustomizer {
Expand All @@ -20,10 +20,9 @@ public String name() {
}

@Override
public void init() {
public void init(EarlyInitAgentConfig earlyConfig) {
int limit =
ConfigPropertiesUtil.getInt(
"otel.javaagent.logging.application.logs-buffer-max-records", 2048);
earlyConfig.getInt("otel.javaagent.logging.application.logs-buffer-max-records", 2048);
InMemoryLogStore inMemoryLogStore = new InMemoryLogStore(limit);
ApplicationLoggerFactory loggerFactory = new ApplicationLoggerFactory(inMemoryLogStore);
// register a shutdown hook that'll dump the logs to stderr in case something goes wrong
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.bootstrap.InternalLogger;
import io.opentelemetry.javaagent.tooling.LoggingCustomizer;
import java.util.Locale;
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
import org.slf4j.LoggerFactory;

@AutoService(LoggingCustomizer.class)
Expand All @@ -31,12 +31,12 @@ public String name() {
}

@Override
public void init() {
public void init(EarlyInitAgentConfig earlyConfig) {
setSystemPropertyDefault(SIMPLE_LOGGER_SHOW_DATE_TIME_PROPERTY, "true");
setSystemPropertyDefault(
SIMPLE_LOGGER_DATE_TIME_FORMAT_PROPERTY, SIMPLE_LOGGER_DATE_TIME_FORMAT_DEFAULT);

if (isDebugMode()) {
if (earlyConfig.getBoolean("otel.javaagent.debug", false)) {
setSystemPropertyDefault(SIMPLE_LOGGER_DEFAULT_LOG_LEVEL_PROPERTY, "DEBUG");
setSystemPropertyDefault(SIMPLE_LOGGER_PREFIX + "okhttp3.internal.http2", "INFO");
}
Expand All @@ -63,26 +63,4 @@ private static void setSystemPropertyDefault(String property, String value) {
System.setProperty(property, value);
}
}

/**
* Determine if we should log in debug level according to otel.javaagent.debug
*
* @return true if we should
*/
private static boolean isDebugMode() {
String tracerDebugLevelSysprop = "otel.javaagent.debug";
String tracerDebugLevelProp = System.getProperty(tracerDebugLevelSysprop);

if (tracerDebugLevelProp != null) {
return Boolean.parseBoolean(tracerDebugLevelProp);
}

String tracerDebugLevelEnv =
System.getenv(tracerDebugLevelSysprop.replace('.', '_').toUpperCase(Locale.ROOT));

if (tracerDebugLevelEnv != null) {
return Boolean.parseBoolean(tracerDebugLevelEnv);
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ public class AgentInstaller {

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

public static void installBytebuddyAgent(Instrumentation inst, ClassLoader extensionClassLoader) {
public static void installBytebuddyAgent(
Instrumentation inst, ClassLoader extensionClassLoader, EarlyInitAgentConfig earlyConfig) {
addByteBuddyRawSetting();

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

logVersionInfo();
EarlyInitAgentConfig agentConfig = EarlyInitAgentConfig.create();
if (agentConfig.getBoolean(JAVAAGENT_ENABLED_CONFIG, true)) {
if (earlyConfig.getBoolean(JAVAAGENT_ENABLED_CONFIG, true)) {
setupUnsafe(inst);
List<AgentListener> agentListeners = loadOrdered(AgentListener.class, extensionClassLoader);
installBytebuddyAgent(inst, extensionClassLoader, agentListeners);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
package io.opentelemetry.javaagent.tooling;

import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
import io.opentelemetry.instrumentation.api.internal.cache.weaklockfree.WeakConcurrentMapCleaner;
import io.opentelemetry.javaagent.bootstrap.AgentInitializer;
import io.opentelemetry.javaagent.bootstrap.AgentStarter;
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
import java.io.File;
import java.lang.instrument.ClassFileTransformer;
import java.lang.instrument.Instrumentation;
Expand Down Expand Up @@ -67,9 +67,10 @@ public boolean delayStart() {

@Override
public void start() {
extensionClassLoader = createExtensionClassLoader(getClass().getClassLoader());
EarlyInitAgentConfig earlyConfig = EarlyInitAgentConfig.create();
extensionClassLoader = createExtensionClassLoader(getClass().getClassLoader(), earlyConfig);

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

Throwable startupError = null;
try {
loggingCustomizer.init();
AgentInstaller.installBytebuddyAgent(instrumentation, extensionClassLoader);
loggingCustomizer.init(earlyConfig);
earlyConfig.logEarlyConfigErrorsIfAny();

AgentInstaller.installBytebuddyAgent(instrumentation, extensionClassLoader, earlyConfig);
WeakConcurrentMapCleaner.start();

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

private ClassLoader createExtensionClassLoader(ClassLoader agentClassLoader) {
private ClassLoader createExtensionClassLoader(
ClassLoader agentClassLoader, EarlyInitAgentConfig earlyConfig) {
return ExtensionClassLoader.getInstance(
agentClassLoader, javaagentFile, isSecurityManagerSupportEnabled);
agentClassLoader, javaagentFile, isSecurityManagerSupportEnabled, earlyConfig);
}

private static class LaunchHelperClassFileTransformer implements ClassFileTransformer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.javaagent.tooling;

import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
Expand All @@ -25,6 +26,7 @@
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.annotation.Nullable;
import net.bytebuddy.dynamic.loading.MultipleParentClassLoader;

/**
Expand All @@ -36,8 +38,7 @@
* MultipleParentClassLoader}.
*/
// TODO find a way to initialize logging before using this class
// Used by AgentInitializer
@SuppressWarnings({"unused", "SystemOut"})
@SuppressWarnings("SystemOut")
public class ExtensionClassLoader extends URLClassLoader {
public static final String EXTENSIONS_CONFIG = "otel.javaagent.extensions";

Expand All @@ -51,22 +52,19 @@ public class ExtensionClassLoader extends URLClassLoader {
}

public static ClassLoader getInstance(
ClassLoader parent, File javaagentFile, boolean isSecurityManagerSupportEnabled) {
ClassLoader parent,
File javaagentFile,
boolean isSecurityManagerSupportEnabled,
EarlyInitAgentConfig earlyConfig) {
List<URL> extensions = new ArrayList<>();

includeEmbeddedExtensionsIfFound(parent, extensions, javaagentFile);
includeEmbeddedExtensionsIfFound(extensions, javaagentFile);

extensions.addAll(
parseLocation(
System.getProperty(EXTENSIONS_CONFIG, System.getenv("OTEL_JAVAAGENT_EXTENSIONS")),
javaagentFile));
extensions.addAll(parseLocation(earlyConfig.getString(EXTENSIONS_CONFIG), javaagentFile));

extensions.addAll(
parseLocation(
System.getProperty(
"otel.javaagent.experimental.extensions",
System.getenv("OTEL_JAVAAGENT_EXPERIMENTAL_EXTENSIONS")),
javaagentFile));
earlyConfig.getString("otel.javaagent.experimental.extensions"), javaagentFile));

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

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

private static void includeEmbeddedExtensionsIfFound(
ClassLoader parent, List<URL> extensions, File javaagentFile) {
private static void includeEmbeddedExtensionsIfFound(List<URL> extensions, File javaagentFile) {
try {
JarFile jarFile = new JarFile(javaagentFile, false);
Enumeration<JarEntry> entryEnumeration = jarFile.entries();
Expand Down Expand Up @@ -132,7 +129,7 @@ private static URLClassLoader getDelegate(
}

// visible for testing
static List<URL> parseLocation(String locationName, File javaagentFile) {
static List<URL> parseLocation(@Nullable String locationName, File javaagentFile) {
if (locationName == null) {
return Collections.emptyList();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

package io.opentelemetry.javaagent.tooling;

import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;

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

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

/**
* Register a callback which will be called on synchronous startup failure (including if {@link
* #init()} fails).
* #init(EarlyInitAgentConfig)} fails).
*
* <p>Synchronous startup may or may not include running {@link
* io.opentelemetry.javaagent.extension.AgentListener#afterAgent(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.javaagent.tooling;

import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig;

@AutoService(LoggingCustomizer.class)
public final class NoopLoggingCustomizer implements LoggingCustomizer {
Expand All @@ -16,7 +17,7 @@ public String name() {
}

@Override
public void init() {}
public void init(EarlyInitAgentConfig earlyConfig) {}

@Override
@SuppressWarnings("SystemOut")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,7 @@
import static java.util.Collections.emptyMap;
import static java.util.logging.Level.SEVERE;

import com.google.auto.service.AutoService;
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
Expand All @@ -22,22 +19,20 @@
import java.util.Properties;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import javax.annotation.Nullable;

@AutoService(AutoConfigurationCustomizerProvider.class)
public final class ConfigurationFileLoader implements AutoConfigurationCustomizerProvider {

private static final Logger logger = Logger.getLogger(ConfigurationFileLoader.class.getName());
final class ConfigurationFile {

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

private static Map<String, String> configFileContents;

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

static Map<String, String> getConfigFileContents() {
static Map<String, String> getProperties() {
if (configFileContents == null) {
configFileContents = loadConfigFile();
}
Expand All @@ -59,7 +54,7 @@ static Map<String, String> loadConfigFile() {
// Configuration properties file is optional
File configurationFile = new File(configurationFilePath);
if (!configurationFile.exists()) {
logger.log(SEVERE, "Configuration file \"{0}\" not found.", configurationFilePath);
fileLoadErrorMessage = "Configuration file \"" + configurationFilePath + "\" not found.";
return emptyMap();
}

Expand All @@ -68,21 +63,24 @@ static Map<String, String> loadConfigFile() {
new InputStreamReader(new FileInputStream(configurationFile), StandardCharsets.UTF_8)) {
properties.load(reader);
} catch (FileNotFoundException fnf) {
logger.log(SEVERE, "Configuration file \"{0}\" not found.", configurationFilePath);
fileLoadErrorMessage = "Configuration file \"" + configurationFilePath + "\" not found.";
} catch (IOException ioe) {
logger.log(
SEVERE,
"Configuration file \"{0}\" cannot be accessed or correctly parsed.",
configurationFilePath);
fileLoadErrorMessage =
"Configuration file \""
+ configurationFilePath
+ "\" cannot be accessed or correctly parsed.";
}

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

@Override
public int order() {
// make sure it runs after all the user-provided customizers
return Integer.MAX_VALUE;
static void logErrorIfAny() {
if (fileLoadErrorMessage != null) {
Logger.getLogger(ConfigurationPropertiesSupplier.class.getName())
.log(SEVERE, fileLoadErrorMessage);
}
}

private ConfigurationFile() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.tooling.config;

import com.google.auto.service.AutoService;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;

@AutoService(AutoConfigurationCustomizerProvider.class)
public final class ConfigurationPropertiesSupplier implements AutoConfigurationCustomizerProvider {

@Override
public void customize(AutoConfigurationCustomizer autoConfiguration) {
autoConfiguration.addPropertiesSupplier(ConfigurationFile::getProperties);
}

@Override
public int order() {
// make sure it runs after all the user-provided customizers
return Integer.MAX_VALUE;
}
}
Loading