From 4496df13baff4cb512a8c1908b5e0f3834f682bf Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Fri, 17 Apr 2026 17:17:58 -0400 Subject: [PATCH 1/4] Improve cloud environment detection logic --- .../com/datadog/ServerlessCompatAgent.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/datadog/ServerlessCompatAgent.java b/src/main/java/com/datadog/ServerlessCompatAgent.java index b3732f4..9b0d076 100644 --- a/src/main/java/com/datadog/ServerlessCompatAgent.java +++ b/src/main/java/com/datadog/ServerlessCompatAgent.java @@ -7,6 +7,8 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -16,6 +18,7 @@ enum CloudEnvironment { AZURE_FUNCTION, AZURE_SPRING_APP, GOOGLE_CLOUD_RUN_FUNCTION_1ST_GEN, + GOOGLE_CLOUD_RUN_FUNCTION_2ND_GEN, UNKNOWN } @@ -51,22 +54,37 @@ public static boolean isLinux() { public static CloudEnvironment getEnvironment() { Map env = System.getenv(); + List detected = new ArrayList<>(); - if (env.get("FUNCTIONS_EXTENSION_VERSION") != null && - env.get("FUNCTIONS_WORKER_RUNTIME") != null) { - return CloudEnvironment.AZURE_FUNCTION; + if (env.get("FUNCTIONS_EXTENSION_VERSION") != null + && env.get("FUNCTIONS_WORKER_RUNTIME") != null) { + detected.add(CloudEnvironment.AZURE_FUNCTION); } if (env.get("ASCSVCRT_SPRING__APPLICATION__NAME") != null) { - return CloudEnvironment.AZURE_SPRING_APP; + detected.add(CloudEnvironment.AZURE_SPRING_APP); } - if (env.get("FUNCTION_NAME") != null && - env.get("GCP_PROJECT") != null) { - return CloudEnvironment.GOOGLE_CLOUD_RUN_FUNCTION_1ST_GEN; + if (env.get("K_SERVICE") != null && env.get("FUNCTION_TARGET") != null) { + // Set by Google Cloud Functions for newer runtimes + detected.add(CloudEnvironment.GOOGLE_CLOUD_RUN_FUNCTION_2ND_GEN); + } else if (env.get("FUNCTION_NAME") != null && env.get("GCP_PROJECT") != null) { + // Set by Google Cloud Functions for older runtimes + detected.add(CloudEnvironment.GOOGLE_CLOUD_RUN_FUNCTION_1ST_GEN); } - return CloudEnvironment.UNKNOWN; + if (detected.isEmpty()) { + log.error("No cloud environment detected"); + return CloudEnvironment.UNKNOWN; + } + if (detected.size() > 1) { + log.error("Multiple cloud environments detected: {}. Returning UNKNOWN.", detected); + return CloudEnvironment.UNKNOWN; + } + + CloudEnvironment environment = detected.get(0); + log.debug("Detected cloud environment: {}", environment); + return environment; } public static String getPackageVersion() { From 8a113ad561e652bce1fc64e5d9e649115d33af55 Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Mon, 20 Apr 2026 14:35:53 -0400 Subject: [PATCH 2/4] Improve cloud environment detection logic --- src/main/java/com/datadog/ServerlessCompatAgent.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/com/datadog/ServerlessCompatAgent.java b/src/main/java/com/datadog/ServerlessCompatAgent.java index 9b0d076..3d288ca 100644 --- a/src/main/java/com/datadog/ServerlessCompatAgent.java +++ b/src/main/java/com/datadog/ServerlessCompatAgent.java @@ -74,7 +74,6 @@ public static CloudEnvironment getEnvironment() { } if (detected.isEmpty()) { - log.error("No cloud environment detected"); return CloudEnvironment.UNKNOWN; } if (detected.size() > 1) { @@ -83,7 +82,6 @@ public static CloudEnvironment getEnvironment() { } CloudEnvironment environment = detected.get(0); - log.debug("Detected cloud environment: {}", environment); return environment; } From c359922cb2c88595973e45bbe950bef8cb341300 Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Mon, 20 Apr 2026 15:41:58 -0400 Subject: [PATCH 3/4] Add unit tests --- .../com/datadog/ServerlessCompatAgent.java | 7 +- .../datadog/ServerlessCompatAgentTest.java | 116 ++++++++++++++++++ src/test/java/test.java | 34 ----- 3 files changed, 121 insertions(+), 36 deletions(-) create mode 100644 src/test/java/com/datadog/ServerlessCompatAgentTest.java delete mode 100644 src/test/java/test.java diff --git a/src/main/java/com/datadog/ServerlessCompatAgent.java b/src/main/java/com/datadog/ServerlessCompatAgent.java index 3d288ca..a4a4d14 100644 --- a/src/main/java/com/datadog/ServerlessCompatAgent.java +++ b/src/main/java/com/datadog/ServerlessCompatAgent.java @@ -53,7 +53,10 @@ public static boolean isLinux() { } public static CloudEnvironment getEnvironment() { - Map env = System.getenv(); + return getEnvironment(System.getenv()); + } + + static CloudEnvironment getEnvironment(Map env) { List detected = new ArrayList<>(); if (env.get("FUNCTIONS_EXTENSION_VERSION") != null @@ -77,7 +80,7 @@ public static CloudEnvironment getEnvironment() { return CloudEnvironment.UNKNOWN; } if (detected.size() > 1) { - log.error("Multiple cloud environments detected: {}. Returning UNKNOWN.", detected); + log.error("Multiple cloud environments detected: {}", detected); return CloudEnvironment.UNKNOWN; } diff --git a/src/test/java/com/datadog/ServerlessCompatAgentTest.java b/src/test/java/com/datadog/ServerlessCompatAgentTest.java new file mode 100644 index 0000000..8f20a84 --- /dev/null +++ b/src/test/java/com/datadog/ServerlessCompatAgentTest.java @@ -0,0 +1,116 @@ +package com.datadog; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.slf4j.Logger; +import org.slf4j.helpers.NOPLogger; + +import static org.junit.jupiter.api.Assertions.*; + +class ServerlessCompatAgentTest { + + @ParameterizedTest + @CsvSource({ + "TRACE, TRACE", + "DEBUG, DEBUG", + "INFO, INFO", + "WARN, WARN", + "ERROR, ERROR", + "CRITICAL, ERROR", + "OFF, null" + }) + void testInitLogger(String ddLogLevel, String expectedSlf4jLevel) throws Exception { + Method initLoggerMethod = ServerlessCompatAgent.class.getDeclaredMethod("initLogger", String.class); + initLoggerMethod.setAccessible(true); + Logger logger = (Logger) initLoggerMethod.invoke(null, ddLogLevel); + + if ("OFF".equals(ddLogLevel)) { + assertTrue(logger instanceof NOPLogger); + } else { + assertEquals(expectedSlf4jLevel, + System.getProperty("org.slf4j.simpleLogger.defaultLogLevel")); + } + } + + @Test + void getEnvironment_returnsUnknownWhenNoVarsSet() { + assertEquals(CloudEnvironment.UNKNOWN, + ServerlessCompatAgent.getEnvironment(new HashMap<>())); + } + + @Test + void getEnvironment_detectsAzureFunction() { + Map env = new HashMap<>(); + env.put("FUNCTIONS_EXTENSION_VERSION", "~4"); + env.put("FUNCTIONS_WORKER_RUNTIME", "java"); + assertEquals(CloudEnvironment.AZURE_FUNCTION, + ServerlessCompatAgent.getEnvironment(env)); + } + + @Test + void getEnvironment_requiresBothAzureFunctionVars() { + Map env = new HashMap<>(); + env.put("FUNCTIONS_EXTENSION_VERSION", "~4"); + assertEquals(CloudEnvironment.UNKNOWN, + ServerlessCompatAgent.getEnvironment(env)); + } + + @Test + void getEnvironment_detectsAzureSpringApp() { + Map env = new HashMap<>(); + env.put("ASCSVCRT_SPRING__APPLICATION__NAME", "my-app"); + assertEquals(CloudEnvironment.AZURE_SPRING_APP, + ServerlessCompatAgent.getEnvironment(env)); + } + + @Test + void getEnvironment_detectsGcpOlderRuntimes() { + Map env = new HashMap<>(); + env.put("FUNCTION_NAME", "my-function"); + env.put("GCP_PROJECT", "my-project"); + assertEquals(CloudEnvironment.GOOGLE_CLOUD_RUN_FUNCTION_1ST_GEN, + ServerlessCompatAgent.getEnvironment(env)); + } + + @Test + void getEnvironment_requiresBothGcpOlderRuntimesVars() { + Map env = new HashMap<>(); + env.put("FUNCTION_NAME", "my-function"); + assertEquals(CloudEnvironment.UNKNOWN, + ServerlessCompatAgent.getEnvironment(env)); + } + + @Test + void getEnvironment_detectsGcpNewerRuntimes() { + Map env = new HashMap<>(); + env.put("K_SERVICE", "my-service"); + env.put("FUNCTION_TARGET", "handler"); + assertEquals(CloudEnvironment.GOOGLE_CLOUD_RUN_FUNCTION_2ND_GEN, + ServerlessCompatAgent.getEnvironment(env)); + } + + @Test + void getEnvironment_returnsUnknownWhenMultipleEnvironmentsDetected() { + Map env = new HashMap<>(); + env.put("FUNCTIONS_EXTENSION_VERSION", "~4"); + env.put("FUNCTIONS_WORKER_RUNTIME", "java"); + env.put("FUNCTION_NAME", "my-function"); + env.put("GCP_PROJECT", "my-project"); + assertEquals(CloudEnvironment.UNKNOWN, + ServerlessCompatAgent.getEnvironment(env)); + } + + @Test + void getEnvironment_bareFunctionNameDoesNotTriggerGcpDetection() { + Map env = new HashMap<>(); + env.put("FUNCTION_NAME", "my-function"); + env.put("FUNCTIONS_EXTENSION_VERSION", "~4"); + env.put("FUNCTIONS_WORKER_RUNTIME", "java"); + assertEquals(CloudEnvironment.AZURE_FUNCTION, + ServerlessCompatAgent.getEnvironment(env)); + } +} diff --git a/src/test/java/test.java b/src/test/java/test.java deleted file mode 100644 index 60078b5..0000000 --- a/src/test/java/test.java +++ /dev/null @@ -1,34 +0,0 @@ -import com.datadog.ServerlessCompatAgent; -import java.lang.reflect.Method; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.CsvSource; -import org.slf4j.Logger; -import org.slf4j.helpers.NOPLogger; - -import static org.junit.jupiter.api.Assertions.*; - -class ServerlessCompatAgentTest { - - @ParameterizedTest - @CsvSource({ - "TRACE, TRACE", - "DEBUG, DEBUG", - "INFO, INFO", - "WARN, WARN", - "ERROR, ERROR", - "CRITICAL, ERROR", - "OFF, null" - }) - void testInitLogger(String ddLogLevel, String expectedSlf4jLevel) throws Exception { - Method initLoggerMethod = ServerlessCompatAgent.class.getDeclaredMethod("initLogger", String.class); - initLoggerMethod.setAccessible(true); - Logger logger = (Logger) initLoggerMethod.invoke(null, ddLogLevel); - - if ("OFF".equals(ddLogLevel)) { - assertTrue(logger instanceof NOPLogger); - } else { - assertEquals(expectedSlf4jLevel, - System.getProperty("org.slf4j.simpleLogger.defaultLogLevel")); - } - } -} From 7e122c5cbdc2c926aa8028826fcae874e6df0e93 Mon Sep 17 00:00:00 2001 From: Kathie Huang Date: Wed, 22 Apr 2026 17:23:40 -0400 Subject: [PATCH 4/4] If all four env vars are present, return 1st gen --- src/main/java/com/datadog/ServerlessCompatAgent.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/datadog/ServerlessCompatAgent.java b/src/main/java/com/datadog/ServerlessCompatAgent.java index a4a4d14..97abbae 100644 --- a/src/main/java/com/datadog/ServerlessCompatAgent.java +++ b/src/main/java/com/datadog/ServerlessCompatAgent.java @@ -68,12 +68,12 @@ static CloudEnvironment getEnvironment(Map env) { detected.add(CloudEnvironment.AZURE_SPRING_APP); } - if (env.get("K_SERVICE") != null && env.get("FUNCTION_TARGET") != null) { - // Set by Google Cloud Functions for newer runtimes - detected.add(CloudEnvironment.GOOGLE_CLOUD_RUN_FUNCTION_2ND_GEN); - } else if (env.get("FUNCTION_NAME") != null && env.get("GCP_PROJECT") != null) { + if (env.get("FUNCTION_NAME") != null && env.get("GCP_PROJECT") != null) { // Set by Google Cloud Functions for older runtimes detected.add(CloudEnvironment.GOOGLE_CLOUD_RUN_FUNCTION_1ST_GEN); + } else if (env.get("K_SERVICE") != null && env.get("FUNCTION_TARGET") != null) { + // Set by Google Cloud Functions for newer runtimes + detected.add(CloudEnvironment.GOOGLE_CLOUD_RUN_FUNCTION_2ND_GEN); } if (detected.isEmpty()) {