Skip to content

Environment component dev #9189

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

Draft
wants to merge 16 commits into
base: master
Choose a base branch
from
Draft
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 @@ -7,6 +7,7 @@
import datadog.common.container.ContainerInfo;
import datadog.common.socket.NamedPipeSocketFactory;
import datadog.common.socket.UnixDomainSocketFactory;
import datadog.environment.SystemProperties;
import datadog.trace.api.Config;
import datadog.trace.util.AgentProxySelector;
import java.io.File;
Expand Down Expand Up @@ -49,9 +50,12 @@ public final class OkHttpUtils {

private static final String DD_API_KEY = "DD-API-KEY";

private static final String JAVA_VERSION = System.getProperty("java.version", "unknown");
private static final String JAVA_VM_NAME = System.getProperty("java.vm.name", "unknown");
private static final String JAVA_VM_VENDOR = System.getProperty("java.vm.vendor", "unknown");
private static final String JAVA_VERSION =
SystemProperties.getOrDefault("java.version", "unknown");
private static final String JAVA_VM_NAME =
SystemProperties.getOrDefault("java.vm.name", "unknown");
private static final String JAVA_VM_VENDOR =
SystemProperties.getOrDefault("java.vm.vendor", "unknown");

public static OkHttpClient buildHttpClient(final HttpUrl url, final long timeoutMillis) {
return buildHttpClient(url, null, null, timeoutMillis);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package datadog.environment;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
Expand Down Expand Up @@ -32,7 +31,7 @@ private EnvironmentVariables() {}
* @return The environment variable value, {@code defaultValue} if missing, can't be retrieved or
* the environment variable name is {@code null}.
*/
public static String getOrDefault(@Nonnull String name, String defaultValue) {
public static String getOrDefault(String name, String defaultValue) {
if (name == null) {
return defaultValue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Objects;
import java.util.function.Predicate;
import java.util.stream.Stream;

/** Detects operating systems and libc library. */
public final class OperatingSystem {
private static final String OS_NAME_PROPERTY = "os.name";
private static final String OS_ARCH_PROPERTY = "os.arch";
private static final Path TEMP_DIR = Paths.get(computeTempPath());

private OperatingSystem() {}

Expand Down Expand Up @@ -146,4 +150,57 @@ private static boolean containsArray(byte[] container, int offset, byte[] contai
}
return true;
}

public static Path getTempDir() {
return TEMP_DIR;
}

private static String computeTempPath() {
if (JavaVirtualMachine.isJ9()) {
return computeJ9TempDir();
}
// See
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-gettemppatha#remarks
// and
// the JDK OS-specific implementations of os::get_temp_directory(), i.e.
// https://github.com/openjdk/jdk/blob/f50bd0d9ec65a6b9596805d0131aaefc1bb913f3/src/hotspot/os/bsd/os_bsd.cpp#L886-L904
if (OperatingSystem.isLinux()) {
return "/tmp";
} else if (OperatingSystem.isWindows()) {
return computeWindowsTempDir();
} else if (OperatingSystem.isMacOs()) {
return EnvironmentVariables.getOrDefault("TMPDIR", ".");
} else {
return SystemProperties.getOrDefault("java.io.tmpdir", ".");
}
}

private static String computeWindowsTempDir() {
return Stream.of("TMP", "TEMP", "USERPROFILE")
.map(EnvironmentVariables::get)
.filter(Objects::nonNull)
.filter(((Predicate<String>) String::isEmpty).negate())
.findFirst()
.orElse("C:\\Windows");
}

private static String computeJ9TempDir() {
try {
https: // github.com/eclipse-openj9/openj9/blob/196082df056a990756a5571bfac29585fbbfbb42/jcl/src/java.base/share/classes/openj9/internal/tools/attach/target/IPC.java#L351
return (String)
Class.forName("openj9.internal.tools.attach.target.IPC")
.getDeclaredMethod("getTmpDir")
.invoke(null);
} catch (Throwable t) {
// Fall back to constants based on J9 source code, may not have perfect coverage
String tmpDir = SystemProperties.get("java.io.tmpdir");
if (tmpDir != null && !tmpDir.isEmpty()) {
return tmpDir;
} else if (OperatingSystem.isWindows()) {
return "C:\\Documents";
} else {
return "/tmp";
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package datadog.environment;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
* Safely queries system properties against security manager.
Expand All @@ -18,7 +18,7 @@ private SystemProperties() {}
* @return The system property value, {@code null} if missing, can't be retrieved, or the system
* property name is {@code null}.
*/
public static String get(String property) {
public static @Nullable String get(String property) {
return getOrDefault(property, null);
}

Expand All @@ -31,7 +31,7 @@ public static String get(String property) {
* @return The system property value, {@code defaultValue} if missing, can't be retrieved, or the
* system property name is {@code null}.
*/
public static String getOrDefault(@Nonnull String property, String defaultValue) {
public static String getOrDefault(String property, String defaultValue) {
if (property == null) {
return defaultValue;
}
Expand All @@ -50,11 +50,32 @@ public static String getOrDefault(@Nonnull String property, String defaultValue)
* @return {@code true} if the system property was successfully set, {@code} false otherwise.
*/
public static boolean set(String property, String value) {
if (property == null || value == null) {
return false;
}
try {
System.setProperty(property, value);
return true;
} catch (SecurityException ignored) {
return false;
}
}

/**
* Clears a system property.
*
* @param property The system property name to clear.
* @return The previous value of the system property, {@code null} if there was no prior property
* and property can't be cleared.
*/
public static @Nullable String clear(String property) {
if (property == null) {
return null;
}
try {
return System.clearProperty(property);
} catch (SecurityException ignored) {
return null;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@ParametersAreNonnullByDefault
package datadog.environment;

import javax.annotation.ParametersAreNonnullByDefault;
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,29 @@ void testGetOrDefault() {

@Test
void testSet() {
String testProperty = "test.property";
String testValue = "test-value";
assumeTrue(SystemProperties.get(testProperty) == null);

String testProperty = "test.set.property";
String testValue = "test.set.value";
assertNull(SystemProperties.get(testProperty));
assertTrue(SystemProperties.set(testProperty, testValue));
assertEquals(testValue, SystemProperties.get(testProperty));
// Null values
assertDoesNotThrow(() -> SystemProperties.set(testProperty, null));
assertFalse(SystemProperties.set(testProperty, null));
assertDoesNotThrow(() -> SystemProperties.set(null, testValue));
assertFalse(SystemProperties.set(null, testValue));
}

@Test
void testClear() {
String testProperty = "test.clear.property";
String testValue = "test.clear.value";
assertNull(SystemProperties.get(testProperty));
assertNull(SystemProperties.clear(testProperty));
assumeTrue(SystemProperties.set(testProperty, testValue));
assertEquals(testValue, SystemProperties.clear(testProperty));
assertNull(SystemProperties.clear(testProperty));
// Null values
assertDoesNotThrow(() -> SystemProperties.clear(null));
assertNull(SystemProperties.clear(null));
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package datadog.trace.bootstrap.benchmark;

import datadog.environment.SystemProperties;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Objects;
Expand All @@ -18,8 +19,8 @@ public class StaticEventLogger {
static {
BufferedWriter writer = null;

if ("true".equalsIgnoreCase(System.getProperty("dd.benchmark.enabled"))) {
String dir = System.getProperty("dd.benchmark.output.dir");
if ("true".equalsIgnoreCase(SystemProperties.get("dd.benchmark.enabled"))) {
String dir = SystemProperties.get("dd.benchmark.output.dir");
dir = (dir != null ? dir + File.separator : "");
String fileName = dir + "startup_" + System.currentTimeMillis() + ".csv";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import static datadog.trace.agent.tooling.bytebuddy.matcher.GlobalIgnoresMatcher.globalIgnoresMatcher;
import static net.bytebuddy.matcher.ElementMatchers.isDefaultFinalizer;

import datadog.environment.SystemProperties;
import datadog.trace.agent.tooling.bytebuddy.SharedTypePools;
import datadog.trace.agent.tooling.bytebuddy.iast.TaintableRedefinitionStrategyListener;
import datadog.trace.agent.tooling.bytebuddy.matcher.DDElementMatchers;
Expand Down Expand Up @@ -318,18 +319,17 @@ public static Set<InstrumenterModule.TargetSystem> getEnabledSystems() {
}

private static void addByteBuddyRawSetting() {
final String savedPropertyValue = System.getProperty(TypeDefinition.RAW_TYPES_PROPERTY);
try {
System.setProperty(TypeDefinition.RAW_TYPES_PROPERTY, "true");
final String savedPropertyValue = SystemProperties.get(TypeDefinition.RAW_TYPES_PROPERTY);
if (SystemProperties.set(TypeDefinition.RAW_TYPES_PROPERTY, "true")) {
final boolean rawTypes = TypeDescription.AbstractBase.RAW_TYPES;
if (!rawTypes && DEBUG) {
log.debug("Too late to enable {}", TypeDefinition.RAW_TYPES_PROPERTY);
}
} finally {
} else {
if (savedPropertyValue == null) {
System.clearProperty(TypeDefinition.RAW_TYPES_PROPERTY);
SystemProperties.clear(TypeDefinition.RAW_TYPES_PROPERTY);
} else {
System.setProperty(TypeDefinition.RAW_TYPES_PROPERTY, savedPropertyValue);
SystemProperties.set(TypeDefinition.RAW_TYPES_PROPERTY, savedPropertyValue);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,17 +144,17 @@ private static GitClient.Factory buildGitClientFactory(

@Nonnull
private static CiEnvironment buildCiEnvironment(Config config, SharedCommunicationObjects sco) {
CiEnvironment localEnvironment = CiEnvironmentImpl.local();
String remoteEnvVarsProviderUrl = config.getCiVisibilityRemoteEnvVarsProviderUrl();
if (remoteEnvVarsProviderUrl != null) {
String remoteEnvVarsProviderKey = config.getCiVisibilityRemoteEnvVarsProviderKey();
CiEnvironment remoteEnvironment =
new CiEnvironmentImpl(
getRemoteEnvironment(
remoteEnvVarsProviderUrl, remoteEnvVarsProviderKey, sco.okHttpClient));
CiEnvironment localEnvironment = new CiEnvironmentImpl(System.getenv());
return new CompositeCiEnvironment(remoteEnvironment, localEnvironment);
} else {
return new CiEnvironmentImpl(System.getenv());
return localEnvironment;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package datadog.trace.civisibility;

import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_SIGNAL_SERVER_HOST;
import static datadog.trace.api.config.CiVisibilityConfig.CIVISIBILITY_SIGNAL_SERVER_PORT;
import static datadog.trace.bootstrap.instrumentation.api.AgentPropagation.extractContextAndGetSpanContext;
import static datadog.trace.util.Strings.propertyNameToSystemPropertyName;

import datadog.trace.api.config.CiVisibilityConfig;
import datadog.environment.SystemProperties;
import datadog.trace.bootstrap.instrumentation.api.AgentPropagation;
import datadog.trace.bootstrap.instrumentation.api.AgentSpanContext;
import datadog.trace.util.Strings;
import java.net.InetSocketAddress;
import java.util.Properties;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -69,8 +71,8 @@ private boolean isWrapper() {
}

private boolean isMavenParent() {
return System.getProperty("maven.home") != null
&& System.getProperty("classworlds.conf") != null
return SystemProperties.get("maven.home") != null
&& SystemProperties.get("classworlds.conf") != null
// when using Maven Wrapper
|| ClassLoader.getSystemClassLoader()
.getResource("org/apache/maven/wrapper/WrapperExecutor.class")
Expand All @@ -82,7 +84,7 @@ private boolean isGradleDaemon() {
.getResource("org/gradle/launcher/daemon/bootstrap/GradleDaemon.class")
!= null
// double-check this is not a Gradle Worker
&& System.getProperties().getProperty("org.gradle.internal.worker.tmpdir") == null;
&& SystemProperties.get("org.gradle.internal.worker.tmpdir") == null;
}

private boolean isGradleLauncher() {
Expand All @@ -93,16 +95,12 @@ private boolean isGradleLauncher() {

@Nullable
public InetSocketAddress getSignalServerAddress() {
// System.getProperty is used rather than Config,
// System properties are used rather than Config,
// because system variables can be set after config was initialized
String host =
System.getProperty(
Strings.propertyNameToSystemPropertyName(
CiVisibilityConfig.CIVISIBILITY_SIGNAL_SERVER_HOST));
SystemProperties.get(propertyNameToSystemPropertyName(CIVISIBILITY_SIGNAL_SERVER_HOST));
String port =
System.getProperty(
Strings.propertyNameToSystemPropertyName(
CiVisibilityConfig.CIVISIBILITY_SIGNAL_SERVER_PORT));
SystemProperties.get(propertyNameToSystemPropertyName(CIVISIBILITY_SIGNAL_SERVER_PORT));
if (host != null && port != null) {
return new InetSocketAddress(host, Integer.parseInt(port));
} else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package datadog.trace.civisibility.ci.env;

import java.util.Collections;
import java.util.Map;

public class CiEnvironmentImpl implements CiEnvironment {
Expand All @@ -10,6 +11,16 @@ public CiEnvironmentImpl(Map<String, String> env) {
this.env = env;
}

public static CiEnvironment local() {
Map<String, String> env;
try {
env = System.getenv();
} catch (SecurityException e) {
env = Collections.emptyMap();
}
return new CiEnvironmentImpl(env);
}

@Override
public String get(String name) {
return env.get(name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,18 @@ private Map<String, String> getPropertiesPropagatedToChildProcess(
ExecutionSettings executionSettings,
BuildSessionSettings sessionSettings) {
Map<String, String> propagatedSystemProperties = new HashMap<>();
Properties systemProperties = System.getProperties();
for (Map.Entry<Object, Object> e : systemProperties.entrySet()) {
String propertyName = (String) e.getKey();
Object propertyValue = e.getValue();
if ((propertyName.startsWith(Config.PREFIX)
|| propertyName.startsWith("datadog.slf4j.simpleLogger.defaultLogLevel"))
&& propertyValue != null) {
propagatedSystemProperties.put(propertyName, propertyValue.toString());
try {
Properties systemProperties = System.getProperties();
for (Map.Entry<Object, Object> e : systemProperties.entrySet()) {
String propertyName = (String) e.getKey();
Object propertyValue = e.getValue();
if ((propertyName.startsWith(Config.PREFIX)
|| propertyName.startsWith("datadog.slf4j.simpleLogger.defaultLogLevel"))
&& propertyValue != null) {
propagatedSystemProperties.put(propertyName, propertyValue.toString());
}
}
} catch (SecurityException ignored) {
}

propagatedSystemProperties.put(
Expand Down
Loading