From 093134848e46258abcaa9369d1dec326d00a9bb4 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Tue, 17 Mar 2026 18:31:42 +0100 Subject: [PATCH 1/3] feat(logging): Create dedicated module for logging utils --- settings.gradle.kts | 3 +- utils/logging-utils/build.gradle.kts | 13 ++ .../main/java/datadog/logging/IOLogger.java | 137 ++++++++++++++ .../datadog/logging/RatelimitedLogger.java | 75 ++++++++ .../datadog/logging/IOLoggerTest.groovy | 167 +++++++++++++++++ .../logging/RateLimitedLoggerTest.groovy | 173 ++++++++++++++++++ 6 files changed, 567 insertions(+), 1 deletion(-) create mode 100644 utils/logging-utils/build.gradle.kts create mode 100644 utils/logging-utils/src/main/java/datadog/logging/IOLogger.java create mode 100644 utils/logging-utils/src/main/java/datadog/logging/RatelimitedLogger.java create mode 100644 utils/logging-utils/src/test/groovy/datadog/logging/IOLoggerTest.groovy create mode 100644 utils/logging-utils/src/test/groovy/datadog/logging/RateLimitedLoggerTest.groovy diff --git a/settings.gradle.kts b/settings.gradle.kts index 298c387457c..5861be60034 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -161,7 +161,8 @@ include( ":utils:container-utils", ":utils:filesystem-utils", ":utils:flare-utils", - ":utils:queue-utils", + ":utils:logging-utils", + ":utils:queue-utils",l ":utils:socket-utils", ":utils:test-agent-utils:decoder", ":utils:test-utils", diff --git a/utils/logging-utils/build.gradle.kts b/utils/logging-utils/build.gradle.kts new file mode 100644 index 00000000000..e6ab86c9e60 --- /dev/null +++ b/utils/logging-utils/build.gradle.kts @@ -0,0 +1,13 @@ +import groovy.lang.Closure +import org.gradle.kotlin.dsl.extra + +plugins { + `java-library` +} + +apply(from = "$rootDir/gradle/java.gradle") + +dependencies { + implementation(libs.slf4j) + implementation(project(":internal-api")) +} diff --git a/utils/logging-utils/src/main/java/datadog/logging/IOLogger.java b/utils/logging-utils/src/main/java/datadog/logging/IOLogger.java new file mode 100644 index 00000000000..407f7509454 --- /dev/null +++ b/utils/logging-utils/src/main/java/datadog/logging/IOLogger.java @@ -0,0 +1,137 @@ +package datadog.logging; + +import static datadog.trace.api.telemetry.LogCollector.EXCLUDE_TELEMETRY; + +import java.util.concurrent.TimeUnit; +import org.slf4j.Logger; + +/** Logger specialized on logging IO-related activity */ +public class IOLogger { + private boolean logNextSuccess = false; + private final Logger log; + private final RatelimitedLogger ratelimitedLogger; + + public IOLogger(final Logger log) { + this(log, new RatelimitedLogger(log, 5, TimeUnit.MINUTES)); + } + + // Visible for testing + IOLogger(final Logger log, final RatelimitedLogger ratelimitedLogger) { + this.log = log; + this.ratelimitedLogger = ratelimitedLogger; + } + + /** + * @return true if actually logged the message, false otherwise + */ + public boolean success(final String format, final Object... arguments) { + if (log.isDebugEnabled()) { + log.debug(EXCLUDE_TELEMETRY, format, arguments); + return true; + } + + if (this.logNextSuccess) { + this.logNextSuccess = false; + if (log.isInfoEnabled()) { + log.info(EXCLUDE_TELEMETRY, format, arguments); + return true; + } + } + + return false; + } + + /** + * @return true if actually logged the message, false otherwise + */ + public boolean error(final String message) { + return error(message, null, null); + } + + /** + * @return true if actually logged the message, false otherwise + */ + public boolean error(final String message, Exception exception) { + return error(message, null, exception); + } + + /** + * @return true if actually logged the message, false otherwise + */ + public boolean error(final String message, Response response) { + return error(message, response, null); + } + + /** + * @return true if actually logged the message, false otherwise + */ + public boolean error(final String message, Response response, Exception exception) { + if (log.isDebugEnabled()) { + if (response != null) { + log.debug( + EXCLUDE_TELEMETRY, + "{} Status: {}, Response: {}, Body: {}", + message, + response.getStatusCode(), + response.getMessage(), + response.getBody()); + } else if (exception != null) { + log.debug(EXCLUDE_TELEMETRY, message, exception); + } else { + log.debug(EXCLUDE_TELEMETRY, message); + } + return true; + } + boolean hasLogged; + if (response != null) { + hasLogged = + ratelimitedLogger.warn( + EXCLUDE_TELEMETRY, + "{} Status: {} {}", + message, + response.getStatusCode(), + response.getMessage()); + } else if (exception != null) { + // NOTE: We do not pass the full exception to warn on purpose. We don't want to + // print a full stacktrace unless we're in debug mode + hasLogged = + ratelimitedLogger.warn( + EXCLUDE_TELEMETRY, + "{} {}: {}", + message, + exception.getClass().getName(), + exception.getMessage()); + } else { + hasLogged = ratelimitedLogger.warn(message); + } + if (hasLogged) { + this.logNextSuccess = true; + } + + return hasLogged; + } + + public static final class Response { + private final int statusCode; + private final String message; + private final String body; + + public Response(int statusCode, String message, String body) { + this.statusCode = statusCode; + this.message = message; + this.body = body; + } + + public int getStatusCode() { + return statusCode; + } + + public String getMessage() { + return message; + } + + public String getBody() { + return body; + } + } +} diff --git a/utils/logging-utils/src/main/java/datadog/logging/RatelimitedLogger.java b/utils/logging-utils/src/main/java/datadog/logging/RatelimitedLogger.java new file mode 100644 index 00000000000..3e5728b6bb7 --- /dev/null +++ b/utils/logging-utils/src/main/java/datadog/logging/RatelimitedLogger.java @@ -0,0 +1,75 @@ +package datadog.logging; + +import datadog.trace.api.time.SystemTimeSource; +import datadog.trace.api.time.TimeSource; +import java.util.Locale; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicLong; +import org.slf4j.Logger; +import org.slf4j.Marker; + +/** + * Logger that logs message once per given delay if debugging is disabled. If debugging is enabled + * then it logs every time. + */ +public class RatelimitedLogger { + + private final Logger log; + private final long delayNanos; + private final String noLogMessage; + private final TimeSource timeSource; + + private final AtomicLong nextLogNanos; + + public RatelimitedLogger(final Logger log, final int delay, final TimeUnit timeUnit) { + this(log, delay, timeUnit, SystemTimeSource.INSTANCE); + } + + // Visible for testing + RatelimitedLogger( + final Logger log, final int delay, final TimeUnit timeUnit, final TimeSource timeSource) { + this.log = log; + this.delayNanos = timeUnit.toNanos(delay); + this.noLogMessage = createNoLogMessage(" (Will not log warnings for ", ")", delay, timeUnit); + this.timeSource = timeSource; + nextLogNanos = new AtomicLong(timeSource.getNanoTicks()); + } + + /** + * @return true if actually logged the message, false otherwise + */ + public boolean warn(final String format, final Object... arguments) { + return warn(null, format, arguments); + } + + public boolean warn(Marker marker, final String format, final Object... arguments) { + if (log.isDebugEnabled()) { + log.warn(marker, format, arguments); + return true; + } + if (log.isWarnEnabled()) { + final long next = nextLogNanos.get(); + final long now = timeSource.getNanoTicks(); + if (now - next >= 0 && nextLogNanos.compareAndSet(next, now + delayNanos)) { + log.warn(marker, format + noLogMessage, arguments); + return true; + } + } + return false; + } + + private static String createNoLogMessage( + String prefix, String postfix, int delay, TimeUnit timeUnit) { + StringBuilder noLogStringBuilder = new StringBuilder(prefix); + noLogStringBuilder.append(delay); + noLogStringBuilder.append(' '); + String unit = timeUnit.name().toLowerCase(Locale.ROOT); + unit = + delay == 1 + ? unit.substring(0, unit.length() - 1) + : unit; // should we drop the plural s or not? + noLogStringBuilder.append(unit); + noLogStringBuilder.append(postfix); + return noLogStringBuilder.toString(); + } +} diff --git a/utils/logging-utils/src/test/groovy/datadog/logging/IOLoggerTest.groovy b/utils/logging-utils/src/test/groovy/datadog/logging/IOLoggerTest.groovy new file mode 100644 index 00000000000..237f5a664be --- /dev/null +++ b/utils/logging-utils/src/test/groovy/datadog/logging/IOLoggerTest.groovy @@ -0,0 +1,167 @@ +package datadog.logging + +import static datadog.trace.api.telemetry.LogCollector.EXCLUDE_TELEMETRY + +import datadog.trace.test.util.DDSpecification +import org.slf4j.Logger + +class IOLoggerTest extends DDSpecification { + final response = new IOLogger.Response(404, "Not Found", + "The thing you were looking for does not exist") + final exception = new RuntimeException("Something went wrong!") + + Logger log = Mock(Logger) + RatelimitedLogger rateLimitedLogger = Mock(RatelimitedLogger) + IOLogger ioLogger = new IOLogger(log, rateLimitedLogger) + + def "Success - Debug level"() { + setup: + log.isDebugEnabled() >> true + log.isInfoEnabled() >> true + + when: + ioLogger.success("test {}", "message") + + then: + 1 * log.debug(EXCLUDE_TELEMETRY, "test {}", "message") + } + + def "Success - Info level"() { + setup: + log.isDebugEnabled() >> false + log.isInfoEnabled() >> true + + when: + ioLogger.success("test {}", "message") + + then: + 0 * log.debug(_) + 0 * log.info(_) + } + + def "Error - Debug level - Message"() { + setup: + log.isDebugEnabled() >> true + log.isInfoEnabled() >> true + + when: + ioLogger.error("test message") + + then: + 1 * log.debug(EXCLUDE_TELEMETRY, "test message") + } + + def "Error - Debug level - Response"() { + setup: + log.isDebugEnabled() >> true + log.isInfoEnabled() >> true + + when: + ioLogger.error("test message", response) + + then: + 1 * log.debug( + EXCLUDE_TELEMETRY, + _, + "test message", + 404, + "Not Found", + "The thing you were looking for does not exist" + ) + } + + def "Error - Debug level - Exception"() { + setup: + log.isDebugEnabled() >> true + log.isInfoEnabled() >> true + + when: + ioLogger.error("test message", exception) + + then: + 1 * log.debug(EXCLUDE_TELEMETRY, + "test message", + exception + ) + } + + def "Error - Info level - Message"() { + setup: + log.isDebugEnabled() >> false + log.isInfoEnabled() >> true + + when: + ioLogger.error("test message") + + then: + 1 * rateLimitedLogger.warn("test message") + } + + def "Error - Info level - Response"() { + setup: + log.isDebugEnabled() >> false + log.isInfoEnabled() >> true + + when: + ioLogger.error("test message", response) + + then: + 1 * rateLimitedLogger.warn( + EXCLUDE_TELEMETRY, + _, + "test message", + 404, + "Not Found" + ) + } + + def "Error - Info level - Exception"() { + setup: + log.isDebugEnabled() >> false + log.isInfoEnabled() >> true + + when: + ioLogger.error("test message", exception) + + then: + 1 * rateLimitedLogger.warn( + EXCLUDE_TELEMETRY, + _, + "test message", + "java.lang.RuntimeException", + "Something went wrong!" + ) + } + + def "Logged Error Then Success - Info level"() { + setup: + log.isDebugEnabled() >> false + log.isInfoEnabled() >> true + + when: + ioLogger.error("test message") + ioLogger.success("very successful") + ioLogger.success("very successful again") + + then: + 1 * rateLimitedLogger.warn("test message") >> true + 1 * log.info(EXCLUDE_TELEMETRY,"very successful") + 0 * log.info(EXCLUDE_TELEMETRY,"very successful again") + } + + def "Unlogged Error Then Success - Info level"() { + setup: + log.isDebugEnabled() >> false + log.isInfoEnabled() >> true + + when: + ioLogger.error("test message") + ioLogger.success("very successful") + ioLogger.success("very successful again") + + then: + 1 * rateLimitedLogger.warn("test message") >> false + 0 * log.info("very successful") + 0 * log.info("very successful again") + } +} diff --git a/utils/logging-utils/src/test/groovy/datadog/logging/RateLimitedLoggerTest.groovy b/utils/logging-utils/src/test/groovy/datadog/logging/RateLimitedLoggerTest.groovy new file mode 100644 index 00000000000..f45f30d54e2 --- /dev/null +++ b/utils/logging-utils/src/test/groovy/datadog/logging/RateLimitedLoggerTest.groovy @@ -0,0 +1,173 @@ +package datadog.logging + +import datadog.trace.api.telemetry.LogCollector +import datadog.trace.api.time.ControllableTimeSource +import datadog.trace.test.util.DDSpecification +import org.slf4j.Logger + +import static java.util.concurrent.TimeUnit.MILLISECONDS +import static java.util.concurrent.TimeUnit.MINUTES +import static java.util.concurrent.TimeUnit.NANOSECONDS + +class RateLimitedLoggerTest extends DDSpecification { + final exception = new RuntimeException("bad thing") + + def "Debug level"() { + setup: + Logger log = Mock(Logger) + ControllableTimeSource timeSource = new ControllableTimeSource() + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, MINUTES, timeSource) + log.isDebugEnabled() >> true + + when: + rateLimitedLog.warn("test {} {}", "message", exception) + rateLimitedLog.warn("test {} {}", "message", exception) + + then: + 2 * log.warn(null, "test {} {}", "message", exception) + } + + def "default warning once"() { + setup: + Logger log = Mock(Logger) + def defaultRateLimitedLog = new RatelimitedLogger(log, 5, MINUTES) + log.isWarnEnabled() >> true + log.isDebugEnabled() >> false + + when: + def firstLog = defaultRateLimitedLog.warn("test {} {}", "message", exception) + def secondLog = defaultRateLimitedLog.warn("test {} {}", "message", exception) + + then: + 1 * log.warn(null, "test {} {} (Will not log warnings for 5 minutes)", "message", exception) + firstLog + !secondLog + } + + + def "warning once"() { + setup: + Logger log = Mock(Logger) + ControllableTimeSource timeSource = new ControllableTimeSource() + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MINUTES, timeSource) + log.isWarnEnabled() >> true + log.isDebugEnabled() >> false + + when: + def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) + + then: + 1 * log.warn(null, "test {} {} (Will not log warnings for 1 minute)", "message", exception) + firstLog + + when: + def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) + + then: + !secondLog + } + + def "warning once negative time"() { + setup: + Logger log = Mock(Logger) + + ControllableTimeSource timeSource = new ControllableTimeSource() + timeSource.set(Long.MIN_VALUE) + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, NANOSECONDS, timeSource) + log.isWarnEnabled() >> true + log.isDebugEnabled() >> false + + when: + def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) + + then: + 1 * log.warn(null, "test {} {} (Will not log warnings for 5 nanoseconds)", "message", exception) + firstLog + + when: + timeSource.advance(5 - 1) + def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) + + then: + !secondLog + } + + def "warning once -zero- time"() { + setup: + Logger log = Mock(Logger) + + ControllableTimeSource timeSource = new ControllableTimeSource() + timeSource.set(0) + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, NANOSECONDS, timeSource) + log.isWarnEnabled() >> true + log.isDebugEnabled() >> false + + when: + def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) + + then: + 1 * log.warn(null, "test {} {} (Will not log warnings for 5 nanoseconds)", "message", exception) + firstLog + + when: + timeSource.advance(1) + def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) + + then: + !secondLog + } + + def "warning twice"() { + setup: + Logger log = Mock(Logger) + ControllableTimeSource timeSource = new ControllableTimeSource() + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 7, NANOSECONDS, timeSource) + log.isWarnEnabled() >> true + log.isDebugEnabled() >> false + + when: + def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) + + then: + 1 * log.warn(null, "test {} {} (Will not log warnings for 7 nanoseconds)", "message", exception) + firstLog + + when: + timeSource.advance(7) + def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) + + then: + 1 * log.warn(null, "test {} {} (Will not log warnings for 7 nanoseconds)", "message", exception) + secondLog + } + + def "no args"() { + setup: + Logger log = Mock(Logger) + ControllableTimeSource timeSource = new ControllableTimeSource() + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MILLISECONDS, timeSource) + log.isWarnEnabled() >> true + log.isDebugEnabled() >> false + + when: + rateLimitedLog.warn("test") + + then: + 1 * log.warn(null, "test (Will not log warnings for 1 millisecond)") + } + + def "with marker"() { + setup: + Logger log = Mock(Logger) + ControllableTimeSource timeSource = new ControllableTimeSource() + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MILLISECONDS, timeSource) + log.isWarnEnabled() >> true + log.isDebugEnabled() >> false + + when: + rateLimitedLog.warn(LogCollector.SEND_TELEMETRY, "test") + + then: + 1 * log.warn(LogCollector.SEND_TELEMETRY, "test (Will not log warnings for 1 millisecond)") + } +} From 0cd3e4eb42034bbb52e3b4dfd48900f392a903e9 Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Tue, 17 Mar 2026 19:34:20 +0100 Subject: [PATCH 2/3] feat(logging): Migrate unit tests to JUnit --- settings.gradle.kts | 2 +- utils/logging-utils/build.gradle.kts | 3 + .../datadog/logging/IOLoggerTest.groovy | 167 ---------------- .../logging/RateLimitedLoggerTest.groovy | 173 ----------------- .../java/datadog/logging/IOLoggerTest.java | 149 +++++++++++++++ .../logging/RateLimitedLoggerTest.java | 179 ++++++++++++++++++ 6 files changed, 332 insertions(+), 341 deletions(-) delete mode 100644 utils/logging-utils/src/test/groovy/datadog/logging/IOLoggerTest.groovy delete mode 100644 utils/logging-utils/src/test/groovy/datadog/logging/RateLimitedLoggerTest.groovy create mode 100644 utils/logging-utils/src/test/java/datadog/logging/IOLoggerTest.java create mode 100644 utils/logging-utils/src/test/java/datadog/logging/RateLimitedLoggerTest.java diff --git a/settings.gradle.kts b/settings.gradle.kts index 5861be60034..dbe66b33670 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -162,7 +162,7 @@ include( ":utils:filesystem-utils", ":utils:flare-utils", ":utils:logging-utils", - ":utils:queue-utils",l + ":utils:queue-utils", ":utils:socket-utils", ":utils:test-agent-utils:decoder", ":utils:test-utils", diff --git a/utils/logging-utils/build.gradle.kts b/utils/logging-utils/build.gradle.kts index e6ab86c9e60..f999e72d516 100644 --- a/utils/logging-utils/build.gradle.kts +++ b/utils/logging-utils/build.gradle.kts @@ -10,4 +10,7 @@ apply(from = "$rootDir/gradle/java.gradle") dependencies { implementation(libs.slf4j) implementation(project(":internal-api")) + + testImplementation(libs.bundles.junit5) + testImplementation(libs.bundles.mockito) } diff --git a/utils/logging-utils/src/test/groovy/datadog/logging/IOLoggerTest.groovy b/utils/logging-utils/src/test/groovy/datadog/logging/IOLoggerTest.groovy deleted file mode 100644 index 237f5a664be..00000000000 --- a/utils/logging-utils/src/test/groovy/datadog/logging/IOLoggerTest.groovy +++ /dev/null @@ -1,167 +0,0 @@ -package datadog.logging - -import static datadog.trace.api.telemetry.LogCollector.EXCLUDE_TELEMETRY - -import datadog.trace.test.util.DDSpecification -import org.slf4j.Logger - -class IOLoggerTest extends DDSpecification { - final response = new IOLogger.Response(404, "Not Found", - "The thing you were looking for does not exist") - final exception = new RuntimeException("Something went wrong!") - - Logger log = Mock(Logger) - RatelimitedLogger rateLimitedLogger = Mock(RatelimitedLogger) - IOLogger ioLogger = new IOLogger(log, rateLimitedLogger) - - def "Success - Debug level"() { - setup: - log.isDebugEnabled() >> true - log.isInfoEnabled() >> true - - when: - ioLogger.success("test {}", "message") - - then: - 1 * log.debug(EXCLUDE_TELEMETRY, "test {}", "message") - } - - def "Success - Info level"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.success("test {}", "message") - - then: - 0 * log.debug(_) - 0 * log.info(_) - } - - def "Error - Debug level - Message"() { - setup: - log.isDebugEnabled() >> true - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message") - - then: - 1 * log.debug(EXCLUDE_TELEMETRY, "test message") - } - - def "Error - Debug level - Response"() { - setup: - log.isDebugEnabled() >> true - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message", response) - - then: - 1 * log.debug( - EXCLUDE_TELEMETRY, - _, - "test message", - 404, - "Not Found", - "The thing you were looking for does not exist" - ) - } - - def "Error - Debug level - Exception"() { - setup: - log.isDebugEnabled() >> true - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message", exception) - - then: - 1 * log.debug(EXCLUDE_TELEMETRY, - "test message", - exception - ) - } - - def "Error - Info level - Message"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message") - - then: - 1 * rateLimitedLogger.warn("test message") - } - - def "Error - Info level - Response"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message", response) - - then: - 1 * rateLimitedLogger.warn( - EXCLUDE_TELEMETRY, - _, - "test message", - 404, - "Not Found" - ) - } - - def "Error - Info level - Exception"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message", exception) - - then: - 1 * rateLimitedLogger.warn( - EXCLUDE_TELEMETRY, - _, - "test message", - "java.lang.RuntimeException", - "Something went wrong!" - ) - } - - def "Logged Error Then Success - Info level"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message") - ioLogger.success("very successful") - ioLogger.success("very successful again") - - then: - 1 * rateLimitedLogger.warn("test message") >> true - 1 * log.info(EXCLUDE_TELEMETRY,"very successful") - 0 * log.info(EXCLUDE_TELEMETRY,"very successful again") - } - - def "Unlogged Error Then Success - Info level"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message") - ioLogger.success("very successful") - ioLogger.success("very successful again") - - then: - 1 * rateLimitedLogger.warn("test message") >> false - 0 * log.info("very successful") - 0 * log.info("very successful again") - } -} diff --git a/utils/logging-utils/src/test/groovy/datadog/logging/RateLimitedLoggerTest.groovy b/utils/logging-utils/src/test/groovy/datadog/logging/RateLimitedLoggerTest.groovy deleted file mode 100644 index f45f30d54e2..00000000000 --- a/utils/logging-utils/src/test/groovy/datadog/logging/RateLimitedLoggerTest.groovy +++ /dev/null @@ -1,173 +0,0 @@ -package datadog.logging - -import datadog.trace.api.telemetry.LogCollector -import datadog.trace.api.time.ControllableTimeSource -import datadog.trace.test.util.DDSpecification -import org.slf4j.Logger - -import static java.util.concurrent.TimeUnit.MILLISECONDS -import static java.util.concurrent.TimeUnit.MINUTES -import static java.util.concurrent.TimeUnit.NANOSECONDS - -class RateLimitedLoggerTest extends DDSpecification { - final exception = new RuntimeException("bad thing") - - def "Debug level"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, MINUTES, timeSource) - log.isDebugEnabled() >> true - - when: - rateLimitedLog.warn("test {} {}", "message", exception) - rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 2 * log.warn(null, "test {} {}", "message", exception) - } - - def "default warning once"() { - setup: - Logger log = Mock(Logger) - def defaultRateLimitedLog = new RatelimitedLogger(log, 5, MINUTES) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = defaultRateLimitedLog.warn("test {} {}", "message", exception) - def secondLog = defaultRateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 5 minutes)", "message", exception) - firstLog - !secondLog - } - - - def "warning once"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MINUTES, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 1 minute)", "message", exception) - firstLog - - when: - def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - !secondLog - } - - def "warning once negative time"() { - setup: - Logger log = Mock(Logger) - - ControllableTimeSource timeSource = new ControllableTimeSource() - timeSource.set(Long.MIN_VALUE) - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, NANOSECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 5 nanoseconds)", "message", exception) - firstLog - - when: - timeSource.advance(5 - 1) - def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - !secondLog - } - - def "warning once -zero- time"() { - setup: - Logger log = Mock(Logger) - - ControllableTimeSource timeSource = new ControllableTimeSource() - timeSource.set(0) - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, NANOSECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 5 nanoseconds)", "message", exception) - firstLog - - when: - timeSource.advance(1) - def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - !secondLog - } - - def "warning twice"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 7, NANOSECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 7 nanoseconds)", "message", exception) - firstLog - - when: - timeSource.advance(7) - def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 7 nanoseconds)", "message", exception) - secondLog - } - - def "no args"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MILLISECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - rateLimitedLog.warn("test") - - then: - 1 * log.warn(null, "test (Will not log warnings for 1 millisecond)") - } - - def "with marker"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MILLISECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - rateLimitedLog.warn(LogCollector.SEND_TELEMETRY, "test") - - then: - 1 * log.warn(LogCollector.SEND_TELEMETRY, "test (Will not log warnings for 1 millisecond)") - } -} diff --git a/utils/logging-utils/src/test/java/datadog/logging/IOLoggerTest.java b/utils/logging-utils/src/test/java/datadog/logging/IOLoggerTest.java new file mode 100644 index 00000000000..4712e147a9c --- /dev/null +++ b/utils/logging-utils/src/test/java/datadog/logging/IOLoggerTest.java @@ -0,0 +1,149 @@ +package datadog.logging; + +import static datadog.trace.api.telemetry.LogCollector.EXCLUDE_TELEMETRY; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.Marker; + +class IOLoggerTest { + final IOLogger.Response response = + new IOLogger.Response(404, "Not Found", "The thing you were looking for does not exist"); + final RuntimeException exception = new RuntimeException("Something went wrong!"); + + Logger log; + RatelimitedLogger rateLimitedLogger; + IOLogger ioLogger; + + @BeforeEach + void setUp() { + log = mock(Logger.class); + rateLimitedLogger = mock(RatelimitedLogger.class); + ioLogger = new IOLogger(log, rateLimitedLogger); + } + + @Test + void successDebugLevel() { + when(log.isDebugEnabled()).thenReturn(true); + + ioLogger.success("test {}", "message"); + + verify(log).debug(eq(EXCLUDE_TELEMETRY), eq("test {}"), (Object[]) any()); + } + + @Test + void successInfoLevel() { + when(log.isDebugEnabled()).thenReturn(false); + + ioLogger.success("test {}", "message"); + + verify(log, never()).debug(nullable(Marker.class), anyString(), (Object[]) any()); + verify(log, never()).info(nullable(Marker.class), anyString(), (Object[]) any()); + } + + @Test + void errorDebugLevelMessage() { + when(log.isDebugEnabled()).thenReturn(true); + + ioLogger.error("test message"); + + verify(log).debug(EXCLUDE_TELEMETRY, "test message"); + } + + @Test + void errorDebugLevelResponse() { + when(log.isDebugEnabled()).thenReturn(true); + + ioLogger.error("test message", response); + + verify(log) + .debug( + eq(EXCLUDE_TELEMETRY), + anyString(), + eq("test message"), + eq(404), + eq("Not Found"), + eq("The thing you were looking for does not exist")); + } + + @Test + void errorDebugLevelException() { + when(log.isDebugEnabled()).thenReturn(true); + + ioLogger.error("test message", exception); + + verify(log).debug(EXCLUDE_TELEMETRY, "test message", exception); + } + + @Test + void errorInfoLevelMessage() { + when(log.isDebugEnabled()).thenReturn(false); + + ioLogger.error("test message"); + + verify(rateLimitedLogger).warn("test message"); + } + + @Test + void errorInfoLevelResponse() { + when(log.isDebugEnabled()).thenReturn(false); + + ioLogger.error("test message", response); + + verify(rateLimitedLogger) + .warn(eq(EXCLUDE_TELEMETRY), anyString(), eq("test message"), eq(404), eq("Not Found")); + } + + @Test + void errorInfoLevelException() { + when(log.isDebugEnabled()).thenReturn(false); + + ioLogger.error("test message", exception); + + verify(rateLimitedLogger) + .warn( + eq(EXCLUDE_TELEMETRY), + anyString(), + eq("test message"), + eq("java.lang.RuntimeException"), + eq("Something went wrong!")); + } + + @Test + void loggedErrorThenSuccessInfoLevel() { + when(log.isDebugEnabled()).thenReturn(false); + when(log.isInfoEnabled()).thenReturn(true); + when(rateLimitedLogger.warn("test message")).thenReturn(true); + + ioLogger.error("test message"); + ioLogger.success("very successful"); + ioLogger.success("very successful again"); + + verify(rateLimitedLogger).warn("test message"); + verify(log).info(eq(EXCLUDE_TELEMETRY), eq("very successful"), (Object[]) any()); + verify(log, never()).info(eq(EXCLUDE_TELEMETRY), eq("very successful again"), (Object[]) any()); + } + + @Test + void unloggedErrorThenSuccessInfoLevel() { + when(log.isDebugEnabled()).thenReturn(false); + when(log.isInfoEnabled()).thenReturn(true); + when(rateLimitedLogger.warn("test message")).thenReturn(false); + + ioLogger.error("test message"); + ioLogger.success("very successful"); + ioLogger.success("very successful again"); + + verify(rateLimitedLogger).warn("test message"); + verify(log, never()).info(nullable(Marker.class), anyString(), (Object[]) any()); + } +} diff --git a/utils/logging-utils/src/test/java/datadog/logging/RateLimitedLoggerTest.java b/utils/logging-utils/src/test/java/datadog/logging/RateLimitedLoggerTest.java new file mode 100644 index 00000000000..ad3c5515a99 --- /dev/null +++ b/utils/logging-utils/src/test/java/datadog/logging/RateLimitedLoggerTest.java @@ -0,0 +1,179 @@ +package datadog.logging; + +import static java.util.concurrent.TimeUnit.MILLISECONDS; +import static java.util.concurrent.TimeUnit.MINUTES; +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.ArgumentMatchers.nullable; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +import datadog.trace.api.telemetry.LogCollector; +import datadog.trace.api.time.ControllableTimeSource; +import org.junit.jupiter.api.Test; +import org.slf4j.Logger; +import org.slf4j.Marker; + +class RateLimitedLoggerTest { + final RuntimeException exception = new RuntimeException("bad thing"); + + @Test + void debugLevel() { + Logger log = mock(Logger.class); + ControllableTimeSource timeSource = new ControllableTimeSource(); + when(log.isDebugEnabled()).thenReturn(true); + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, MINUTES, timeSource); + + rateLimitedLog.warn("test {} {}", "message", exception); + rateLimitedLog.warn("test {} {}", "message", exception); + + verify(log, times(2)).warn(nullable(Marker.class), eq("test {} {}"), (Object[]) any()); + } + + @Test + void defaultWarningOnce() { + Logger log = mock(Logger.class); + when(log.isWarnEnabled()).thenReturn(true); + when(log.isDebugEnabled()).thenReturn(false); + RatelimitedLogger defaultRateLimitedLog = new RatelimitedLogger(log, 5, MINUTES); + + boolean firstLog = defaultRateLimitedLog.warn("test {} {}", "message", exception); + boolean secondLog = defaultRateLimitedLog.warn("test {} {}", "message", exception); + + verify(log) + .warn( + nullable(Marker.class), + eq("test {} {} (Will not log warnings for 5 minutes)"), + (Object[]) any()); + assertTrue(firstLog); + assertFalse(secondLog); + } + + @Test + void warningOnce() { + Logger log = mock(Logger.class); + ControllableTimeSource timeSource = new ControllableTimeSource(); + when(log.isWarnEnabled()).thenReturn(true); + when(log.isDebugEnabled()).thenReturn(false); + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MINUTES, timeSource); + + boolean firstLog = rateLimitedLog.warn("test {} {}", "message", exception); + assertTrue(firstLog); + + boolean secondLog = rateLimitedLog.warn("test {} {}", "message", exception); + assertFalse(secondLog); + + verify(log) + .warn( + nullable(Marker.class), + eq("test {} {} (Will not log warnings for 1 minute)"), + (Object[]) any()); + } + + @Test + void warningOnceNegativeTime() { + Logger log = mock(Logger.class); + ControllableTimeSource timeSource = new ControllableTimeSource(); + timeSource.set(Long.MIN_VALUE); + when(log.isWarnEnabled()).thenReturn(true); + when(log.isDebugEnabled()).thenReturn(false); + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, NANOSECONDS, timeSource); + + boolean firstLog = rateLimitedLog.warn("test {} {}", "message", exception); + assertTrue(firstLog); + + timeSource.advance(5 - 1); + boolean secondLog = rateLimitedLog.warn("test {} {}", "message", exception); + assertFalse(secondLog); + + verify(log) + .warn( + nullable(Marker.class), + eq("test {} {} (Will not log warnings for 5 nanoseconds)"), + (Object[]) any()); + } + + @Test + void warningOnceZeroTime() { + Logger log = mock(Logger.class); + ControllableTimeSource timeSource = new ControllableTimeSource(); + timeSource.set(0); + when(log.isWarnEnabled()).thenReturn(true); + when(log.isDebugEnabled()).thenReturn(false); + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, NANOSECONDS, timeSource); + + boolean firstLog = rateLimitedLog.warn("test {} {}", "message", exception); + assertTrue(firstLog); + + timeSource.advance(1); + boolean secondLog = rateLimitedLog.warn("test {} {}", "message", exception); + assertFalse(secondLog); + + verify(log) + .warn( + nullable(Marker.class), + eq("test {} {} (Will not log warnings for 5 nanoseconds)"), + (Object[]) any()); + } + + @Test + void warningTwice() { + Logger log = mock(Logger.class); + ControllableTimeSource timeSource = new ControllableTimeSource(); + when(log.isWarnEnabled()).thenReturn(true); + when(log.isDebugEnabled()).thenReturn(false); + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 7, NANOSECONDS, timeSource); + + boolean firstLog = rateLimitedLog.warn("test {} {}", "message", exception); + assertTrue(firstLog); + + timeSource.advance(7); + boolean secondLog = rateLimitedLog.warn("test {} {}", "message", exception); + assertTrue(secondLog); + + verify(log, times(2)) + .warn( + nullable(Marker.class), + eq("test {} {} (Will not log warnings for 7 nanoseconds)"), + (Object[]) any()); + } + + @Test + void noArgs() { + Logger log = mock(Logger.class); + ControllableTimeSource timeSource = new ControllableTimeSource(); + when(log.isWarnEnabled()).thenReturn(true); + when(log.isDebugEnabled()).thenReturn(false); + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MILLISECONDS, timeSource); + + rateLimitedLog.warn("test"); + + verify(log) + .warn( + nullable(Marker.class), + eq("test (Will not log warnings for 1 millisecond)"), + (Object[]) any()); + } + + @Test + void withMarker() { + Logger log = mock(Logger.class); + ControllableTimeSource timeSource = new ControllableTimeSource(); + when(log.isWarnEnabled()).thenReturn(true); + when(log.isDebugEnabled()).thenReturn(false); + RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MILLISECONDS, timeSource); + + rateLimitedLog.warn(LogCollector.SEND_TELEMETRY, "test"); + + verify(log) + .warn( + eq(LogCollector.SEND_TELEMETRY), + eq("test (Will not log warnings for 1 millisecond)"), + (Object[]) any()); + } +} From 529fc8ae6ce2362092094837803189ae9f6dc16f Mon Sep 17 00:00:00 2001 From: Bruce Bujon Date: Tue, 17 Mar 2026 20:53:44 +0100 Subject: [PATCH 3/3] feat(logging): Migrate to logging-utils module --- dd-java-agent/agent-debugger/build.gradle | 1 + .../debugger/agent/ConfigurationUpdater.java | 2 +- .../debugger/sink/ProbeStatusSink.java | 2 +- .../debugger/uploader/BatchUploader.java | 2 +- .../debugger/util/ExceptionHelper.java | 2 +- .../debugger/uploader/BatchUploaderTest.java | 2 +- .../debugger/util/ExceptionHelperTest.java | 2 +- .../agent-otel/otel-bootstrap/build.gradle | 2 + .../otel/metrics/data/OtelMetricStorage.java | 2 +- .../agent-otel/otel-shim/build.gradle | 1 + .../shim/metrics/OtelDoubleCounter.java | 2 +- .../shim/metrics/OtelDoubleHistogram.java | 2 +- .../shim/metrics/OtelLongCounter.java | 2 +- .../shim/metrics/OtelLongHistogram.java | 2 +- .../shim/metrics/OtelObservableCallback.java | 2 +- .../metrics/OtelObservableMeasurement.java | 2 +- .../profiling-uploader/build.gradle | 1 + .../profiling/uploader/ProfileUploader.java | 2 +- .../profiling/uploader/util/JfrCliHelper.java | 2 +- .../uploader/ProfileUploaderTest.java | 2 +- .../uploader/util/JfrCliHelperTest.java | 2 +- dd-java-agent/build.gradle | 7 +- .../test/BootstrapClasspathSetupListener.java | 2 +- dd-trace-core/build.gradle | 1 + .../trace/common/writer/RemoteApi.java | 2 +- .../trace/common/writer/RemoteWriter.java | 2 +- .../java/datadog/trace/core/CoreTracer.java | 2 +- .../propagation/ptags/DatadogPTagsCodec.java | 2 +- .../core/propagation/ptags/W3CPTagsCodec.java | 2 +- .../scopemanager/ContinuableScopeManager.java | 2 +- gradle/dependencies.gradle | 1 + .../datadog/trace/relocate/api/IOLogger.java | 137 -------------- .../trace/relocate/api/RatelimitedLogger.java | 75 -------- .../trace/relocate/api/IOLoggerTest.groovy | 167 ----------------- .../relocate/api/RateLimitedLoggerTest.groovy | 173 ------------------ products/metrics/metrics-lib/build.gradle.kts | 1 + .../impl/statsd/DDAgentStatsDConnection.java | 2 +- .../remote-config-core/build.gradle.kts | 1 + .../DefaultConfigurationPoller.java | 2 +- .../datadog/remoteconfig/ExceptionHelper.java | 2 +- .../remoteconfig/state/ProductState.java | 2 +- utils/socket-utils/build.gradle.kts | 1 + .../socket/UnixDomainSocketFactory.java | 2 +- 43 files changed, 44 insertions(+), 583 deletions(-) delete mode 100644 internal-api/src/main/java/datadog/trace/relocate/api/IOLogger.java delete mode 100644 internal-api/src/main/java/datadog/trace/relocate/api/RatelimitedLogger.java delete mode 100644 internal-api/src/test/groovy/datadog/trace/relocate/api/IOLoggerTest.groovy delete mode 100644 internal-api/src/test/groovy/datadog/trace/relocate/api/RateLimitedLoggerTest.groovy diff --git a/dd-java-agent/agent-debugger/build.gradle b/dd-java-agent/agent-debugger/build.gradle index 5fbf978ade7..c6e229c9689 100644 --- a/dd-java-agent/agent-debugger/build.gradle +++ b/dd-java-agent/agent-debugger/build.gradle @@ -36,6 +36,7 @@ dependencies { implementation libs.slf4j implementation libs.bundles.asm implementation project(':internal-api') + implementation project(':utils:logging-utils') implementation project(':communication') implementation project(':products:metrics:metrics-lib') compileOnly project(':dd-java-agent:agent-tooling') diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ConfigurationUpdater.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ConfigurationUpdater.java index 8858425992a..a02a40a1ac4 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ConfigurationUpdater.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/agent/ConfigurationUpdater.java @@ -14,12 +14,12 @@ import com.datadog.debugger.util.ExceptionHelper; import com.datadog.debugger.util.SpringHelper; import datadog.environment.JavaVirtualMachine; +import datadog.logging.RatelimitedLogger; import datadog.trace.api.Config; import datadog.trace.bootstrap.debugger.DebuggerContext; import datadog.trace.bootstrap.debugger.ProbeId; import datadog.trace.bootstrap.debugger.ProbeImplementation; import datadog.trace.bootstrap.debugger.ProbeRateLimiter; -import datadog.trace.relocate.api.RatelimitedLogger; import datadog.trace.util.TagsHelper; import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/ProbeStatusSink.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/ProbeStatusSink.java index 1a8958a8a96..6a17a522b0e 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/ProbeStatusSink.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/sink/ProbeStatusSink.java @@ -10,9 +10,9 @@ import com.datadog.debugger.util.ExceptionHelper; import com.datadog.debugger.util.MoshiHelper; import com.squareup.moshi.JsonAdapter; +import datadog.logging.RatelimitedLogger; import datadog.trace.api.Config; import datadog.trace.bootstrap.debugger.ProbeId; -import datadog.trace.relocate.api.RatelimitedLogger; import java.time.Clock; import java.time.Duration; import java.time.Instant; diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/uploader/BatchUploader.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/uploader/BatchUploader.java index 3d478707e67..63ff0ef8dcc 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/uploader/BatchUploader.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/uploader/BatchUploader.java @@ -5,8 +5,8 @@ import com.datadog.debugger.util.DebuggerMetrics; import datadog.common.container.ContainerInfo; import datadog.communication.http.OkHttpUtils; +import datadog.logging.RatelimitedLogger; import datadog.trace.api.Config; -import datadog.trace.relocate.api.RatelimitedLogger; import datadog.trace.util.AgentThreadFactory; import java.io.IOException; import java.time.Duration; diff --git a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/util/ExceptionHelper.java b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/util/ExceptionHelper.java index f7113318bfb..b4ca9e2a4e2 100644 --- a/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/util/ExceptionHelper.java +++ b/dd-java-agent/agent-debugger/src/main/java/com/datadog/debugger/util/ExceptionHelper.java @@ -1,6 +1,6 @@ package com.datadog.debugger.util; -import datadog.trace.relocate.api.RatelimitedLogger; +import datadog.logging.RatelimitedLogger; import java.io.PrintWriter; import java.io.StringWriter; import java.io.Writer; diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/uploader/BatchUploaderTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/uploader/BatchUploaderTest.java index 2b89cee558c..1eb7cf59ddf 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/uploader/BatchUploaderTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/uploader/BatchUploaderTest.java @@ -12,8 +12,8 @@ import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import datadog.logging.RatelimitedLogger; import datadog.trace.api.Config; -import datadog.trace.relocate.api.RatelimitedLogger; import java.io.IOException; import java.net.ConnectException; import java.net.ServerSocket; diff --git a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/util/ExceptionHelperTest.java b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/util/ExceptionHelperTest.java index 3160a17c72f..9f3f246667a 100644 --- a/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/util/ExceptionHelperTest.java +++ b/dd-java-agent/agent-debugger/src/test/java/com/datadog/debugger/util/ExceptionHelperTest.java @@ -7,7 +7,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.when; -import datadog.trace.relocate.api.RatelimitedLogger; +import datadog.logging.RatelimitedLogger; import java.util.ArrayDeque; import java.util.Deque; import org.junit.jupiter.api.Test; diff --git a/dd-java-agent/agent-otel/otel-bootstrap/build.gradle b/dd-java-agent/agent-otel/otel-bootstrap/build.gradle index 8c697165f96..d62b3fa9815 100644 --- a/dd-java-agent/agent-otel/otel-bootstrap/build.gradle +++ b/dd-java-agent/agent-otel/otel-bootstrap/build.gradle @@ -73,6 +73,8 @@ dependencies { embeddedClasspath group: 'io.opentelemetry.javaagent.instrumentation', name: 'opentelemetry-javaagent-servlet-common-bootstrap', version: "$otelInstrumentationApiVersion-alpha" compileOnly project(':dd-java-agent:agent-bootstrap') + + implementation project(':utils:logging-utils') } tasks.named("shadowJar", ShadowJar) { diff --git a/dd-java-agent/agent-otel/otel-bootstrap/src/main/java/datadog/trace/bootstrap/otel/metrics/data/OtelMetricStorage.java b/dd-java-agent/agent-otel/otel-bootstrap/src/main/java/datadog/trace/bootstrap/otel/metrics/data/OtelMetricStorage.java index fcffa0abf52..cb6cc958532 100644 --- a/dd-java-agent/agent-otel/otel-bootstrap/src/main/java/datadog/trace/bootstrap/otel/metrics/data/OtelMetricStorage.java +++ b/dd-java-agent/agent-otel/otel-bootstrap/src/main/java/datadog/trace/bootstrap/otel/metrics/data/OtelMetricStorage.java @@ -1,12 +1,12 @@ package datadog.trace.bootstrap.otel.metrics.data; +import datadog.logging.RatelimitedLogger; import datadog.trace.api.Config; import datadog.trace.api.config.OtlpConfig; import datadog.trace.bootstrap.instrumentation.api.UTF8BytesString; import datadog.trace.bootstrap.otel.metrics.OtelInstrumentDescriptor; import datadog.trace.bootstrap.otel.metrics.OtelInstrumentType; import datadog.trace.bootstrap.otel.metrics.export.OtelMetricVisitor; -import datadog.trace.relocate.api.RatelimitedLogger; import io.opentelemetry.api.common.Attributes; import java.util.List; import java.util.Map; diff --git a/dd-java-agent/agent-otel/otel-shim/build.gradle b/dd-java-agent/agent-otel/otel-shim/build.gradle index 85f8c9a9067..4a979dd1056 100644 --- a/dd-java-agent/agent-otel/otel-shim/build.gradle +++ b/dd-java-agent/agent-otel/otel-shim/build.gradle @@ -10,4 +10,5 @@ dependencies { implementation project(':products:metrics:metrics-api') implementation project(':internal-api') + implementation project(':utils:logging-utils') } diff --git a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelDoubleCounter.java b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelDoubleCounter.java index c9f11a29207..d2ab4dedbc2 100644 --- a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelDoubleCounter.java +++ b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelDoubleCounter.java @@ -3,10 +3,10 @@ import static datadog.trace.bootstrap.otel.metrics.OtelInstrumentBuilder.ofDoubles; import static datadog.trace.bootstrap.otel.metrics.OtelInstrumentType.COUNTER; +import datadog.logging.RatelimitedLogger; import datadog.trace.bootstrap.otel.metrics.OtelInstrument; import datadog.trace.bootstrap.otel.metrics.OtelInstrumentBuilder; import datadog.trace.bootstrap.otel.metrics.data.OtelMetricStorage; -import datadog.trace.relocate.api.RatelimitedLogger; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleCounter; import io.opentelemetry.api.metrics.DoubleCounterBuilder; diff --git a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelDoubleHistogram.java b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelDoubleHistogram.java index 94d161a1849..c0e950917f7 100644 --- a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelDoubleHistogram.java +++ b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelDoubleHistogram.java @@ -6,10 +6,10 @@ import static java.util.Arrays.asList; import static java.util.Collections.emptyList; +import datadog.logging.RatelimitedLogger; import datadog.trace.bootstrap.otel.metrics.OtelInstrument; import datadog.trace.bootstrap.otel.metrics.OtelInstrumentBuilder; import datadog.trace.bootstrap.otel.metrics.data.OtelMetricStorage; -import datadog.trace.relocate.api.RatelimitedLogger; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleHistogram; diff --git a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelLongCounter.java b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelLongCounter.java index 4d8c1c4603f..949c10733c4 100644 --- a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelLongCounter.java +++ b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelLongCounter.java @@ -3,10 +3,10 @@ import static datadog.trace.bootstrap.otel.metrics.OtelInstrumentBuilder.ofLongs; import static datadog.trace.bootstrap.otel.metrics.OtelInstrumentType.COUNTER; +import datadog.logging.RatelimitedLogger; import datadog.trace.bootstrap.otel.metrics.OtelInstrument; import datadog.trace.bootstrap.otel.metrics.OtelInstrumentBuilder; import datadog.trace.bootstrap.otel.metrics.data.OtelMetricStorage; -import datadog.trace.relocate.api.RatelimitedLogger; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.DoubleCounterBuilder; import io.opentelemetry.api.metrics.LongCounter; diff --git a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelLongHistogram.java b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelLongHistogram.java index 3a200f0ee7d..6543748ee26 100644 --- a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelLongHistogram.java +++ b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelLongHistogram.java @@ -6,10 +6,10 @@ import static datadog.trace.bootstrap.otel.metrics.data.OtelMetricStorage.newHistogramStorage; import static java.util.stream.Collectors.toList; +import datadog.logging.RatelimitedLogger; import datadog.trace.bootstrap.otel.metrics.OtelInstrument; import datadog.trace.bootstrap.otel.metrics.OtelInstrumentBuilder; import datadog.trace.bootstrap.otel.metrics.data.OtelMetricStorage; -import datadog.trace.relocate.api.RatelimitedLogger; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.LongHistogram; diff --git a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelObservableCallback.java b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelObservableCallback.java index 27fc36f318b..80bf2c7f47d 100644 --- a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelObservableCallback.java +++ b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelObservableCallback.java @@ -1,7 +1,7 @@ package datadog.opentelemetry.shim.metrics; +import datadog.logging.RatelimitedLogger; import datadog.trace.bootstrap.otel.metrics.data.OtelObservable; -import datadog.trace.relocate.api.RatelimitedLogger; import io.opentelemetry.api.metrics.BatchCallback; import io.opentelemetry.api.metrics.ObservableDoubleCounter; import io.opentelemetry.api.metrics.ObservableDoubleGauge; diff --git a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelObservableMeasurement.java b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelObservableMeasurement.java index 01b7c617c66..7c5888b2a53 100644 --- a/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelObservableMeasurement.java +++ b/dd-java-agent/agent-otel/otel-shim/src/main/java/datadog/opentelemetry/shim/metrics/OtelObservableMeasurement.java @@ -1,7 +1,7 @@ package datadog.opentelemetry.shim.metrics; +import datadog.logging.RatelimitedLogger; import datadog.trace.bootstrap.otel.metrics.data.OtelMetricStorage; -import datadog.trace.relocate.api.RatelimitedLogger; import io.opentelemetry.api.common.Attributes; import io.opentelemetry.api.metrics.ObservableDoubleMeasurement; import io.opentelemetry.api.metrics.ObservableLongMeasurement; diff --git a/dd-java-agent/agent-profiling/profiling-uploader/build.gradle b/dd-java-agent/agent-profiling/profiling-uploader/build.gradle index f9a03e3a917..1cd43b0e91f 100644 --- a/dd-java-agent/agent-profiling/profiling-uploader/build.gradle +++ b/dd-java-agent/agent-profiling/profiling-uploader/build.gradle @@ -24,6 +24,7 @@ dependencies { implementation project(':communication') implementation project(':internal-api') implementation project(':utils:container-utils') + implementation project(':utils:logging-utils') implementation project(':utils:socket-utils') implementation project(':utils:version-utils') diff --git a/dd-java-agent/agent-profiling/profiling-uploader/src/main/java/com/datadog/profiling/uploader/ProfileUploader.java b/dd-java-agent/agent-profiling/profiling-uploader/src/main/java/com/datadog/profiling/uploader/ProfileUploader.java index ab588da6e1a..80afc760feb 100644 --- a/dd-java-agent/agent-profiling/profiling-uploader/src/main/java/com/datadog/profiling/uploader/ProfileUploader.java +++ b/dd-java-agent/agent-profiling/profiling-uploader/src/main/java/com/datadog/profiling/uploader/ProfileUploader.java @@ -24,6 +24,7 @@ import datadog.common.container.ServerlessInfo; import datadog.common.version.VersionInfo; import datadog.communication.http.OkHttpUtils; +import datadog.logging.IOLogger; import datadog.trace.api.Config; import datadog.trace.api.DDTags; import datadog.trace.api.Platform; @@ -34,7 +35,6 @@ import datadog.trace.api.profiling.RecordingType; import datadog.trace.bootstrap.config.provider.ConfigProvider; import datadog.trace.bootstrap.instrumentation.api.Tags; -import datadog.trace.relocate.api.IOLogger; import datadog.trace.util.AgentThreadFactory; import datadog.trace.util.PidHelper; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; diff --git a/dd-java-agent/agent-profiling/profiling-uploader/src/main/java/com/datadog/profiling/uploader/util/JfrCliHelper.java b/dd-java-agent/agent-profiling/profiling-uploader/src/main/java/com/datadog/profiling/uploader/util/JfrCliHelper.java index 44f027bd264..3a306e4105b 100644 --- a/dd-java-agent/agent-profiling/profiling-uploader/src/main/java/com/datadog/profiling/uploader/util/JfrCliHelper.java +++ b/dd-java-agent/agent-profiling/profiling-uploader/src/main/java/com/datadog/profiling/uploader/util/JfrCliHelper.java @@ -4,8 +4,8 @@ import datadog.environment.JavaVirtualMachine; import datadog.environment.SystemProperties; +import datadog.logging.IOLogger; import datadog.trace.api.profiling.RecordingData; -import datadog.trace.relocate.api.IOLogger; import datadog.trace.util.AgentThreadFactory; import java.io.ByteArrayOutputStream; import java.io.File; diff --git a/dd-java-agent/agent-profiling/profiling-uploader/src/test/java/com/datadog/profiling/uploader/ProfileUploaderTest.java b/dd-java-agent/agent-profiling/profiling-uploader/src/test/java/com/datadog/profiling/uploader/ProfileUploaderTest.java index a611bd20612..4349563d177 100644 --- a/dd-java-agent/agent-profiling/profiling-uploader/src/test/java/com/datadog/profiling/uploader/ProfileUploaderTest.java +++ b/dd-java-agent/agent-profiling/profiling-uploader/src/test/java/com/datadog/profiling/uploader/ProfileUploaderTest.java @@ -41,6 +41,7 @@ import com.google.common.io.ByteStreams; import datadog.common.version.VersionInfo; import datadog.environment.JavaVirtualMachine; +import datadog.logging.IOLogger; import datadog.trace.api.Config; import datadog.trace.api.DDTags; import datadog.trace.api.ProcessTags; @@ -49,7 +50,6 @@ import datadog.trace.api.profiling.RecordingInputStream; import datadog.trace.api.profiling.RecordingType; import datadog.trace.bootstrap.config.provider.ConfigProvider; -import datadog.trace.relocate.api.IOLogger; import datadog.trace.test.util.ControllableEnvironmentVariables; import datadog.trace.util.PidHelper; import delight.fileupload.FileUpload; diff --git a/dd-java-agent/agent-profiling/profiling-uploader/src/test/java/com/datadog/profiling/uploader/util/JfrCliHelperTest.java b/dd-java-agent/agent-profiling/profiling-uploader/src/test/java/com/datadog/profiling/uploader/util/JfrCliHelperTest.java index fea7fee6e0a..fb94c5490e1 100644 --- a/dd-java-agent/agent-profiling/profiling-uploader/src/test/java/com/datadog/profiling/uploader/util/JfrCliHelperTest.java +++ b/dd-java-agent/agent-profiling/profiling-uploader/src/test/java/com/datadog/profiling/uploader/util/JfrCliHelperTest.java @@ -11,9 +11,9 @@ import datadog.environment.JavaVirtualMachine; import datadog.environment.SystemProperties; +import datadog.logging.IOLogger; import datadog.trace.api.profiling.RecordingData; import datadog.trace.api.profiling.RecordingInputStream; -import datadog.trace.relocate.api.IOLogger; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; diff --git a/dd-java-agent/build.gradle b/dd-java-agent/build.gradle index 083c79415be..d081d1330ce 100644 --- a/dd-java-agent/build.gradle +++ b/dd-java-agent/build.gradle @@ -163,8 +163,8 @@ def generalShadowJarConfig(ShadowJar shadowJarTask) { relocate 'datadog.trace.common', 'datadog.trace.agent.common' relocate 'datadog.trace.core', 'datadog.trace.agent.core' relocate 'datadog.opentracing', 'datadog.trace.agent.ot' - // shadow things in internal API that has slf4j in the API and is accessed from core - relocate 'datadog.trace.relocate', 'datadog.trace.agent.relocate' + // shadow logging-utils that has slf4j in the API and is accessed from core + relocate 'datadog.logging', 'datadog.trace.agent.logging' } } } @@ -411,6 +411,9 @@ dependencies { sharedShadowInclude project(':utils:version-utils'), { transitive = false } + sharedShadowInclude project(':utils:logging-utils'), { + transitive = false + } sharedShadowInclude project(':dd-java-agent:agent-crashtracking'), { transitive = false } diff --git a/dd-java-agent/instrumentation-testing/src/main/java/datadog/trace/agent/test/BootstrapClasspathSetupListener.java b/dd-java-agent/instrumentation-testing/src/main/java/datadog/trace/agent/test/BootstrapClasspathSetupListener.java index 476e10b356e..c5caff59c9b 100644 --- a/dd-java-agent/instrumentation-testing/src/main/java/datadog/trace/agent/test/BootstrapClasspathSetupListener.java +++ b/dd-java-agent/instrumentation-testing/src/main/java/datadog/trace/agent/test/BootstrapClasspathSetupListener.java @@ -87,7 +87,7 @@ public void launcherSessionOpened(LauncherSession session) { static { TEST_BOOTSTRAP_PREFIXES = Arrays.copyOf(BOOTSTRAP_PACKAGE_PREFIXES_COPY, BOOTSTRAP_PACKAGE_PREFIXES_COPY.length + 3); - TEST_BOOTSTRAP_PREFIXES[BOOTSTRAP_PACKAGE_PREFIXES_COPY.length] = "datadog.trace.relocate.api"; + TEST_BOOTSTRAP_PREFIXES[BOOTSTRAP_PACKAGE_PREFIXES_COPY.length] = "datadog.logging"; TEST_BOOTSTRAP_PREFIXES[BOOTSTRAP_PACKAGE_PREFIXES_COPY.length + 1] = "org.slf4j"; TEST_BOOTSTRAP_PREFIXES[BOOTSTRAP_PACKAGE_PREFIXES_COPY.length + 2] = "ch.qos.logback"; diff --git a/dd-trace-core/build.gradle b/dd-trace-core/build.gradle index 5cfceffed6f..420a533fe67 100644 --- a/dd-trace-core/build.gradle +++ b/dd-trace-core/build.gradle @@ -73,6 +73,7 @@ dependencies { implementation project(':components:json') implementation project(':utils:container-utils') implementation project(':utils:socket-utils') + implementation project(':utils:logging-utils') implementation project(':utils:queue-utils') // for span exception debugging compileOnly project(':dd-java-agent:agent-debugger:debugger-bootstrap') diff --git a/dd-trace-core/src/main/java/datadog/trace/common/writer/RemoteApi.java b/dd-trace-core/src/main/java/datadog/trace/common/writer/RemoteApi.java index 771459bd3cd..72d4562d7f1 100644 --- a/dd-trace-core/src/main/java/datadog/trace/common/writer/RemoteApi.java +++ b/dd-trace-core/src/main/java/datadog/trace/common/writer/RemoteApi.java @@ -1,6 +1,6 @@ package datadog.trace.common.writer; -import datadog.trace.relocate.api.IOLogger; +import datadog.logging.IOLogger; import java.io.IOException; import java.util.Optional; import java.util.OptionalInt; diff --git a/dd-trace-core/src/main/java/datadog/trace/common/writer/RemoteWriter.java b/dd-trace-core/src/main/java/datadog/trace/common/writer/RemoteWriter.java index 90008cad0a0..2aa8ca57ec0 100644 --- a/dd-trace-core/src/main/java/datadog/trace/common/writer/RemoteWriter.java +++ b/dd-trace-core/src/main/java/datadog/trace/common/writer/RemoteWriter.java @@ -3,9 +3,9 @@ import static datadog.trace.api.sampling.PrioritySampling.UNSET; import static java.util.concurrent.TimeUnit.MINUTES; +import datadog.logging.RatelimitedLogger; import datadog.trace.core.DDSpan; import datadog.trace.core.monitor.HealthMetrics; -import datadog.trace.relocate.api.RatelimitedLogger; import java.util.Collection; import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java index c38f4994c3a..81ea55d0a42 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/CoreTracer.java @@ -24,6 +24,7 @@ import datadog.communication.ddagent.SharedCommunicationObjects; import datadog.context.propagation.Propagators; import datadog.environment.ThreadSupport; +import datadog.logging.RatelimitedLogger; import datadog.metrics.agent.AgentMeter; import datadog.metrics.api.Monitoring; import datadog.metrics.api.Recording; @@ -104,7 +105,6 @@ import datadog.trace.core.taginterceptor.TagInterceptor; import datadog.trace.core.traceinterceptor.LatencyTraceInterceptor; import datadog.trace.lambda.LambdaHandler; -import datadog.trace.relocate.api.RatelimitedLogger; import datadog.trace.util.AgentTaskScheduler; import java.io.IOException; import java.lang.ref.WeakReference; diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/ptags/DatadogPTagsCodec.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/ptags/DatadogPTagsCodec.java index f01b3f40005..c1bcd4535a7 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/ptags/DatadogPTagsCodec.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/ptags/DatadogPTagsCodec.java @@ -1,10 +1,10 @@ package datadog.trace.core.propagation.ptags; +import datadog.logging.RatelimitedLogger; import datadog.trace.api.ProductTraceSource; import datadog.trace.core.propagation.PropagationTags; import datadog.trace.core.propagation.ptags.PTagsFactory.PTags; import datadog.trace.core.propagation.ptags.TagElement.Encoding; -import datadog.trace.relocate.api.RatelimitedLogger; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/dd-trace-core/src/main/java/datadog/trace/core/propagation/ptags/W3CPTagsCodec.java b/dd-trace-core/src/main/java/datadog/trace/core/propagation/ptags/W3CPTagsCodec.java index 31052f27846..8fe534ccfd4 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/propagation/ptags/W3CPTagsCodec.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/propagation/ptags/W3CPTagsCodec.java @@ -2,12 +2,12 @@ import static datadog.trace.api.internal.util.LongStringUtils.toHexStringPadded; +import datadog.logging.RatelimitedLogger; import datadog.trace.api.ProductTraceSource; import datadog.trace.api.sampling.PrioritySampling; import datadog.trace.core.propagation.PropagationTags; import datadog.trace.core.propagation.ptags.PTagsFactory.PTags; import datadog.trace.core.propagation.ptags.TagElement.Encoding; -import datadog.trace.relocate.api.RatelimitedLogger; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ContinuableScopeManager.java b/dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ContinuableScopeManager.java index bcbb736a931..f67d3b5d39f 100644 --- a/dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ContinuableScopeManager.java +++ b/dd-trace-core/src/main/java/datadog/trace/core/scopemanager/ContinuableScopeManager.java @@ -15,6 +15,7 @@ import datadog.context.Context; import datadog.context.ContextManager; import datadog.context.ContextScope; +import datadog.logging.RatelimitedLogger; import datadog.trace.api.Config; import datadog.trace.api.Stateful; import datadog.trace.api.scopemanager.ExtendedScopeListener; @@ -26,7 +27,6 @@ import datadog.trace.bootstrap.instrumentation.api.ProfilerContext; import datadog.trace.bootstrap.instrumentation.api.ProfilingContextIntegration; import datadog.trace.core.monitor.HealthMetrics; -import datadog.trace.relocate.api.RatelimitedLogger; import datadog.trace.util.AgentTaskScheduler; import java.util.Iterator; import java.util.List; diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index c3bc6ea3dda..3814c64f559 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -32,6 +32,7 @@ final class CachedData { exclude(project(':utils:queue-utils')) exclude(project(':utils:socket-utils')) exclude(project(':utils:time-utils')) + exclude(project(':utils:logging-utils')) exclude(project(':utils:version-utils')) exclude(project(':dd-java-agent:agent-crashtracking')) exclude(project(':dd-java-agent:ddprof-lib')) diff --git a/internal-api/src/main/java/datadog/trace/relocate/api/IOLogger.java b/internal-api/src/main/java/datadog/trace/relocate/api/IOLogger.java deleted file mode 100644 index 609006156a0..00000000000 --- a/internal-api/src/main/java/datadog/trace/relocate/api/IOLogger.java +++ /dev/null @@ -1,137 +0,0 @@ -package datadog.trace.relocate.api; - -import static datadog.trace.api.telemetry.LogCollector.EXCLUDE_TELEMETRY; - -import java.util.concurrent.TimeUnit; -import org.slf4j.Logger; - -/** Logger specialized on logging IO-related activity */ -public class IOLogger { - private boolean logNextSuccess = false; - private final Logger log; - private final RatelimitedLogger ratelimitedLogger; - - public IOLogger(final Logger log) { - this(log, new RatelimitedLogger(log, 5, TimeUnit.MINUTES)); - } - - // Visible for testing - IOLogger(final Logger log, final RatelimitedLogger ratelimitedLogger) { - this.log = log; - this.ratelimitedLogger = ratelimitedLogger; - } - - /** - * @return true if actually logged the message, false otherwise - */ - public boolean success(final String format, final Object... arguments) { - if (log.isDebugEnabled()) { - log.debug(EXCLUDE_TELEMETRY, format, arguments); - return true; - } - - if (this.logNextSuccess) { - this.logNextSuccess = false; - if (log.isInfoEnabled()) { - log.info(EXCLUDE_TELEMETRY, format, arguments); - return true; - } - } - - return false; - } - - /** - * @return true if actually logged the message, false otherwise - */ - public boolean error(final String message) { - return error(message, null, null); - } - - /** - * @return true if actually logged the message, false otherwise - */ - public boolean error(final String message, Exception exception) { - return error(message, null, exception); - } - - /** - * @return true if actually logged the message, false otherwise - */ - public boolean error(final String message, Response response) { - return error(message, response, null); - } - - /** - * @return true if actually logged the message, false otherwise - */ - public boolean error(final String message, Response response, Exception exception) { - if (log.isDebugEnabled()) { - if (response != null) { - log.debug( - EXCLUDE_TELEMETRY, - "{} Status: {}, Response: {}, Body: {}", - message, - response.getStatusCode(), - response.getMessage(), - response.getBody()); - } else if (exception != null) { - log.debug(EXCLUDE_TELEMETRY, message, exception); - } else { - log.debug(EXCLUDE_TELEMETRY, message); - } - return true; - } - boolean hasLogged; - if (response != null) { - hasLogged = - ratelimitedLogger.warn( - EXCLUDE_TELEMETRY, - "{} Status: {} {}", - message, - response.getStatusCode(), - response.getMessage()); - } else if (exception != null) { - // NOTE: We do not pass the full exception to warn on purpose. We don't want to - // print a full stacktrace unless we're in debug mode - hasLogged = - ratelimitedLogger.warn( - EXCLUDE_TELEMETRY, - "{} {}: {}", - message, - exception.getClass().getName(), - exception.getMessage()); - } else { - hasLogged = ratelimitedLogger.warn(message); - } - if (hasLogged) { - this.logNextSuccess = true; - } - - return hasLogged; - } - - public static final class Response { - private final int statusCode; - private final String message; - private final String body; - - public Response(int statusCode, String message, String body) { - this.statusCode = statusCode; - this.message = message; - this.body = body; - } - - public int getStatusCode() { - return statusCode; - } - - public String getMessage() { - return message; - } - - public String getBody() { - return body; - } - } -} diff --git a/internal-api/src/main/java/datadog/trace/relocate/api/RatelimitedLogger.java b/internal-api/src/main/java/datadog/trace/relocate/api/RatelimitedLogger.java deleted file mode 100644 index ed14ee2e52f..00000000000 --- a/internal-api/src/main/java/datadog/trace/relocate/api/RatelimitedLogger.java +++ /dev/null @@ -1,75 +0,0 @@ -package datadog.trace.relocate.api; - -import datadog.trace.api.time.SystemTimeSource; -import datadog.trace.api.time.TimeSource; -import java.util.Locale; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import org.slf4j.Logger; -import org.slf4j.Marker; - -/** - * Logger that logs message once per given delay if debugging is disabled. If debugging is enabled - * then it logs every time. - */ -public class RatelimitedLogger { - - private final Logger log; - private final long delayNanos; - private final String noLogMessage; - private final TimeSource timeSource; - - private final AtomicLong nextLogNanos; - - public RatelimitedLogger(final Logger log, final int delay, final TimeUnit timeUnit) { - this(log, delay, timeUnit, SystemTimeSource.INSTANCE); - } - - // Visible for testing - RatelimitedLogger( - final Logger log, final int delay, final TimeUnit timeUnit, final TimeSource timeSource) { - this.log = log; - this.delayNanos = timeUnit.toNanos(delay); - this.noLogMessage = createNoLogMessage(" (Will not log warnings for ", ")", delay, timeUnit); - this.timeSource = timeSource; - nextLogNanos = new AtomicLong(timeSource.getNanoTicks()); - } - - /** - * @return true if actually logged the message, false otherwise - */ - public boolean warn(final String format, final Object... arguments) { - return warn(null, format, arguments); - } - - public boolean warn(Marker marker, final String format, final Object... arguments) { - if (log.isDebugEnabled()) { - log.warn(marker, format, arguments); - return true; - } - if (log.isWarnEnabled()) { - final long next = nextLogNanos.get(); - final long now = timeSource.getNanoTicks(); - if (now - next >= 0 && nextLogNanos.compareAndSet(next, now + delayNanos)) { - log.warn(marker, format + noLogMessage, arguments); - return true; - } - } - return false; - } - - private static String createNoLogMessage( - String prefix, String postfix, int delay, TimeUnit timeUnit) { - StringBuilder noLogStringBuilder = new StringBuilder(prefix); - noLogStringBuilder.append(delay); - noLogStringBuilder.append(' '); - String unit = timeUnit.name().toLowerCase(Locale.ROOT); - unit = - delay == 1 - ? unit.substring(0, unit.length() - 1) - : unit; // should we drop the plural s or not? - noLogStringBuilder.append(unit); - noLogStringBuilder.append(postfix); - return noLogStringBuilder.toString(); - } -} diff --git a/internal-api/src/test/groovy/datadog/trace/relocate/api/IOLoggerTest.groovy b/internal-api/src/test/groovy/datadog/trace/relocate/api/IOLoggerTest.groovy deleted file mode 100644 index c78210036e6..00000000000 --- a/internal-api/src/test/groovy/datadog/trace/relocate/api/IOLoggerTest.groovy +++ /dev/null @@ -1,167 +0,0 @@ -package datadog.trace.relocate.api - -import static datadog.trace.api.telemetry.LogCollector.EXCLUDE_TELEMETRY - -import datadog.trace.test.util.DDSpecification -import org.slf4j.Logger - -class IOLoggerTest extends DDSpecification { - final response = new IOLogger.Response(404, "Not Found", - "The thing you were looking for does not exist") - final exception = new RuntimeException("Something went wrong!") - - Logger log = Mock(Logger) - RatelimitedLogger rateLimitedLogger = Mock(RatelimitedLogger) - IOLogger ioLogger = new IOLogger(log, rateLimitedLogger) - - def "Success - Debug level"() { - setup: - log.isDebugEnabled() >> true - log.isInfoEnabled() >> true - - when: - ioLogger.success("test {}", "message") - - then: - 1 * log.debug(EXCLUDE_TELEMETRY, "test {}", "message") - } - - def "Success - Info level"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.success("test {}", "message") - - then: - 0 * log.debug(_) - 0 * log.info(_) - } - - def "Error - Debug level - Message"() { - setup: - log.isDebugEnabled() >> true - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message") - - then: - 1 * log.debug(EXCLUDE_TELEMETRY, "test message") - } - - def "Error - Debug level - Response"() { - setup: - log.isDebugEnabled() >> true - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message", response) - - then: - 1 * log.debug( - EXCLUDE_TELEMETRY, - _, - "test message", - 404, - "Not Found", - "The thing you were looking for does not exist" - ) - } - - def "Error - Debug level - Exception"() { - setup: - log.isDebugEnabled() >> true - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message", exception) - - then: - 1 * log.debug(EXCLUDE_TELEMETRY, - "test message", - exception - ) - } - - def "Error - Info level - Message"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message") - - then: - 1 * rateLimitedLogger.warn("test message") - } - - def "Error - Info level - Response"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message", response) - - then: - 1 * rateLimitedLogger.warn( - EXCLUDE_TELEMETRY, - _, - "test message", - 404, - "Not Found" - ) - } - - def "Error - Info level - Exception"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message", exception) - - then: - 1 * rateLimitedLogger.warn( - EXCLUDE_TELEMETRY, - _, - "test message", - "java.lang.RuntimeException", - "Something went wrong!" - ) - } - - def "Logged Error Then Success - Info level"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message") - ioLogger.success("very successful") - ioLogger.success("very successful again") - - then: - 1 * rateLimitedLogger.warn("test message") >> true - 1 * log.info(EXCLUDE_TELEMETRY,"very successful") - 0 * log.info(EXCLUDE_TELEMETRY,"very successful again") - } - - def "Unlogged Error Then Success - Info level"() { - setup: - log.isDebugEnabled() >> false - log.isInfoEnabled() >> true - - when: - ioLogger.error("test message") - ioLogger.success("very successful") - ioLogger.success("very successful again") - - then: - 1 * rateLimitedLogger.warn("test message") >> false - 0 * log.info("very successful") - 0 * log.info("very successful again") - } -} diff --git a/internal-api/src/test/groovy/datadog/trace/relocate/api/RateLimitedLoggerTest.groovy b/internal-api/src/test/groovy/datadog/trace/relocate/api/RateLimitedLoggerTest.groovy deleted file mode 100644 index cf7c31dd809..00000000000 --- a/internal-api/src/test/groovy/datadog/trace/relocate/api/RateLimitedLoggerTest.groovy +++ /dev/null @@ -1,173 +0,0 @@ -package datadog.trace.relocate.api - -import datadog.trace.api.telemetry.LogCollector -import datadog.trace.api.time.ControllableTimeSource -import datadog.trace.test.util.DDSpecification -import org.slf4j.Logger - -import static java.util.concurrent.TimeUnit.MILLISECONDS -import static java.util.concurrent.TimeUnit.MINUTES -import static java.util.concurrent.TimeUnit.NANOSECONDS - -class RateLimitedLoggerTest extends DDSpecification { - final exception = new RuntimeException("bad thing") - - def "Debug level"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, MINUTES, timeSource) - log.isDebugEnabled() >> true - - when: - rateLimitedLog.warn("test {} {}", "message", exception) - rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 2 * log.warn(null, "test {} {}", "message", exception) - } - - def "default warning once"() { - setup: - Logger log = Mock(Logger) - def defaultRateLimitedLog = new RatelimitedLogger(log, 5, MINUTES) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = defaultRateLimitedLog.warn("test {} {}", "message", exception) - def secondLog = defaultRateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 5 minutes)", "message", exception) - firstLog - !secondLog - } - - - def "warning once"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MINUTES, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 1 minute)", "message", exception) - firstLog - - when: - def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - !secondLog - } - - def "warning once negative time"() { - setup: - Logger log = Mock(Logger) - - ControllableTimeSource timeSource = new ControllableTimeSource() - timeSource.set(Long.MIN_VALUE) - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, NANOSECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 5 nanoseconds)", "message", exception) - firstLog - - when: - timeSource.advance(5 - 1) - def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - !secondLog - } - - def "warning once -zero- time"() { - setup: - Logger log = Mock(Logger) - - ControllableTimeSource timeSource = new ControllableTimeSource() - timeSource.set(0) - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 5, NANOSECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 5 nanoseconds)", "message", exception) - firstLog - - when: - timeSource.advance(1) - def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - !secondLog - } - - def "warning twice"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 7, NANOSECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - def firstLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 7 nanoseconds)", "message", exception) - firstLog - - when: - timeSource.advance(7) - def secondLog = rateLimitedLog.warn("test {} {}", "message", exception) - - then: - 1 * log.warn(null, "test {} {} (Will not log warnings for 7 nanoseconds)", "message", exception) - secondLog - } - - def "no args"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MILLISECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - rateLimitedLog.warn("test") - - then: - 1 * log.warn(null, "test (Will not log warnings for 1 millisecond)") - } - - def "with marker"() { - setup: - Logger log = Mock(Logger) - ControllableTimeSource timeSource = new ControllableTimeSource() - RatelimitedLogger rateLimitedLog = new RatelimitedLogger(log, 1, MILLISECONDS, timeSource) - log.isWarnEnabled() >> true - log.isDebugEnabled() >> false - - when: - rateLimitedLog.warn(LogCollector.SEND_TELEMETRY, "test") - - then: - 1 * log.warn(LogCollector.SEND_TELEMETRY, "test (Will not log warnings for 1 millisecond)") - } -} diff --git a/products/metrics/metrics-lib/build.gradle.kts b/products/metrics/metrics-lib/build.gradle.kts index 4050a596b31..18deab80914 100644 --- a/products/metrics/metrics-lib/build.gradle.kts +++ b/products/metrics/metrics-lib/build.gradle.kts @@ -15,6 +15,7 @@ dependencies { implementation(libs.dogstatsd) implementation(project(":internal-api")) implementation(project(":utils:filesystem-utils")) + implementation(project(":utils:logging-utils")) implementation(group = "com.datadoghq", name = "sketches-java", version = "0.8.3") diff --git a/products/metrics/metrics-lib/src/main/java/datadog/metrics/impl/statsd/DDAgentStatsDConnection.java b/products/metrics/metrics-lib/src/main/java/datadog/metrics/impl/statsd/DDAgentStatsDConnection.java index 36f981c2830..f64fdbd285c 100644 --- a/products/metrics/metrics-lib/src/main/java/datadog/metrics/impl/statsd/DDAgentStatsDConnection.java +++ b/products/metrics/metrics-lib/src/main/java/datadog/metrics/impl/statsd/DDAgentStatsDConnection.java @@ -10,8 +10,8 @@ import com.timgroup.statsd.StatsDClientErrorHandler; import datadog.common.filesystem.Files; import datadog.environment.OperatingSystem; +import datadog.logging.IOLogger; import datadog.trace.api.Config; -import datadog.trace.relocate.api.IOLogger; import datadog.trace.util.AgentTaskScheduler; import datadog.trace.util.AgentThreadFactory; import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; diff --git a/remote-config/remote-config-core/build.gradle.kts b/remote-config/remote-config-core/build.gradle.kts index f3d0200b797..c6638c4ca06 100644 --- a/remote-config/remote-config-core/build.gradle.kts +++ b/remote-config/remote-config-core/build.gradle.kts @@ -38,6 +38,7 @@ dependencies { implementation(libs.bundles.cafe.crypto) implementation(project(":internal-api")) + implementation(project(":utils:logging-utils")) testImplementation(project(":utils:test-utils")) } diff --git a/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/DefaultConfigurationPoller.java b/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/DefaultConfigurationPoller.java index 43863d1699b..61e5fc88d77 100644 --- a/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/DefaultConfigurationPoller.java +++ b/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/DefaultConfigurationPoller.java @@ -7,6 +7,7 @@ import cafe.cryptography.ed25519.Ed25519PublicKey; import cafe.cryptography.ed25519.Ed25519Signature; import com.squareup.moshi.Moshi; +import datadog.logging.RatelimitedLogger; import datadog.remoteconfig.state.ParsedConfigKey; import datadog.remoteconfig.state.ProductListener; import datadog.remoteconfig.state.ProductState; @@ -18,7 +19,6 @@ import datadog.remoteconfig.tuf.RemoteConfigRequest.ClientInfo.ClientState.ConfigState; import datadog.remoteconfig.tuf.RemoteConfigResponse; import datadog.trace.api.Config; -import datadog.trace.relocate.api.RatelimitedLogger; import datadog.trace.util.AgentTaskScheduler; import datadog.trace.util.AgentThreadFactory; import datadog.trace.util.SizeCheckedInputStream; diff --git a/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/ExceptionHelper.java b/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/ExceptionHelper.java index 041633bc7f9..edb303992f3 100644 --- a/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/ExceptionHelper.java +++ b/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/ExceptionHelper.java @@ -1,6 +1,6 @@ package datadog.remoteconfig; -import datadog.trace.relocate.api.RatelimitedLogger; +import datadog.logging.RatelimitedLogger; import java.util.Arrays; import org.slf4j.Logger; diff --git a/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/state/ProductState.java b/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/state/ProductState.java index 91a70c7be7b..ccce0dab21c 100644 --- a/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/state/ProductState.java +++ b/remote-config/remote-config-core/src/main/java/datadog/remoteconfig/state/ProductState.java @@ -1,12 +1,12 @@ package datadog.remoteconfig.state; +import datadog.logging.RatelimitedLogger; import datadog.remoteconfig.PollingRateHinter; import datadog.remoteconfig.Product; import datadog.remoteconfig.ReportableException; import datadog.remoteconfig.tuf.MissingContentException; import datadog.remoteconfig.tuf.RemoteConfigRequest; import datadog.remoteconfig.tuf.RemoteConfigResponse; -import datadog.trace.relocate.api.RatelimitedLogger; import java.io.InterruptedIOException; import java.util.ArrayList; import java.util.Collection; diff --git a/utils/socket-utils/build.gradle.kts b/utils/socket-utils/build.gradle.kts index f572034de59..8023caf758a 100644 --- a/utils/socket-utils/build.gradle.kts +++ b/utils/socket-utils/build.gradle.kts @@ -16,6 +16,7 @@ dependencies { implementation(libs.slf4j) implementation(project(":internal-api")) implementation(project(":utils:filesystem-utils")) + implementation(project(":utils:logging-utils")) implementation(libs.jnr.unixsocket) testImplementation(files(sourceSets["main_java17"].output)) } diff --git a/utils/socket-utils/src/main/java/datadog/common/socket/UnixDomainSocketFactory.java b/utils/socket-utils/src/main/java/datadog/common/socket/UnixDomainSocketFactory.java index c41ae56abf4..38e1011c5ae 100644 --- a/utils/socket-utils/src/main/java/datadog/common/socket/UnixDomainSocketFactory.java +++ b/utils/socket-utils/src/main/java/datadog/common/socket/UnixDomainSocketFactory.java @@ -3,8 +3,8 @@ import static java.util.concurrent.TimeUnit.MINUTES; import datadog.environment.JavaVirtualMachine; +import datadog.logging.RatelimitedLogger; import datadog.trace.api.Config; -import datadog.trace.relocate.api.RatelimitedLogger; import java.io.File; import java.io.IOException; import java.net.InetAddress;