From 66ace606bcff6552b380297f354b341f1aa78512 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matheus=20Andr=C3=A9?= Date: Wed, 9 Sep 2026 09:58:51 -0300 Subject: [PATCH] feat: add logging configuration support to Dapr SDK MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Matheus André --- .../ApiLoggingConfigurationSettings.java | 63 +++++++++++ .../io/dapr/testcontainers/Configuration.java | 27 ++++- .../LoggingConfigurationSettings.java | 37 +++++++ .../converter/ConfigurationYamlConverter.java | 20 ++++ .../ConfigurationYamlConverterTest.java | 101 ++++++++++++++++++ 5 files changed, 247 insertions(+), 1 deletion(-) create mode 100644 testcontainers-dapr/src/main/java/io/dapr/testcontainers/ApiLoggingConfigurationSettings.java create mode 100644 testcontainers-dapr/src/main/java/io/dapr/testcontainers/LoggingConfigurationSettings.java diff --git a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/ApiLoggingConfigurationSettings.java b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/ApiLoggingConfigurationSettings.java new file mode 100644 index 000000000..810d5866f --- /dev/null +++ b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/ApiLoggingConfigurationSettings.java @@ -0,0 +1,63 @@ +/* + * Copyright 2026 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ + +package io.dapr.testcontainers; + +/** + * Configuration settings for Dapr API logging. + * + * @see + * Dapr logging configuration + */ +public class ApiLoggingConfigurationSettings implements ConfigurationSettings { + private final Boolean enabled; + private final Boolean obfuscateUrls; + private final Boolean omitHealthChecks; + + /** + * Creates a new API logging configuration. + * + * @param enabled if true, enables API logging (default value for the {@code --enable-api-logging} daprd flag). + */ + public ApiLoggingConfigurationSettings(Boolean enabled) { + this(enabled, null, null); + } + + /** + * Creates a new API logging configuration. + * + * @param enabled if true, enables API logging (default value for the {@code --enable-api-logging} + * daprd flag). + * @param obfuscateUrls if true, obfuscates the values of URLs in HTTP API logs, logging the abstract route + * name rather than the full path being invoked. + * @param omitHealthChecks if true, calls to health check endpoints (e.g. {@code /v1.0/healthz}) are not logged + * when API logging is enabled. + */ + public ApiLoggingConfigurationSettings(Boolean enabled, Boolean obfuscateUrls, Boolean omitHealthChecks) { + this.enabled = enabled; + this.obfuscateUrls = obfuscateUrls; + this.omitHealthChecks = omitHealthChecks; + } + + public Boolean getEnabled() { + return enabled; + } + + public Boolean getObfuscateUrls() { + return obfuscateUrls; + } + + public Boolean getOmitHealthChecks() { + return omitHealthChecks; + } +} diff --git a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/Configuration.java b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/Configuration.java index 66ab4c7d6..cd410463e 100644 --- a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/Configuration.java +++ b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/Configuration.java @@ -21,10 +21,10 @@ public class Configuration { private final TracingConfigurationSettings tracing; private final AppHttpPipeline appHttpPipeline; private final MtlsConfigurationSettings mtls; + private final LoggingConfigurationSettings logging; // @TODO: add secrets https://github.com/dapr/java-sdk/issues/1280 // @TODO: add metrics https://github.com/dapr/java-sdk/issues/1281 - // @TODO: add logging https://github.com/dapr/java-sdk/issues/1282 // @TODO: add middleware httpPipeline https://github.com/dapr/java-sdk/issues/1283 // @TODO: add nameResolution https://github.com/dapr/java-sdk/issues/1284 // @TODO: add disallow components https://github.com/dapr/java-sdk/issues/1285 @@ -55,11 +55,32 @@ public Configuration( TracingConfigurationSettings tracing, AppHttpPipeline appHttpPipeline, MtlsConfigurationSettings mtls + ) { + this(name, tracing, appHttpPipeline, mtls, null); + } + + /** + * Creates a new configuration. + * + * @param name Configuration name. + * @param tracing TracingConfigParameters tracing configuration + * parameters. + * @param appHttpPipeline AppHttpPipeline middleware configuration. + * @param mtls MtlsConfigurationSettings mTLS configuration. + * @param logging LoggingConfigurationSettings logging configuration. + */ + public Configuration( + String name, + TracingConfigurationSettings tracing, + AppHttpPipeline appHttpPipeline, + MtlsConfigurationSettings mtls, + LoggingConfigurationSettings logging ) { this.name = name; this.tracing = tracing; this.appHttpPipeline = appHttpPipeline; this.mtls = mtls; + this.logging = logging; } public String getName() { @@ -77,4 +98,8 @@ public AppHttpPipeline getAppHttpPipeline() { public MtlsConfigurationSettings getMtls() { return mtls; } + + public LoggingConfigurationSettings getLogging() { + return logging; + } } diff --git a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/LoggingConfigurationSettings.java b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/LoggingConfigurationSettings.java new file mode 100644 index 000000000..8fe07adaf --- /dev/null +++ b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/LoggingConfigurationSettings.java @@ -0,0 +1,37 @@ +/* + * Copyright 2026 The Dapr Authors + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and +limitations under the License. +*/ + +package io.dapr.testcontainers; + +/** + * Configuration settings for how logging works in the Dapr runtime. + * + * @see + * Dapr logging configuration + */ +public class LoggingConfigurationSettings implements ConfigurationSettings { + private final ApiLoggingConfigurationSettings apiLogging; + + /** + * Creates a new logging configuration. + * + * @param apiLogging API logging configuration settings. + */ + public LoggingConfigurationSettings(ApiLoggingConfigurationSettings apiLogging) { + this.apiLogging = apiLogging; + } + + public ApiLoggingConfigurationSettings getApiLogging() { + return apiLogging; + } +} diff --git a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/converter/ConfigurationYamlConverter.java b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/converter/ConfigurationYamlConverter.java index 7cd502c25..ae1038af2 100644 --- a/testcontainers-dapr/src/main/java/io/dapr/testcontainers/converter/ConfigurationYamlConverter.java +++ b/testcontainers-dapr/src/main/java/io/dapr/testcontainers/converter/ConfigurationYamlConverter.java @@ -13,9 +13,11 @@ package io.dapr.testcontainers.converter; +import io.dapr.testcontainers.ApiLoggingConfigurationSettings; import io.dapr.testcontainers.AppHttpPipeline; import io.dapr.testcontainers.Configuration; import io.dapr.testcontainers.ListEntry; +import io.dapr.testcontainers.LoggingConfigurationSettings; import io.dapr.testcontainers.MtlsConfigurationSettings; import io.dapr.testcontainers.MtlsTokenValidator; import io.dapr.testcontainers.OtelTracingConfigurationSettings; @@ -117,6 +119,24 @@ public String convert(Configuration configuration) { configurationSpec.put("mtls", mtlsMap); } + LoggingConfigurationSettings logging = configuration.getLogging(); + if (logging != null) { + Map loggingMap = new LinkedHashMap<>(); + + ApiLoggingConfigurationSettings apiLogging = logging.getApiLogging(); + if (apiLogging != null) { + Map apiLoggingMap = new LinkedHashMap<>(); + + putIfNotNull(apiLoggingMap, "enabled", apiLogging.getEnabled()); + putIfNotNull(apiLoggingMap, "obfuscateURLs", apiLogging.getObfuscateUrls()); + putIfNotNull(apiLoggingMap, "omitHealthChecks", apiLogging.getOmitHealthChecks()); + + loggingMap.put("apiLogging", apiLoggingMap); + } + + configurationSpec.put("logging", loggingMap); + } + configurationProps.put("spec", configurationSpec); return mapper.dumpAsMap(configurationProps); diff --git a/testcontainers-dapr/src/test/java/io/dapr/testcontainers/converter/ConfigurationYamlConverterTest.java b/testcontainers-dapr/src/test/java/io/dapr/testcontainers/converter/ConfigurationYamlConverterTest.java index f8ca8fa30..0a9ec5af6 100644 --- a/testcontainers-dapr/src/test/java/io/dapr/testcontainers/converter/ConfigurationYamlConverterTest.java +++ b/testcontainers-dapr/src/test/java/io/dapr/testcontainers/converter/ConfigurationYamlConverterTest.java @@ -13,10 +13,12 @@ package io.dapr.testcontainers.converter; +import io.dapr.testcontainers.ApiLoggingConfigurationSettings; import io.dapr.testcontainers.AppHttpPipeline; import io.dapr.testcontainers.Configuration; import io.dapr.testcontainers.DaprContainer; import io.dapr.testcontainers.ListEntry; +import io.dapr.testcontainers.LoggingConfigurationSettings; import io.dapr.testcontainers.MtlsConfigurationSettings; import io.dapr.testcontainers.MtlsTokenValidator; import io.dapr.testcontainers.OtelTracingConfigurationSettings; @@ -238,4 +240,103 @@ public void testConfigurationWithEmptyMtlsTokenValidatorsToYaml() { assertEquals(expectedConfigurationYaml, configurationYaml); } + + @Test + public void testConfigurationWithLoggingToYaml() { + ApiLoggingConfigurationSettings apiLogging = new ApiLoggingConfigurationSettings(true, true, true); + LoggingConfigurationSettings logging = new LoggingConfigurationSettings(apiLogging); + + DaprContainer dapr = new DaprContainer(DAPR_RUNTIME_IMAGE_TAG) + .withAppName("dapr-app") + .withAppPort(8081) + .withConfiguration(new Configuration("my-config", null, null, null, logging)) + .withAppChannelAddress("host.testcontainers.internal"); + + Configuration configuration = dapr.getConfiguration(); + assertNotNull(configuration); + + String configurationYaml = converter.convert(configuration); + String expectedConfigurationYaml = + "apiVersion: dapr.io/v1alpha1\n" + + "kind: Configuration\n" + + "metadata:\n" + + " name: my-config\n" + + "spec:\n" + + " logging:\n" + + " apiLogging:\n" + + " enabled: true\n" + + " obfuscateURLs: true\n" + + " omitHealthChecks: true\n"; + + assertEquals(expectedConfigurationYaml, configurationYaml); + } + + @Test + public void testConfigurationWithMinimalLoggingToYaml() { + LoggingConfigurationSettings logging = new LoggingConfigurationSettings( + new ApiLoggingConfigurationSettings(true) + ); + + Configuration configuration = new Configuration("my-config", null, null, null, logging); + + String configurationYaml = converter.convert(configuration); + String expectedConfigurationYaml = + "apiVersion: dapr.io/v1alpha1\n" + + "kind: Configuration\n" + + "metadata:\n" + + " name: my-config\n" + + "spec:\n" + + " logging:\n" + + " apiLogging:\n" + + " enabled: true\n"; + + assertEquals(expectedConfigurationYaml, configurationYaml); + } + + @Test + public void testConfigurationWithLoggingAndMtlsToYaml() { + MtlsConfigurationSettings mtls = new MtlsConfigurationSettings(true, "24h", "15m"); + LoggingConfigurationSettings logging = new LoggingConfigurationSettings( + new ApiLoggingConfigurationSettings(true, false, true) + ); + + Configuration configuration = new Configuration("my-config", null, null, mtls, logging); + + String configurationYaml = converter.convert(configuration); + String expectedConfigurationYaml = + "apiVersion: dapr.io/v1alpha1\n" + + "kind: Configuration\n" + + "metadata:\n" + + " name: my-config\n" + + "spec:\n" + + " mtls:\n" + + " enabled: true\n" + + " workloadCertTTL: 24h\n" + + " allowedClockSkew: 15m\n" + + " logging:\n" + + " apiLogging:\n" + + " enabled: true\n" + + " obfuscateURLs: false\n" + + " omitHealthChecks: true\n"; + + assertEquals(expectedConfigurationYaml, configurationYaml); + } + + @Test + public void testConfigurationWithLoggingWithoutApiLoggingToYaml() { + LoggingConfigurationSettings logging = new LoggingConfigurationSettings(null); + + Configuration configuration = new Configuration("my-config", null, null, null, logging); + + String configurationYaml = converter.convert(configuration); + String expectedConfigurationYaml = + "apiVersion: dapr.io/v1alpha1\n" + + "kind: Configuration\n" + + "metadata:\n" + + " name: my-config\n" + + "spec:\n" + + " logging: {}\n"; + + assertEquals(expectedConfigurationYaml, configurationYaml); + } }