diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/LogConsoleFormatBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/LogConsoleFormatBuildItem.java deleted file mode 100644 index a30522477735a..0000000000000 --- a/core/deployment/src/main/java/io/quarkus/deployment/builditem/LogConsoleFormatBuildItem.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.quarkus.deployment.builditem; - -import java.util.Optional; -import java.util.logging.Formatter; - -import org.wildfly.common.Assert; - -import io.quarkus.builder.item.MultiBuildItem; -import io.quarkus.runtime.RuntimeValue; - -/** - * The log console format build item. Producing this item will cause the logging subsystem to disregard its - * console logging formatting configuration and use the formatter provided instead. If multiple formatters - * are enabled at run time, a warning message is printed and only one is used. - */ -public final class LogConsoleFormatBuildItem extends MultiBuildItem { - private final RuntimeValue> formatterValue; - - /** - * Construct a new instance. - * - * @param formatterValue the optional formatter run time value to use (must not be {@code null}) - */ - public LogConsoleFormatBuildItem(final RuntimeValue> formatterValue) { - this.formatterValue = Assert.checkNotNullParam("formatterValue", formatterValue); - } - - /** - * Get the formatter value. - * - * @return the formatter value - */ - public RuntimeValue> getFormatterValue() { - return formatterValue; - } -} diff --git a/core/deployment/src/main/java/io/quarkus/deployment/builditem/NamedLogFormatsBuildItem.java b/core/deployment/src/main/java/io/quarkus/deployment/builditem/NamedLogFormatsBuildItem.java new file mode 100644 index 0000000000000..73b3b72002a0c --- /dev/null +++ b/core/deployment/src/main/java/io/quarkus/deployment/builditem/NamedLogFormatsBuildItem.java @@ -0,0 +1,38 @@ +package io.quarkus.deployment.builditem; + +import java.util.Map; +import java.util.Optional; +import java.util.logging.Formatter; + +import org.wildfly.common.Assert; + +import io.quarkus.builder.item.MultiBuildItem; +import io.quarkus.runtime.RuntimeValue; + +/** + * The named log formatters build item. Producing this item will cause the logging subsystem to disregard its + * logging formatting configuration and use the formatter provided instead. If multiple formatters + * are enabled at run time, a warning message is printed and only one is used. Reserved names are console, file, syslog, + * socket. + */ +public final class NamedLogFormatsBuildItem extends MultiBuildItem { + private final RuntimeValue>> namedFormattersValue; + + /** + * Construct a new instance. + * + * @param namedFormattersValue the optional named formatters run time value to use (must not be {@code null}) + */ + public NamedLogFormatsBuildItem(final RuntimeValue>> namedFormattersValue) { + this.namedFormattersValue = Assert.checkNotNullParam("namedFormattersValue", namedFormattersValue); + } + + /** + * Get the named formatters value. + * + * @return the named formatters value + */ + public RuntimeValue>> getNamedFormattersValue() { + return namedFormattersValue; + } +} diff --git a/core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java b/core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java index 6274bf445f727..cabb9de9d4128 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/logging/LoggingResourceProcessor.java @@ -54,8 +54,8 @@ import io.quarkus.deployment.builditem.GeneratedClassBuildItem; import io.quarkus.deployment.builditem.LaunchModeBuildItem; import io.quarkus.deployment.builditem.LogCategoryBuildItem; -import io.quarkus.deployment.builditem.LogConsoleFormatBuildItem; import io.quarkus.deployment.builditem.LogHandlerBuildItem; +import io.quarkus.deployment.builditem.NamedLogFormatsBuildItem; import io.quarkus.deployment.builditem.NamedLogHandlersBuildItem; import io.quarkus.deployment.builditem.RunTimeConfigurationDefaultBuildItem; import io.quarkus.deployment.builditem.SystemPropertyBuildItem; @@ -172,7 +172,7 @@ void miscSetup( LoggingSetupBuildItem setupLoggingRuntimeInit(LoggingSetupRecorder recorder, LogConfig log, LogBuildTimeConfig buildLog, Optional logStreamHandlerBuildItem, List handlerBuildItems, - List namedHandlerBuildItems, List consoleFormatItems, + List namedHandlerBuildItems, List formatItems, Optional possibleBannerBuildItem, List logStreamBuildItems, LaunchModeBuildItem launchModeBuildItem, @@ -205,7 +205,7 @@ LoggingSetupBuildItem setupLoggingRuntimeInit(LoggingSetupRecorder recorder, Log recorder.initializeLogging(log, buildLog, alwaysEnableLogStream, devUiLogHandler, handlers, namedHandlers, - consoleFormatItems.stream().map(LogConsoleFormatBuildItem::getFormatterValue).collect(Collectors.toList()), + formatItems.stream().map(NamedLogFormatsBuildItem::getNamedFormattersValue).collect(Collectors.toList()), possibleSupplier, launchModeBuildItem.getLaunchMode()); LogConfig logConfig = new LogConfig(); ConfigInstantiator.handleObject(logConfig); @@ -232,7 +232,7 @@ public void run() { @BuildStep(onlyIfNot = IsNormal.class) @Produce(TestSetupBuildItem.class) - @Produce(LogConsoleFormatBuildItem.class) + @Produce(NamedLogFormatsBuildItem.class) @Consume(ConsoleInstalledBuildItem.class) void setupStackTraceFormatter(ApplicationArchivesBuildItem item, EffectiveIdeBuildItem ideSupport, BuildSystemTargetBuildItem buildSystemTargetBuildItem, diff --git a/core/runtime/src/main/java/io/quarkus/runtime/logging/LogConfig.java b/core/runtime/src/main/java/io/quarkus/runtime/logging/LogConfig.java index a03c7eacb375f..0f97c86fe311e 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/logging/LogConfig.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/logging/LogConfig.java @@ -57,6 +57,14 @@ public final class LogConfig { @ConfigDocSection public SyslogConfig syslog; + /** + * Socket logging. + *

+ * Logging to a socket is also supported but not enabled by default. + */ + @ConfigDocSection + public SocketConfig socket; + /** * Logging categories. *

@@ -95,6 +103,15 @@ public final class LogConfig { @ConfigDocSection public Map syslogHandlers; + /** + * Socket handlers. + *

+ * The named socket handlers configured here can be linked on one or more categories. + */ + @ConfigItem(name = "handler.socket") + @ConfigDocSection + public Map socketHandlers; + /** * Log cleanup filters - internal use. */ diff --git a/core/runtime/src/main/java/io/quarkus/runtime/logging/LoggingSetupRecorder.java b/core/runtime/src/main/java/io/quarkus/runtime/logging/LoggingSetupRecorder.java index 88131e7f7271d..2d0f4630bd0ab 100644 --- a/core/runtime/src/main/java/io/quarkus/runtime/logging/LoggingSetupRecorder.java +++ b/core/runtime/src/main/java/io/quarkus/runtime/logging/LoggingSetupRecorder.java @@ -36,6 +36,7 @@ import org.jboss.logmanager.handlers.PeriodicRotatingFileHandler; import org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler; import org.jboss.logmanager.handlers.SizeRotatingFileHandler; +import org.jboss.logmanager.handlers.SocketHandler; import org.jboss.logmanager.handlers.SyslogHandler; import io.quarkus.bootstrap.logging.InitialConfigurator; @@ -85,7 +86,7 @@ public void initializeLogging(LogConfig config, LogBuildTimeConfig buildConfig, final RuntimeValue> devUiConsoleHandler, final List>> additionalHandlers, final List>> additionalNamedHandlers, - final List>> possibleFormatters, + final List>>> possibleFormatters, final RuntimeValue>> possibleBannerSupplier, LaunchMode launchMode) { final Map categories = config.categories; @@ -126,7 +127,7 @@ public void accept(String loggerName, CleanupFilterConfig config) { if (config.console.enable) { final Handler consoleHandler = configureConsoleHandler(config.console, consoleRuntimeConfig.getValue(), errorManager, cleanupFiler, - possibleFormatters, possibleBannerSupplier, launchMode); + getApplicableFormatters(possibleFormatters, "console"), possibleBannerSupplier, launchMode); errorManager = consoleHandler.getErrorManager(); handlers.add(consoleHandler); } @@ -150,16 +151,26 @@ public void close() throws SecurityException { } if (config.file.enable) { - handlers.add(configureFileHandler(config.file, errorManager, cleanupFiler)); + handlers.add(configureFileHandler(config.file, errorManager, cleanupFiler, + getApplicableFormatters(possibleFormatters, "file"))); } if (config.syslog.enable) { - final Handler syslogHandler = configureSyslogHandler(config.syslog, errorManager, cleanupFiler); + final Handler syslogHandler = configureSyslogHandler(config.syslog, errorManager, cleanupFiler, + getApplicableFormatters(possibleFormatters, "syslog")); if (syslogHandler != null) { handlers.add(syslogHandler); } } + if (config.socket.enable) { + final Handler socketHandler = configureSocketHandler(config.socket, errorManager, cleanupFiler, + getApplicableFormatters(possibleFormatters, "socket")); + if (socketHandler != null) { + handlers.add(socketHandler); + } + } + if ((launchMode.isDevOrTest() || enableWebStream) && devUiConsoleHandler != null && devUiConsoleHandler.getValue().isPresent()) { @@ -317,7 +328,7 @@ private static CategoryBuildTimeConfig isSubsetOf(String categoryName, Map createNamedHandlers(LogConfig config, ConsoleRuntimeConfig consoleRuntimeConfig, - List>> possibleFormatters, ErrorManager errorManager, + List>>> possibleFormatters, ErrorManager errorManager, LogCleanupFilter cleanupFilter, LaunchMode launchMode) { Map namedHandlers = new HashMap<>(); for (Entry consoleConfigEntry : config.consoleHandlers.entrySet()) { @@ -325,9 +336,11 @@ private static Map createNamedHandlers(LogConfig config, Consol if (!namedConsoleConfig.enable) { continue; } + List formatters = getApplicableFormatters(possibleFormatters, "console"); + formatters.addAll(getApplicableFormatters(possibleFormatters, consoleConfigEntry.getKey())); final Handler consoleHandler = configureConsoleHandler(namedConsoleConfig, consoleRuntimeConfig, errorManager, cleanupFilter, - possibleFormatters, null, launchMode); + formatters, null, launchMode); addToNamedHandlers(namedHandlers, consoleHandler, consoleConfigEntry.getKey()); } for (Entry fileConfigEntry : config.fileHandlers.entrySet()) { @@ -335,7 +348,9 @@ private static Map createNamedHandlers(LogConfig config, Consol if (!namedFileConfig.enable) { continue; } - final Handler fileHandler = configureFileHandler(namedFileConfig, errorManager, cleanupFilter); + List formatters = getApplicableFormatters(possibleFormatters, "file"); + formatters.addAll(getApplicableFormatters(possibleFormatters, fileConfigEntry.getKey())); + final Handler fileHandler = configureFileHandler(namedFileConfig, errorManager, cleanupFilter, formatters); addToNamedHandlers(namedHandlers, fileHandler, fileConfigEntry.getKey()); } for (Entry sysLogConfigEntry : config.syslogHandlers.entrySet()) { @@ -343,11 +358,25 @@ private static Map createNamedHandlers(LogConfig config, Consol if (!namedSyslogConfig.enable) { continue; } - final Handler syslogHandler = configureSyslogHandler(namedSyslogConfig, errorManager, cleanupFilter); + List formatters = getApplicableFormatters(possibleFormatters, "syslog"); + formatters.addAll(getApplicableFormatters(possibleFormatters, sysLogConfigEntry.getKey())); + final Handler syslogHandler = configureSyslogHandler(namedSyslogConfig, errorManager, cleanupFilter, formatters); if (syslogHandler != null) { addToNamedHandlers(namedHandlers, syslogHandler, sysLogConfigEntry.getKey()); } } + for (Entry socketConfigEntry : config.socketHandlers.entrySet()) { + SocketConfig namedSocketConfig = socketConfigEntry.getValue(); + if (!namedSocketConfig.enable) { + continue; + } + List formatters = getApplicableFormatters(possibleFormatters, "socket"); + formatters.addAll(getApplicableFormatters(possibleFormatters, socketConfigEntry.getKey())); + final Handler socketHandler = configureSocketHandler(namedSocketConfig, errorManager, cleanupFilter, formatters); + if (socketHandler != null) { + addToNamedHandlers(namedHandlers, socketHandler, socketConfigEntry.getKey()); + } + } return namedHandlers; } @@ -395,23 +424,31 @@ public void initializeLoggingForImageBuild() { } } + public static List getApplicableFormatters( + List>>> possibleFormatters, String key) { + List formatters = new ArrayList<>(); + for (RuntimeValue>> value : possibleFormatters) { + final Optional> val = value.getValue(); + if (val.isPresent()) { + Formatter formatter = val.get().get(key); + if (formatter != null) + formatters.add(formatter); + } + } + return formatters; + } + private static Handler configureConsoleHandler(final ConsoleConfig config, ConsoleRuntimeConfig consoleRuntimeConfig, final ErrorManager defaultErrorManager, final LogCleanupFilter cleanupFilter, - final List>> possibleFormatters, + final List formatters, final RuntimeValue>> possibleBannerSupplier, LaunchMode launchMode) { Formatter formatter = null; - boolean formatterWarning = false; - - for (RuntimeValue> value : possibleFormatters) { - if (formatter != null) { - formatterWarning = true; - } - final Optional val = value.getValue(); - if (val.isPresent()) { - formatter = val.get(); - } + boolean formatterWarning = formatters.size() > 1; + if (!formatters.isEmpty()) { + formatter = formatters.get(formatters.size() - 1); } + boolean color = false; if (formatter == null) { Supplier bannerSupplier = null; @@ -478,7 +515,7 @@ public void close() throws SecurityException { } private static Handler configureFileHandler(final FileConfig config, final ErrorManager errorManager, - final LogCleanupFilter cleanupFilter) { + final LogCleanupFilter cleanupFilter, List formatters) { FileHandler handler = new FileHandler(); FileConfig.RotationConfig rotationConfig = config.rotation; if ((rotationConfig.maxFileSize.isPresent() || rotationConfig.rotateOnBoot) @@ -501,8 +538,7 @@ private static Handler configureFileHandler(final FileConfig config, final Error handler = periodicRotatingFileHandler; } - final PatternFormatter formatter = new PatternFormatter(config.format); - handler.setFormatter(formatter); + handler.setFormatter(getFormatter(errorManager, formatters, () -> new PatternFormatter(config.format))); handler.setAppend(true); try { handler.setFile(config.path); @@ -520,7 +556,7 @@ private static Handler configureFileHandler(final FileConfig config, final Error private static Handler configureSyslogHandler(final SyslogConfig config, final ErrorManager errorManager, - final LogCleanupFilter logCleanupFilter) { + final LogCleanupFilter logCleanupFilter, List formatters) { try { final SyslogHandler handler = new SyslogHandler(config.endpoint.getHostString(), config.endpoint.getPort()); handler.setAppName(config.appName.orElse(getProcessName())); @@ -532,8 +568,7 @@ private static Handler configureSyslogHandler(final SyslogConfig config, handler.setTruncate(config.truncate); handler.setUseCountingFraming(config.useCountingFraming); handler.setLevel(config.level); - final PatternFormatter formatter = new PatternFormatter(config.format); - handler.setFormatter(formatter); + handler.setFormatter(getFormatter(errorManager, formatters, () -> new PatternFormatter(config.format))); handler.setErrorManager(errorManager); handler.setFilter(logCleanupFilter); if (config.async.enable) { @@ -546,6 +581,42 @@ private static Handler configureSyslogHandler(final SyslogConfig config, } } + private static Handler configureSocketHandler(final SocketConfig config, + final ErrorManager errorManager, + final LogCleanupFilter logCleanupFilter, List formatters) { + try { + final SocketHandler handler = new SocketHandler(config.endpoint.getHostString(), config.endpoint.getPort()); + handler.setProtocol(config.protocol); + handler.setBlockOnReconnect(config.blockOnReconnect); + handler.setLevel(config.level); + handler.setFormatter(getFormatter(errorManager, formatters, () -> new PatternFormatter(config.format))); + handler.setErrorManager(errorManager); + handler.setFilter(logCleanupFilter); + if (config.async.enable) { + return createAsyncHandler(config.async, config.level, handler); + } + return handler; + } catch (IOException e) { + errorManager.error("Failed to create socket handler", e, ErrorManager.OPEN_FAILURE); + return null; + } + } + + public static Formatter getFormatter(final ErrorManager errorManager, List formatters, + Supplier defaultFormatter) { + Formatter formatter; + boolean formatterWarning = formatters.size() > 1; + if (!formatters.isEmpty()) { + formatter = formatters.get(formatters.size() - 1); + } else { + formatter = defaultFormatter.get(); + } + if (formatterWarning) { + errorManager.error("Multiple formatters were activated", null, ErrorManager.GENERIC_FAILURE); + } + return formatter; + } + private static AsyncHandler createAsyncHandler(AsyncConfig asyncConfig, Level level, Handler handler) { final AsyncHandler asyncHandler = new AsyncHandler(asyncConfig.queueLength); asyncHandler.setOverflowAction(asyncConfig.overflow); @@ -602,4 +673,5 @@ public void accept(String name, Handler handler) { handler.setFilter(new LogCleanupFilter(filterElements)); } } + } diff --git a/core/runtime/src/main/java/io/quarkus/runtime/logging/SocketConfig.java b/core/runtime/src/main/java/io/quarkus/runtime/logging/SocketConfig.java new file mode 100644 index 0000000000000..e325c76ebb06e --- /dev/null +++ b/core/runtime/src/main/java/io/quarkus/runtime/logging/SocketConfig.java @@ -0,0 +1,57 @@ +package io.quarkus.runtime.logging; + +import java.net.InetSocketAddress; +import java.util.logging.Level; + +import org.jboss.logmanager.handlers.SocketHandler.Protocol; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +@ConfigGroup +public class SocketConfig { + + /** + * If socket logging should be enabled + */ + @ConfigItem + boolean enable; + + /** + * + * The IP address and port of the server receiving the logs + */ + @ConfigItem(defaultValue = "localhost:4560") + InetSocketAddress endpoint; + + /** + * Sets the protocol used to connect to the server + */ + @ConfigItem(defaultValue = "tcp") + Protocol protocol; + + /** + * Enables or disables blocking when attempting to reconnect a + * {@link Protocol#TCP + * TCP} or {@link Protocol#SSL_TCP SSL TCP} protocol + */ + @ConfigItem + boolean blockOnReconnect; + + /** + * The log message format + */ + @ConfigItem(defaultValue = "%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{3.}] (%t) %s%e%n") + String format; + /** + * The log level specifying, which message levels will be logged by socket logger + */ + @ConfigItem(defaultValue = "ALL") + Level level; + + /** + * Syslog async logging config + */ + AsyncConfig async; + +} diff --git a/core/test-extension/deployment/src/main/resources/application-async-socket-output.properties b/core/test-extension/deployment/src/main/resources/application-async-socket-output.properties new file mode 100644 index 0000000000000..c906a98fbe758 --- /dev/null +++ b/core/test-extension/deployment/src/main/resources/application-async-socket-output.properties @@ -0,0 +1,10 @@ +quarkus.log.level=INFO +quarkus.log.socket.enable=true +quarkus.log.socket.endpoint=localhost:5140 +quarkus.log.socket.protocol=TCP +quarkus.log.socket.level=WARNING +quarkus.log.socket.async=true +quarkus.log.socket.async.queue-length=256 +quarkus.log.socket.async.overflow=discard +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/core/test-extension/deployment/src/main/resources/application-socket-output.properties b/core/test-extension/deployment/src/main/resources/application-socket-output.properties new file mode 100644 index 0000000000000..4bb2331dd8ec5 --- /dev/null +++ b/core/test-extension/deployment/src/main/resources/application-socket-output.properties @@ -0,0 +1,8 @@ +quarkus.log.level=INFO +quarkus.log.socket.enable=true +quarkus.log.socket.endpoint=localhost:5140 +quarkus.log.socket.protocol=TCP +quarkus.log.socket.format=%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{3.}] (%t) %s%e%n +quarkus.log.socket.level=WARNING +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/core/test-extension/deployment/src/test/java/io/quarkus/logging/AsyncSocketHandlerTest.java b/core/test-extension/deployment/src/test/java/io/quarkus/logging/AsyncSocketHandlerTest.java new file mode 100644 index 0000000000000..112c0ee914a78 --- /dev/null +++ b/core/test-extension/deployment/src/test/java/io/quarkus/logging/AsyncSocketHandlerTest.java @@ -0,0 +1,47 @@ +package io.quarkus.logging; + +import static io.quarkus.logging.LoggingTestsHelper.getHandler; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import java.util.logging.Handler; +import java.util.logging.Level; + +import org.jboss.logmanager.handlers.AsyncHandler; +import org.jboss.logmanager.handlers.SocketHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; + +public class AsyncSocketHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-async-socket-output.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")) + .setLogFileName("AsyncSyslogHandlerTest.log"); + + @Test + public void asyncSyslogHandlerConfigurationTest() throws NullPointerException { + Handler handler = getHandler(AsyncHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + AsyncHandler asyncHandler = (AsyncHandler) handler; + assertThat(asyncHandler.getHandlers()).isNotEmpty(); + assertThat(asyncHandler.getQueueLength()).isEqualTo(256); + assertThat(asyncHandler.getOverflowAction()).isEqualTo(AsyncHandler.OverflowAction.DISCARD); + + Handler nestedSyslogHandler = Arrays.stream(asyncHandler.getHandlers()) + .filter(h -> (h instanceof SocketHandler)) + .findFirst().get(); + + SocketHandler socketHandler = (SocketHandler) nestedSyslogHandler; + assertThat(socketHandler.getPort()).isEqualTo(5140); + assertThat(socketHandler.getAddress().getHostAddress()).isEqualTo("127.0.0.1"); + assertThat(socketHandler.getProtocol()).isEqualTo(SocketHandler.Protocol.TCP); + assertThat(socketHandler.isBlockOnReconnect()).isEqualTo(false); + } +} diff --git a/core/test-extension/deployment/src/test/java/io/quarkus/logging/SocketHandlerTest.java b/core/test-extension/deployment/src/test/java/io/quarkus/logging/SocketHandlerTest.java new file mode 100644 index 0000000000000..ba2d4d63c7641 --- /dev/null +++ b/core/test-extension/deployment/src/test/java/io/quarkus/logging/SocketHandlerTest.java @@ -0,0 +1,41 @@ +package io.quarkus.logging; + +import static io.quarkus.logging.LoggingTestsHelper.getHandler; +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.SocketHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; + +public class SocketHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-socket-output.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")); + + @Test + public void socketOutputTest() { + Handler handler = getHandler(SocketHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(PatternFormatter.class); + PatternFormatter patternFormatter = (PatternFormatter) formatter; + assertThat(patternFormatter.getPattern()).isEqualTo("%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c{3.}] (%t) %s%e%n"); + SocketHandler socketHandler = (SocketHandler) handler; + assertThat(socketHandler.getPort()).isEqualTo(5140); + assertThat(socketHandler.getAddress().getHostAddress()).isEqualTo("127.0.0.1"); + assertThat(socketHandler.getProtocol()).isEqualTo(SocketHandler.Protocol.TCP); + assertThat(socketHandler.isBlockOnReconnect()).isEqualTo(false); + } +} diff --git a/extensions/logging-json/deployment/src/main/java/io/quarkus/logging/json/deployment/LoggingJsonSteps.java b/extensions/logging-json/deployment/src/main/java/io/quarkus/logging/json/deployment/LoggingJsonSteps.java index f09287aae3204..9282cc067d545 100644 --- a/extensions/logging-json/deployment/src/main/java/io/quarkus/logging/json/deployment/LoggingJsonSteps.java +++ b/extensions/logging-json/deployment/src/main/java/io/quarkus/logging/json/deployment/LoggingJsonSteps.java @@ -3,15 +3,16 @@ import io.quarkus.deployment.annotations.BuildStep; import io.quarkus.deployment.annotations.ExecutionTime; import io.quarkus.deployment.annotations.Record; -import io.quarkus.deployment.builditem.LogConsoleFormatBuildItem; -import io.quarkus.logging.json.runtime.JsonConfig; +import io.quarkus.deployment.builditem.NamedLogFormatsBuildItem; +import io.quarkus.logging.json.runtime.JsonLogConfig; import io.quarkus.logging.json.runtime.LoggingJsonRecorder; public final class LoggingJsonSteps { @BuildStep @Record(ExecutionTime.RUNTIME_INIT) - public LogConsoleFormatBuildItem setUpFormatter(LoggingJsonRecorder recorder, JsonConfig config) { - return new LogConsoleFormatBuildItem(recorder.initializeJsonLogging(config)); + public NamedLogFormatsBuildItem setUpFormatter(LoggingJsonRecorder recorder, JsonLogConfig config) { + return new NamedLogFormatsBuildItem( + recorder.initializeJsonLogging(config)); } } diff --git a/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/JsonConfig.java b/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/JsonConfig.java index 677c16573df25..9480afbb0c56f 100644 --- a/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/JsonConfig.java +++ b/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/JsonConfig.java @@ -1,17 +1,19 @@ package io.quarkus.logging.json.runtime; +import java.util.Map; import java.util.Optional; import org.jboss.logmanager.formatters.StructuredFormatter; +import io.quarkus.runtime.annotations.ConfigDocMapKey; +import io.quarkus.runtime.annotations.ConfigDocSection; +import io.quarkus.runtime.annotations.ConfigGroup; import io.quarkus.runtime.annotations.ConfigItem; -import io.quarkus.runtime.annotations.ConfigPhase; -import io.quarkus.runtime.annotations.ConfigRoot; /** * Configuration for JSON log formatting. */ -@ConfigRoot(phase = ConfigPhase.RUN_TIME, name = "log.console.json") +@ConfigGroup public class JsonConfig { /** * Determine whether to enable the JSON console formatting extension, which disables "normal" console formatting. @@ -51,4 +53,36 @@ public class JsonConfig { */ @ConfigItem boolean printDetails; + + /** + * comma-seperated key=value pairs + * possible keys are listed {@link StructuredFormatter.Key} + * e.g. HOST_NAME=host,LEVEL=severity + */ + @ConfigItem(defaultValue = "") + public String keyoverrides; + + /** + * Post additional fields only for JSON formatted messages + * You can add static fields to each log event in the following form: + * + *

+     * quarkus.log.handler.socket.mySocket.additional-field.field1.value=value1
+     * quarkus.log.console.additional-field.field2.value=value2
+     * 
+ */ + @ConfigItem + @ConfigDocMapKey("field-name") + @ConfigDocSection + public Map additionalField; + + @ConfigGroup + public static class AdditionalFieldConfig { + /** + * Additional field value. + */ + @ConfigItem + public String value; + + } } diff --git a/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/JsonLogConfig.java b/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/JsonLogConfig.java new file mode 100644 index 0000000000000..4e4c9335aca07 --- /dev/null +++ b/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/JsonLogConfig.java @@ -0,0 +1,71 @@ +package io.quarkus.logging.json.runtime; + +import java.util.Map; + +import io.quarkus.runtime.annotations.ConfigDocSection; +import io.quarkus.runtime.annotations.ConfigItem; +import io.quarkus.runtime.annotations.ConfigPhase; +import io.quarkus.runtime.annotations.ConfigRoot; + +/** + * Configuration for JSON log formatting. + */ +@ConfigRoot(phase = ConfigPhase.RUN_TIME, name = "log") +public class JsonLogConfig { + /** + * Console logging configuration + */ + @ConfigItem(name = "console.json") + JsonConfig console; + /** + * File logging configuration + */ + @ConfigItem(name = "file.json") + JsonConfig file; + /** + * Syslog logging configuration + */ + @ConfigItem(name = "syslog.json") + JsonConfig syslog; + /** + * Socket logging configuration + */ + @ConfigItem(name = "socket.json") + JsonConfig socket; + + /** + * Named console handler formatters + *

+ * The named console formatters configured here can be linked on one or more categories. + */ + @ConfigItem(name = "handler.console") + @ConfigDocSection + public Map consoleFormatters; + + /** + * Named file handler formatters + *

+ * The named file formatters configured here can be linked on one or more categories. + */ + @ConfigItem(name = "handler.file") + @ConfigDocSection + public Map fileFormatters; + + /** + * Named syslog handler formatters + *

+ * The named syslog formatters configured here can be linked on one or more categories. + */ + @ConfigItem(name = "handler.syslog") + @ConfigDocSection + public Map syslogFormatters; + + /** + * Named syslog handler formatters + *

+ * The named syslog formatters configured here can be linked on one or more categories. + */ + @ConfigItem(name = "handler.socket") + @ConfigDocSection + public Map socketFormatters; +} diff --git a/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/LoggingJsonRecorder.java b/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/LoggingJsonRecorder.java index 639f8cb62a3a5..b8151485f5e0e 100644 --- a/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/LoggingJsonRecorder.java +++ b/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/LoggingJsonRecorder.java @@ -1,20 +1,85 @@ package io.quarkus.logging.json.runtime; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import java.util.Optional; import java.util.logging.Formatter; +import org.jboss.logmanager.ExtLogRecord; import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.StructuredFormatter; import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.annotations.Recorder; +import io.quarkus.runtime.configuration.ConfigurationException; @Recorder public class LoggingJsonRecorder { - public RuntimeValue> initializeJsonLogging(final JsonConfig config) { - if (!config.enable) { - return new RuntimeValue<>(Optional.empty()); + public RuntimeValue>> initializeJsonLogging(final JsonLogConfig config) { + Map namedFormatterMap = new HashMap<>(); + if (config.console.enable) { + namedFormatterMap.put("console", createJsonFormatter(config.console)); } - final JsonFormatter formatter = new JsonFormatter(); + if (config.file.enable) { + namedFormatterMap.put("file", createJsonFormatter(config.file)); + } + if (config.syslog.enable) { + namedFormatterMap.put("syslog", createJsonFormatter(config.syslog)); + } + if (config.socket.enable) { + namedFormatterMap.put("socket", createJsonFormatter(config.socket)); + } + addNamedConfigs(config.consoleFormatters, namedFormatterMap); + addNamedConfigs(config.fileFormatters, namedFormatterMap); + addNamedConfigs(config.syslogFormatters, namedFormatterMap); + addNamedConfigs(config.socketFormatters, namedFormatterMap); + return new RuntimeValue<>(Optional.of(namedFormatterMap)); + } + + private void addNamedConfigs(Map namedConfigs, Map namedFormatterMap) { + for (Map.Entry entry : namedConfigs.entrySet()) { + if (entry.getValue().jsonConfig.enable) { + String name = entry.getKey(); + NamedHandlerJsonConfig config = entry.getValue(); + if (namedFormatterMap.containsKey(name)) { + throw new RuntimeException(String.format("Only one formatter can be configured with the same name '%s'", + name)); + } + namedFormatterMap.put(name, createJsonFormatter(config.jsonConfig)); + } + } + + } + + private static JsonFormatter createJsonFormatter(JsonConfig config) { + String keyOverrides = config.keyoverrides; + Map keyOverrideMap = null; + if (!keyOverrides.equals("")) { + keyOverrideMap = new HashMap<>(); + for (String pair : keyOverrides.split(",")) { + String[] split = pair.split("=", 2); + if (split.length == 2) { + StructuredFormatter.Key key = translateToKey(split[0]); + if (key != null) { + keyOverrideMap.put(key, split[1]); + } + } else { + throw new ConfigurationException( + "Key override pair '" + pair + "' is invalid, key and value should be separated by = character"); + } + } + } + JsonFormatter formatter; + Map additionalField = config.additionalField; + if (!additionalField.isEmpty()) { + Map additionalFields = new HashMap<>(); + for (Map.Entry field : additionalField.entrySet()) { + additionalFields.put(field.getKey(), field.getValue().value); + } + formatter = new CustomFieldsJsonFormatter(keyOverrideMap, additionalFields); + } else + formatter = new JsonFormatter(keyOverrideMap); formatter.setPrettyPrint(config.prettyPrint); final String dateFormat = config.dateFormat; if (!dateFormat.equals("default")) { @@ -27,6 +92,34 @@ public RuntimeValue> initializeJsonLogging(final JsonConfig if (!zoneId.equals("default")) { formatter.setZoneId(zoneId); } - return new RuntimeValue<>(Optional.of(formatter)); + return formatter; + } + + private static StructuredFormatter.Key translateToKey(String name) { + try { + return StructuredFormatter.Key.valueOf(name); + } catch (IllegalArgumentException e) { + throw new ConfigurationException( + "Invalid key: " + name + ". Valid values are: " + Arrays.toString(StructuredFormatter.Key.values())); + } + } + + public static class CustomFieldsJsonFormatter extends JsonFormatter { + public Map additionalFields; + + public CustomFieldsJsonFormatter(Map keyOverrides, Map additionalFields) { + super(keyOverrides); + this.additionalFields = additionalFields; + } + + @Override + protected void after(Generator generator, ExtLogRecord record) throws Exception { + super.after(generator, record); + if (!additionalFields.isEmpty()) { + for (Map.Entry entry : additionalFields.entrySet()) + generator.add(entry.getKey(), entry.getValue()); + } + } + } } diff --git a/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/NamedHandlerJsonConfig.java b/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/NamedHandlerJsonConfig.java new file mode 100644 index 0000000000000..62d16eb45186a --- /dev/null +++ b/extensions/logging-json/runtime/src/main/java/io/quarkus/logging/json/runtime/NamedHandlerJsonConfig.java @@ -0,0 +1,16 @@ +package io.quarkus.logging.json.runtime; + +import io.quarkus.runtime.annotations.ConfigGroup; +import io.quarkus.runtime.annotations.ConfigItem; + +/** + * Configuration for JSON log formatting. + */ +@ConfigGroup +public class NamedHandlerJsonConfig { + /** + * Json formatter configuration for named handler + */ + @ConfigItem(name = "json") + JsonConfig jsonConfig; +} diff --git a/extensions/logging-json/runtime/src/main/resources/META-INF/quarkus-extension.yaml b/extensions/logging-json/runtime/src/main/resources/META-INF/quarkus-extension.yaml index f687588582134..65fbe1a17f55a 100644 --- a/extensions/logging-json/runtime/src/main/resources/META-INF/quarkus-extension.yaml +++ b/extensions/logging-json/runtime/src/main/resources/META-INF/quarkus-extension.yaml @@ -11,4 +11,4 @@ metadata: status: "preview" guide: "https://quarkus.io/guides/logging#json-logging" config: - - "quarkus.log.console.json." + - "quarkus.log." diff --git a/integration-tests/logging-json/pom.xml b/integration-tests/logging-json/pom.xml index 380d77b785221..0ee5affc85b24 100644 --- a/integration-tests/logging-json/pom.xml +++ b/integration-tests/logging-json/pom.xml @@ -23,8 +23,25 @@ io.quarkus quarkus-logging-json - - + + io.quarkus + quarkus-arc-deployment + + + io.quarkus + quarkus-test-extension + ${project.version} + + + org.assertj + assertj-core + test + + + io.quarkus + quarkus-junit5-internal + test + io.quarkus quarkus-junit5 diff --git a/integration-tests/logging-json/src/main/java/io/quarkus/it/logging/json/GreetingResource.java b/integration-tests/logging-json/src/main/java/io/quarkus/it/logging/json/GreetingResource.java deleted file mode 100644 index 1c3099e4d5610..0000000000000 --- a/integration-tests/logging-json/src/main/java/io/quarkus/it/logging/json/GreetingResource.java +++ /dev/null @@ -1,21 +0,0 @@ -package io.quarkus.it.logging.json; - -import java.util.logging.Logger; - -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.MediaType; - -@Path("/hello") -public class GreetingResource { - - private static final Logger logger = Logger.getLogger(GreetingResource.class.getName()); - - @GET - @Produces(MediaType.TEXT_PLAIN) - public String hello() { - logger.info("Hello to \"Quarkus\""); - return "hello"; - } -} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AdditionalFieldsHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AdditionalFieldsHandlerTest.java new file mode 100644 index 0000000000000..8e1c36886d9ae --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AdditionalFieldsHandlerTest.java @@ -0,0 +1,49 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.logging.json.runtime.LoggingJsonRecorder; +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.ConsoleHandler; +import org.jboss.logmanager.handlers.SocketHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler; +import static org.assertj.core.api.Assertions.assertThat; + + +public class AdditionalFieldsHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-additional-fields.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")); + + @Test + public void additionalFieldsHandlerTest() { + Handler handler = getHandler(SocketHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(JsonFormatter.class); + LoggingJsonRecorder.CustomFieldsJsonFormatter customFieldsJsonFormatter = (LoggingJsonRecorder.CustomFieldsJsonFormatter) formatter; + assertThat(customFieldsJsonFormatter.additionalFields).containsKey("myownfield"); + assertThat(customFieldsJsonFormatter.additionalFields.get("myownfield")).isEqualTo("testingvalue"); + SocketHandler socketHandler = (SocketHandler) handler; + assertThat(socketHandler.getPort()).isEqualTo(5140); + assertThat(socketHandler.getAddress().getHostAddress()).isEqualTo("127.0.0.1"); + assertThat(socketHandler.getProtocol()).isEqualTo(SocketHandler.Protocol.TCP); + assertThat(socketHandler.isBlockOnReconnect()).isEqualTo(false); + Handler consoleHanlder = getHandler(ConsoleHandler.class); + assertThat(consoleHanlder).isNotNull(); + formatter = consoleHanlder.getFormatter(); + assertThat(formatter).isInstanceOf(PatternFormatter.class); + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AdditionalHandlersTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AdditionalHandlersTest.java new file mode 100644 index 0000000000000..8d508ddd0169d --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AdditionalHandlersTest.java @@ -0,0 +1,32 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.extest.runtime.logging.AdditionalLogHandlerValueFactory.TestHandler; +import io.quarkus.test.QuarkusUnitTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class AdditionalHandlersTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-additional-handlers.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")); + + @Test + public void additionalHandlersConfigurationTest() { + Handler handler = getHandler(TestHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.FINE); + + TestHandler testHandler = (TestHandler) handler; + assertThat(testHandler.records).isNotEmpty(); + } + +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncConsoleHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncConsoleHandlerTest.java new file mode 100644 index 0000000000000..7ddfed3950413 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncConsoleHandlerTest.java @@ -0,0 +1,45 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.handlers.AsyncHandler; +import org.jboss.logmanager.handlers.ConsoleHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.Arrays; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler; +import static org.assertj.core.api.Assertions.assertThat; + +public class AsyncConsoleHandlerTest { + + @RegisterExtension + static final io.quarkus.test.QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-async-console-log.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")) + .setLogFileName("AsyncConsoleHandlerTest.log"); + + @Test + public void asyncConsoleHandlerConfigurationTest() { + Handler handler = getHandler(AsyncHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + AsyncHandler asyncHandler = (AsyncHandler) handler; + assertThat(asyncHandler.getHandlers()).isNotEmpty(); + assertThat(asyncHandler.getQueueLength()).isEqualTo(256); + assertThat(asyncHandler.getOverflowAction()).isEqualTo(AsyncHandler.OverflowAction.DISCARD); + + Handler nestedConsoleHandler = Arrays.stream(asyncHandler.getHandlers()) + .filter(h -> (h instanceof ConsoleHandler)) + .findFirst().get(); + + ConsoleHandler consoleHandler = (ConsoleHandler) nestedConsoleHandler; + assertThat(consoleHandler.getLevel()).isEqualTo(Level.WARNING); + + } + +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncFileHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncFileHandlerTest.java new file mode 100644 index 0000000000000..137be1a08b1c6 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncFileHandlerTest.java @@ -0,0 +1,44 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.handlers.AsyncHandler; +import org.jboss.logmanager.handlers.FileHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.Arrays; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class AsyncFileHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-async-file-log.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")) + .setLogFileName("AsyncFileHandlerTest.log"); + + @Test + public void asyncFileHandlerConfigurationTest() { + Handler handler = getHandler(AsyncHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.INFO); + + AsyncHandler asyncHandler = (AsyncHandler) handler; + assertThat(asyncHandler.getHandlers()).isNotEmpty(); + assertThat(asyncHandler.getQueueLength()).isEqualTo(1024); + assertThat(asyncHandler.getOverflowAction()).isEqualTo(AsyncHandler.OverflowAction.BLOCK); + + Handler nestedFileHandler = Arrays.stream(asyncHandler.getHandlers()) + .filter(h -> (h instanceof FileHandler)) + .findFirst().get(); + + FileHandler fileHandler = (FileHandler) nestedFileHandler; + assertThat(fileHandler.getLevel()).isEqualTo(Level.INFO); + + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncSocketHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncSocketHandlerTest.java new file mode 100644 index 0000000000000..c17a9b4698437 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncSocketHandlerTest.java @@ -0,0 +1,46 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.handlers.AsyncHandler; +import org.jboss.logmanager.handlers.SocketHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.Arrays; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class AsyncSocketHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-async-socket-output.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")) + .setLogFileName("AsyncSyslogHandlerTest.log"); + + @Test + public void asyncSyslogHandlerConfigurationTest() throws NullPointerException { + Handler handler = getHandler(AsyncHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + AsyncHandler asyncHandler = (AsyncHandler) handler; + assertThat(asyncHandler.getHandlers()).isNotEmpty(); + assertThat(asyncHandler.getQueueLength()).isEqualTo(256); + assertThat(asyncHandler.getOverflowAction()).isEqualTo(AsyncHandler.OverflowAction.DISCARD); + + Handler nestedSyslogHandler = Arrays.stream(asyncHandler.getHandlers()) + .filter(h -> (h instanceof SocketHandler)) + .findFirst().get(); + + SocketHandler socketHandler = (SocketHandler) nestedSyslogHandler; + assertThat(socketHandler.getPort()).isEqualTo(5140); + assertThat(socketHandler.getAddress().getHostAddress()).isEqualTo("127.0.0.1"); + assertThat(socketHandler.getProtocol()).isEqualTo(SocketHandler.Protocol.TCP); + assertThat(socketHandler.isBlockOnReconnect()).isEqualTo(false); + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncSyslogHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncSyslogHandlerTest.java new file mode 100644 index 0000000000000..af9ad94e791c6 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/AsyncSyslogHandlerTest.java @@ -0,0 +1,51 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.handlers.AsyncHandler; +import org.jboss.logmanager.handlers.SyslogHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.Arrays; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class AsyncSyslogHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-async-syslog.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")) + .setLogFileName("AsyncSyslogHandlerTest.log"); + + @Test + public void asyncSyslogHandlerConfigurationTest() throws NullPointerException { + Handler handler = getHandler(AsyncHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + AsyncHandler asyncHandler = (AsyncHandler) handler; + assertThat(asyncHandler.getHandlers()).isNotEmpty(); + assertThat(asyncHandler.getQueueLength()).isEqualTo(256); + assertThat(asyncHandler.getOverflowAction()).isEqualTo(AsyncHandler.OverflowAction.DISCARD); + + Handler nestedSyslogHandler = Arrays.stream(asyncHandler.getHandlers()) + .filter(h -> (h instanceof SyslogHandler)) + .findFirst().get(); + + SyslogHandler syslogHandler = (SyslogHandler) nestedSyslogHandler; + assertThat(syslogHandler.getPort()).isEqualTo(5144); + assertThat(syslogHandler.getAppName()).isEqualTo("quarkus"); + assertThat(syslogHandler.getHostname()).isEqualTo("quarkus-test"); + assertThat(syslogHandler.getFacility()).isEqualTo(SyslogHandler.Facility.LOG_ALERT); + assertThat(syslogHandler.getSyslogType()).isEqualTo(SyslogHandler.SyslogType.RFC3164); + assertThat(syslogHandler.getProtocol()).isEqualTo(SyslogHandler.Protocol.UDP); + assertThat(syslogHandler.isUseCountingFraming()).isEqualTo(true); + assertThat(syslogHandler.isTruncate()).isEqualTo(false); + assertThat(syslogHandler.isBlockOnReconnect()).isEqualTo(false); + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/CategoryConfiguredHandlerInvalidDueToMultipleHandlersTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/CategoryConfiguredHandlerInvalidDueToMultipleHandlersTest.java new file mode 100644 index 0000000000000..c102158a42529 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/CategoryConfiguredHandlerInvalidDueToMultipleHandlersTest.java @@ -0,0 +1,23 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import static org.junit.jupiter.api.Assertions.fail; + +public class CategoryConfiguredHandlerInvalidDueToMultipleHandlersTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .setExpectedException(RuntimeException.class) + .withConfigurationResource("application-category-invalid-configured-handlers-output.properties") + .withApplicationRoot((jar) -> jar + .addAsManifestResource("application.properties", "microprofile-config.properties")); + + @Test + public void consoleOutputTest() { + fail("This method should not be invoked because of invalid configuration of logging handlers"); + } + +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/CategoryConfiguredHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/CategoryConfiguredHandlerTest.java new file mode 100644 index 0000000000000..2d781bb5f97b4 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/CategoryConfiguredHandlerTest.java @@ -0,0 +1,72 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.bootstrap.logging.InitialConfigurator; +import io.quarkus.bootstrap.logging.QuarkusDelayedHandler; +import io.quarkus.logging.json.runtime.LoggingJsonRecorder; +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.ConsoleHandler; +import org.jboss.logmanager.handlers.FileHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.Arrays; +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +import static org.assertj.core.api.Assertions.assertThat; + +public class CategoryConfiguredHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-category-configured-handlers-output.properties") + .withApplicationRoot((jar) -> jar + .addAsManifestResource("application.properties", "microprofile-config.properties")); + + @Test + public void consoleOutputTest() { + LogManager logManager = LogManager.getLogManager(); + assertThat(logManager).isInstanceOf(org.jboss.logmanager.LogManager.class); + + QuarkusDelayedHandler delayedHandler = InitialConfigurator.DELAYED_HANDLER; + assertThat(Logger.getLogger("").getHandlers()).contains(delayedHandler); + + Handler handler = Arrays.stream(delayedHandler.getHandlers()).filter(h -> (h instanceof ConsoleHandler)) + .findFirst().get(); + assertThat(handler).isNotNull(); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + Logger categoryLogger = logManager.getLogger("io.quarkus.category"); + assertThat(categoryLogger).isNotNull(); + assertThat(categoryLogger.getHandlers()).hasSize(2).extracting("class").containsExactlyInAnyOrder(ConsoleHandler.class, + FileHandler.class); + for (Handler h : categoryLogger.getHandlers()){ + if (h instanceof FileHandler){ + assertThat(h.getFormatter()).isInstanceOf(LoggingJsonRecorder.CustomFieldsJsonFormatter.class); + LoggingJsonRecorder.CustomFieldsJsonFormatter customFieldsJsonFormatter = (LoggingJsonRecorder.CustomFieldsJsonFormatter) h.getFormatter(); + assertThat(customFieldsJsonFormatter.additionalFields).containsKey("myfield"); + assertThat(customFieldsJsonFormatter.additionalFields.get("myfield")).isEqualTo("true"); + } + } + + Logger otherCategoryLogger = logManager.getLogger("io.quarkus.othercategory"); + assertThat(otherCategoryLogger).isNotNull(); + assertThat(otherCategoryLogger.getHandlers()).hasSize(1).extracting("class") + .containsExactlyInAnyOrder(ConsoleHandler.class); + ConsoleHandler consoleHandler = (ConsoleHandler) otherCategoryLogger.getHandlers()[0]; + assertThat(consoleHandler.getFormatter()).isInstanceOf(PatternFormatter.class); + + Logger anotherCategoryLogger = logManager.getLogger("io.quarkus.anothercategory"); + assertThat(anotherCategoryLogger).isNotNull(); + assertThat(anotherCategoryLogger.getHandlers()).isEmpty(); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(PatternFormatter.class); + } + +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/ConsoleHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/ConsoleHandlerTest.java new file mode 100644 index 0000000000000..d33218dad9c07 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/ConsoleHandlerTest.java @@ -0,0 +1,36 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.ConsoleHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class ConsoleHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-console-output.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")); + + @Test + public void consoleOutputTest() { + Handler handler = getHandler(ConsoleHandler.class); + assertThat(handler).isNotNull(); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(JsonFormatter.class); + } + +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/FileHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/FileHandlerTest.java new file mode 100644 index 0000000000000..510b7aafbc9ca --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/FileHandlerTest.java @@ -0,0 +1,35 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.FileHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class FileHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-file-output-log.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")); + + @Test + public void fileOutputTest() { + Handler handler = getHandler(FileHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.INFO); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(JsonFormatter.class); + } + +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/GreetingResourceTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/GreetingResourceTest.java deleted file mode 100644 index f56b70e099f03..0000000000000 --- a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/GreetingResourceTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.quarkus.it.logging.json; - -import static io.restassured.RestAssured.given; -import static org.hamcrest.CoreMatchers.is; - -import org.junit.jupiter.api.Test; - -import io.quarkus.test.junit.QuarkusTest; - -@QuarkusTest -public class GreetingResourceTest { - - @Test - public void testHelloEndpoint() throws Exception { - given() - .when().get("/hello") - .then() - .statusCode(200) - .body(is("hello")); - } - -} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/LoggingTestsHelper.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/LoggingTestsHelper.java new file mode 100644 index 0000000000000..c9ad92ca2ae3c --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/LoggingTestsHelper.java @@ -0,0 +1,32 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.bootstrap.logging.InitialConfigurator; +import io.quarkus.bootstrap.logging.QuarkusDelayedHandler; +import org.junit.jupiter.api.Assertions; + +import java.util.Arrays; +import java.util.Optional; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogManager; +import java.util.logging.Logger; + +import static org.assertj.core.api.Assertions.assertThat; + +public class LoggingTestsHelper { + + public static Handler getHandler(Class clazz) { + LogManager logManager = LogManager.getLogManager(); + assertThat(logManager).isInstanceOf(org.jboss.logmanager.LogManager.class); + + QuarkusDelayedHandler delayedHandler = InitialConfigurator.DELAYED_HANDLER; + assertThat(Logger.getLogger("").getHandlers()).contains(delayedHandler); + assertThat(delayedHandler.getLevel()).isEqualTo(Level.ALL); + + Optional handler = Arrays.stream(delayedHandler.getHandlers()).filter(h -> (clazz.isInstance(h))) + .findFirst(); + Assertions.assertTrue(handler.isPresent(), () -> String.format("Could not find handler of type %s: %s", clazz, + Arrays.asList(delayedHandler.getHandlers()))); + return handler.get(); + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/NativeGreetingResourceIT.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/NativeGreetingResourceIT.java deleted file mode 100644 index 64336b5303852..0000000000000 --- a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/NativeGreetingResourceIT.java +++ /dev/null @@ -1,9 +0,0 @@ -package io.quarkus.it.logging.json; - -import io.quarkus.test.junit.QuarkusIntegrationTest; - -@QuarkusIntegrationTest -public class NativeGreetingResourceIT extends GreetingResourceTest { - - // Execute the same tests but in native mode. -} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/PeriodicRotatingLoggingTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/PeriodicRotatingLoggingTest.java new file mode 100644 index 0000000000000..761178649cf7e --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/PeriodicRotatingLoggingTest.java @@ -0,0 +1,35 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.PeriodicRotatingFileHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class PeriodicRotatingLoggingTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-periodic-file-log-rotating.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")) + .setLogFileName("PeriodicRotatingLoggingTest.log"); + + @Test + public void periodicRotatingConfigurationTest() { + Handler handler = getHandler(PeriodicRotatingFileHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.INFO); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(JsonFormatter.class); + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/PeriodicSizeRotatingLoggingRotateOnBootTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/PeriodicSizeRotatingLoggingRotateOnBootTest.java new file mode 100644 index 0000000000000..65f2bbe0d10de --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/PeriodicSizeRotatingLoggingRotateOnBootTest.java @@ -0,0 +1,40 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class PeriodicSizeRotatingLoggingRotateOnBootTest { + + private static final String FILE_NAME = PeriodicSizeRotatingLoggingRotateOnBootTest.class.getSimpleName() + ".log"; + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-periodic-size-file-log-rotating-rotate-on-boot.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")) + .setLogFileName(FILE_NAME); + + @Test + public void periodicSizeRotatingConfigurationTest() { + Handler handler = getHandler(PeriodicSizeRotatingFileHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.INFO); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(JsonFormatter.class); + + PeriodicSizeRotatingFileHandler periodicSizeRotatingFileHandler = (PeriodicSizeRotatingFileHandler) handler; + assertThat(periodicSizeRotatingFileHandler.isRotateOnBoot()).isTrue(); + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/PeriodicSizeRotatingLoggingTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/PeriodicSizeRotatingLoggingTest.java new file mode 100644 index 0000000000000..491a09a268c2c --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/PeriodicSizeRotatingLoggingTest.java @@ -0,0 +1,38 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.PeriodicSizeRotatingFileHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class PeriodicSizeRotatingLoggingTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-periodic-size-file-log-rotating.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")) + .setLogFileName("PeriodicSizeRotatingLoggingTest.log"); + + @Test + public void periodicSizeRotatingConfigurationTest() { + Handler handler = getHandler(PeriodicSizeRotatingFileHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.INFO); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(JsonFormatter.class); + + PeriodicSizeRotatingFileHandler periodicSizeRotatingFileHandler = (PeriodicSizeRotatingFileHandler) handler; + assertThat(periodicSizeRotatingFileHandler.isRotateOnBoot()).isFalse(); + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/SizeRotatingLoggingTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/SizeRotatingLoggingTest.java new file mode 100644 index 0000000000000..1ddb024b1f6a9 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/SizeRotatingLoggingTest.java @@ -0,0 +1,37 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.SizeRotatingFileHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class SizeRotatingLoggingTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-size-file-log-rotating.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")) + .setLogFileName("SizeRotatingLoggingTest.log"); + + @Test + public void sizeRotatingConfigurationTest() { + Handler handler = getHandler(SizeRotatingFileHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.INFO); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(JsonFormatter.class); + SizeRotatingFileHandler sizeRotatingFileHandler = (SizeRotatingFileHandler) handler; + assertThat(sizeRotatingFileHandler.isRotateOnBoot()).isTrue(); + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/SocketHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/SocketHandlerTest.java new file mode 100644 index 0000000000000..8886584f2c489 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/SocketHandlerTest.java @@ -0,0 +1,39 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.SocketHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; + +public class SocketHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-socket-output.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")); + + @Test + public void socketOutputTest() { + Handler handler = getHandler(SocketHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(JsonFormatter.class); + SocketHandler socketHandler = (SocketHandler) handler; + assertThat(socketHandler.getPort()).isEqualTo(5140); + assertThat(socketHandler.getAddress().getHostAddress()).isEqualTo("127.0.0.1"); + assertThat(socketHandler.getProtocol()).isEqualTo(SocketHandler.Protocol.TCP); + assertThat(socketHandler.isBlockOnReconnect()).isEqualTo(false); + } +} diff --git a/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/SyslogHandlerTest.java b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/SyslogHandlerTest.java new file mode 100644 index 0000000000000..86139f2c41376 --- /dev/null +++ b/integration-tests/logging-json/src/test/java/io/quarkus/it/logging/json/SyslogHandlerTest.java @@ -0,0 +1,47 @@ +package io.quarkus.it.logging.json; + +import io.quarkus.test.QuarkusUnitTest; +import org.jboss.logmanager.formatters.JsonFormatter; +import org.jboss.logmanager.formatters.PatternFormatter; +import org.jboss.logmanager.handlers.SyslogHandler; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import java.util.logging.Formatter; +import java.util.logging.Handler; +import java.util.logging.Level; + +import static io.quarkus.it.logging.json.LoggingTestsHelper.getHandler;; +import static org.assertj.core.api.Assertions.assertThat; +import static org.wildfly.common.net.HostName.getQualifiedHostName; +import static org.wildfly.common.os.Process.getProcessName; + +public class SyslogHandlerTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withConfigurationResource("application-syslog-output.properties") + .withApplicationRoot((jar) -> jar + .addClass(LoggingTestsHelper.class) + .addAsManifestResource("application.properties", "microprofile-config.properties")); + + @Test + public void syslogOutputTest() { + Handler handler = getHandler(SyslogHandler.class); + assertThat(handler.getLevel()).isEqualTo(Level.WARNING); + + Formatter formatter = handler.getFormatter(); + assertThat(formatter).isInstanceOf(JsonFormatter.class); + + SyslogHandler syslogHandler = (SyslogHandler) handler; + assertThat(syslogHandler.getPort()).isEqualTo(5140); + assertThat(syslogHandler.getAppName()).isEqualTo(getProcessName()); + assertThat(syslogHandler.getHostname()).isEqualTo(getQualifiedHostName()); + assertThat(syslogHandler.getFacility()).isEqualTo(SyslogHandler.Facility.USER_LEVEL); + assertThat(syslogHandler.getSyslogType()).isEqualTo(SyslogHandler.SyslogType.RFC5424); + assertThat(syslogHandler.getProtocol()).isEqualTo(SyslogHandler.Protocol.TCP); + assertThat(syslogHandler.isUseCountingFraming()).isEqualTo(false); + assertThat(syslogHandler.isTruncate()).isEqualTo(true); + assertThat(syslogHandler.isBlockOnReconnect()).isEqualTo(false); + } +} diff --git a/integration-tests/logging-json/src/test/resources/DSAPublicKey.encoded b/integration-tests/logging-json/src/test/resources/DSAPublicKey.encoded new file mode 100644 index 0000000000000..f3d3e7a80c453 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/DSAPublicKey.encoded @@ -0,0 +1 @@ +MIIDQjCCAjUGByqGSM44BAEwggIoAoIBAQCPeTXZuarpv6vtiHrPSVG28y7FnjuvNxjo6sSWHz79NgbnQ1GpxBgzObgJ58KuHFObp0dbhdARrbi0eYd1SYRpXKwOjxSzNggooi/6JxEKPWKpk0U0CaD+aWxGWPhL3SCBnDcJoBBXsZWtzQAjPbpUhLYpH51kjviDRIZ3l5zsBLQ0pqwudemYXeI9sCkvwRGMn/qdgYHnM423krcw17njSVkvaAmYchU5Feo9a4tGU8YzRY+AOzKkwuDycpAlbk4/ijsIOKHEUOThjBopo33fXqFD3ktm/wSQPtXPFiPhWNSHxgjpfyEc2B3KI8tuOAdl+CLjQr5ITAV2OTlgHNZnAh0AuvaWpoV499/e5/pnyXfHhe8ysjO65YDAvNVpXQKCAQAWplxYIEhQcE51AqOXVwQNNNo6NHjBVNTkpcAtJC7gT5bmHkvQkEq9rI837rHgnzGC0jyQQ8tkL4gAQWDt+coJsyB2p5wypifyRz6Rh5uixOdEvSCBVEy1W4AsNo0fqD7UielOD6BojjJCilx4xHjGjQUntxyaOrsLC+EsRGiWOefTznTbEBplqiuH9kxoJts+xy9LVZmDS7TtsC98kOmkltOlXVNb6/xF1PYZ9j897buHOSXC8iTgdzEpbaiH7B5HSPh++1/et1SEMWsiMt7lU92vAhErDR8C2jCXMiT+J67ai51LKSLZuovjntnhA6Y8UoELxoi34u1DFuHvF9veA4IBBQACggEAK6IeZShhydDUM5XsOJ/VAYPOgrnLr30AfKWLR39+FJBunVMWNPpvO5D9dU7B6nmSiLATpwhBDNEhyJ0ltmBGuFDBAkKkqE4l6l2iVh+C1TyYliv1P2LCJFNgrAJxyr+5Q5zM9hUgfbT66xnwCf/4aiO7nBlj4wOL3l9ABVllYifMZyKVYFGluXmo+jyyeAcCtzHi5SABbTOQJN0WXTlGtzxLFQ0QErDGhP1/A6z5lw5VHJn2aWMeTCaH+rJZpQfM8b2VWr7UEljqFgpSIHbrImuXcf2nP6uZLKFiDdAjDUyj0h2jXwwcdhwWXuhOEv8XIilkc9nMcPLqbdcQ4M5agg== \ No newline at end of file diff --git a/integration-tests/logging-json/src/test/resources/application-additional-fields.properties b/integration-tests/logging-json/src/test/resources/application-additional-fields.properties new file mode 100644 index 0000000000000..5c1f477714c4e --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-additional-fields.properties @@ -0,0 +1,10 @@ +quarkus.log.level=INFO +quarkus.log.socket.enable=true +quarkus.log.socket.endpoint=localhost:5140 +quarkus.log.socket.protocol=TCP +quarkus.log.console.enable=true +quarkus.log.console.json=false +quarkus.log.socket.json.additional-field.myownfield.value=testingvalue +quarkus.log.socket.level=WARNING +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-additional-handlers.properties b/integration-tests/logging-json/src/test/resources/application-additional-handlers.properties new file mode 100644 index 0000000000000..6d03d0e86e141 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-additional-handlers.properties @@ -0,0 +1,5 @@ +quarkus.log.level=INFO +quarkus.log.console.enable=true +quarkus.log.console.level=WARNING +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-async-console-log.properties b/integration-tests/logging-json/src/test/resources/application-async-console-log.properties new file mode 100644 index 0000000000000..a17d62867d9da --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-async-console-log.properties @@ -0,0 +1,7 @@ +quarkus.log.level=INFO +quarkus.log.console.enable=true +quarkus.log.console.level=WARNING +quarkus.log.console.async=true +quarkus.log.console.async.queue-length=256 +quarkus.log.console.async.overflow=DISCARD +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-async-file-log.properties b/integration-tests/logging-json/src/test/resources/application-async-file-log.properties new file mode 100644 index 0000000000000..c52ee30c55ee7 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-async-file-log.properties @@ -0,0 +1,7 @@ +quarkus.log.level=INFO +quarkus.log.file.enable=true +quarkus.log.file.level=INFO +quarkus.log.file.async=true +quarkus.log.file.async.queue-length=1024 +quarkus.log.file.async.overflow=block +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-async-socket-output.properties b/integration-tests/logging-json/src/test/resources/application-async-socket-output.properties new file mode 100644 index 0000000000000..c906a98fbe758 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-async-socket-output.properties @@ -0,0 +1,10 @@ +quarkus.log.level=INFO +quarkus.log.socket.enable=true +quarkus.log.socket.endpoint=localhost:5140 +quarkus.log.socket.protocol=TCP +quarkus.log.socket.level=WARNING +quarkus.log.socket.async=true +quarkus.log.socket.async.queue-length=256 +quarkus.log.socket.async.overflow=discard +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-async-syslog.properties b/integration-tests/logging-json/src/test/resources/application-async-syslog.properties new file mode 100644 index 0000000000000..5db148f68c13e --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-async-syslog.properties @@ -0,0 +1,16 @@ +quarkus.log.level=INFO +quarkus.log.syslog.enable=true +quarkus.log.syslog.endpoint=localhost:5144 +quarkus.log.syslog.app-name=quarkus +quarkus.log.syslog.hostname=quarkus-test +quarkus.log.syslog.facility=LOG_ALERT +quarkus.log.syslog.syslog-type=RFC3164 +quarkus.log.syslog.protocol=UDP +quarkus.log.syslog.use-counting-framing=true +quarkus.log.syslog.truncate=false +quarkus.log.syslog.block-on-reconnect=false +quarkus.log.syslog.level=WARNING +quarkus.log.syslog.async=true +quarkus.log.syslog.async.queue-length=256 +quarkus.log.syslog.async.overflow=discard +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-category-configured-handlers-output.properties b/integration-tests/logging-json/src/test/resources/application-category-configured-handlers-output.properties new file mode 100644 index 0000000000000..df9b7f9eaa7c2 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-category-configured-handlers-output.properties @@ -0,0 +1,21 @@ +quarkus.log.level=INFO +quarkus.log.console.enable=true +quarkus.log.console.level=WARNING +quarkus.log.console.json=false +# Configure a named handler that logs to console +quarkus.log.handler.console."STRUCTURED_LOGGING".enable=true +quarkus.log.handler.console."STRUCTURED_LOGGING".json=false +# Configure a named handler that logs to file +quarkus.log.handler.file."STRUCTURED_LOGGING_FILE".enable=true +quarkus.log.handler.file."STRUCTURED_LOGGING_FILE".json=true +quarkus.log.handler.file."STRUCTURED_LOGGING_FILE".json.additional-field.myfield.value=true +# Configure the category and link the two named handlers to it +quarkus.log.category."io.quarkus.category".level=INFO +quarkus.log.category."io.quarkus.category".handlers=STRUCTURED_LOGGING,STRUCTURED_LOGGING_FILE +# Configure other category and also link one named handler to it +quarkus.log.category."io.quarkus.othercategory".level=INFO +quarkus.log.category."io.quarkus.othercategory".handlers=STRUCTURED_LOGGING +# Configure other category and without linked named handlers +quarkus.log.category."io.quarkus.anothercategory".level=INFO +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-category-invalid-configured-handlers-output.properties b/integration-tests/logging-json/src/test/resources/application-category-invalid-configured-handlers-output.properties new file mode 100644 index 0000000000000..d76e9ee1f3019 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-category-invalid-configured-handlers-output.properties @@ -0,0 +1,12 @@ +quarkus.log.level=INFO +quarkus.log.console.enable=true +quarkus.log.console.level=WARNING +# Configure a named handler that logs to console +quarkus.log.handler.console."STRUCTURED_LOGGING".enable=true +# Configure a named handler that logs to file but uses the same name which is not allowed +quarkus.log.handler.file."STRUCTURED_LOGGING".enable=true +# Configure the category and link the two named handlers to it +quarkus.log.category."io.quarkus.category".level=INFO +quarkus.log.category."io.quarkus.category".handlers=STRUCTURED_LOGGING +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-console-output.properties b/integration-tests/logging-json/src/test/resources/application-console-output.properties new file mode 100644 index 0000000000000..6d03d0e86e141 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-console-output.properties @@ -0,0 +1,5 @@ +quarkus.log.level=INFO +quarkus.log.console.enable=true +quarkus.log.console.level=WARNING +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-file-output-log.properties b/integration-tests/logging-json/src/test/resources/application-file-output-log.properties new file mode 100644 index 0000000000000..a5a5dc47f9c60 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-file-output-log.properties @@ -0,0 +1,4 @@ +quarkus.log.level=INFO +quarkus.log.file.enable=true +quarkus.log.file.level=INFO +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-periodic-file-log-rotating.properties b/integration-tests/logging-json/src/test/resources/application-periodic-file-log-rotating.properties new file mode 100644 index 0000000000000..b7556c9e9cabd --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-periodic-file-log-rotating.properties @@ -0,0 +1,5 @@ +quarkus.log.level=INFO +quarkus.log.file.enable=true +quarkus.log.file.level=INFO +quarkus.log.file.rotation.file-suffix=.yyyy-MM-dd +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-periodic-size-file-log-rotating-rotate-on-boot.properties b/integration-tests/logging-json/src/test/resources/application-periodic-size-file-log-rotating-rotate-on-boot.properties new file mode 100644 index 0000000000000..599b660cb84da --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-periodic-size-file-log-rotating-rotate-on-boot.properties @@ -0,0 +1,6 @@ +quarkus.log.level=INFO +quarkus.log.file.enable=true +quarkus.log.file.level=INFO +quarkus.log.file.rotation.file-suffix=.yyyy-MM-dd +quarkus.log.file.rotation.rotate-on-boot=true +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-periodic-size-file-log-rotating.properties b/integration-tests/logging-json/src/test/resources/application-periodic-size-file-log-rotating.properties new file mode 100644 index 0000000000000..2f479402080c9 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-periodic-size-file-log-rotating.properties @@ -0,0 +1,7 @@ +quarkus.log.level=INFO +quarkus.log.file.enable=true +quarkus.log.file.level=INFO +quarkus.log.file.rotation.max-file-size=100 +quarkus.log.file.rotation.file-suffix=.yyyy-MM-dd +quarkus.log.file.rotation.rotate-on-boot=false +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-size-file-log-rotating.properties b/integration-tests/logging-json/src/test/resources/application-size-file-log-rotating.properties new file mode 100644 index 0000000000000..a771efa9781cf --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-size-file-log-rotating.properties @@ -0,0 +1,7 @@ +quarkus.log.level=INFO +quarkus.log.file.enable=true +quarkus.log.file.level=INFO +quarkus.log.file.rotation.max-file-size=1M +quarkus.log.file.rotation.max-backup-index=100 +quarkus.log.file.rotation.rotate-on-boot=true +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-socket-output.properties b/integration-tests/logging-json/src/test/resources/application-socket-output.properties new file mode 100644 index 0000000000000..ffa84f6004982 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-socket-output.properties @@ -0,0 +1,7 @@ +quarkus.log.level=INFO +quarkus.log.socket.enable=true +quarkus.log.socket.endpoint=localhost:5140 +quarkus.log.socket.protocol=TCP +quarkus.log.socket.level=WARNING +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application-syslog-output.properties b/integration-tests/logging-json/src/test/resources/application-syslog-output.properties new file mode 100644 index 0000000000000..fddd696eeabbf --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application-syslog-output.properties @@ -0,0 +1,9 @@ +quarkus.log.level=INFO +quarkus.log.syslog.enable=true +quarkus.log.syslog.endpoint=localhost:5140 +quarkus.log.syslog.facility=USER_LEVEL +quarkus.log.syslog.syslogType=RFC5424 +quarkus.log.syslog.protocol=TCP +quarkus.log.syslog.level=WARNING +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded diff --git a/integration-tests/logging-json/src/test/resources/application.properties b/integration-tests/logging-json/src/test/resources/application.properties new file mode 100644 index 0000000000000..f60115a75670d --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/application.properties @@ -0,0 +1,172 @@ +# Log settings +# log level in lower case for testing +quarkus.log.level=info +quarkus.log.file.enable=true +quarkus.log.file.level=INFO + +# Resource path to DSAPublicKey base64 encoded bytes +quarkus.root.dsa-key-location=/DSAPublicKey.encoded + +# Have the TestProcessor validate the build time configuration below +quarkus.root.validate-build-config=true + + +### Configuration settings for the TestBuildTimeConfig config root +quarkus.bt.bt-string-opt=btStringOptValue +quarkus.bt.bt-sbv=StringBasedValue +# This is not set so that we should get the @ConfigItem defaultValue +#quarkus.bt.bt-sbv-with-default=StringBasedValue +quarkus.bt.all-values.oov=configPart1+configPart2 +quarkus.bt.all-values.ovo=configPart1+configPart2 +# This is not set so that we should get the @ConfigItem defaultValue +#quarkus.bt.bt-oov-with-default=ObjectOfValue +quarkus.bt.all-values.long-primitive=1234567891 +quarkus.bt.all-values.double-primitive=3.1415926535897932384 +quarkus.bt.all-values.long-value=1234567892 +quarkus.bt.all-values.opt-long-value=1234567893 +quarkus.bt.all-values.opt-double-value=3.1415926535897932384 +quarkus.bt.all-values.optional-long-value=1234567894 +quarkus.bt.all-values.nested-config-map.key1.nested-value=value1 +quarkus.bt.all-values.nested-config-map.key1.oov=value1.1+value1.2 +quarkus.bt.all-values.nested-config-map.key2.nested-value=value2 +quarkus.bt.all-values.nested-config-map.key2.oov=value2.1+value2.2 +quarkus.bt.all-values.string-list=value1,value2 +quarkus.bt.all-values.long-list=1,2,3 +quarkus.bt.bt-config-value=value +quarkus.bt.bt-config-value-empty= + +### Duplicate settings for the TestBuildAndRunTimeConfig. May be able to drop if ConfigRoot inheritance is added +quarkus.btrt.bt-string-opt=btStringOptValue +quarkus.btrt.bt-sbv=StringBasedValue +quarkus.btrt.all-values.oov=configPart1+configPart2 +quarkus.btrt.all-values.ovo=configPart1+configPart2 +quarkus.btrt.all-values.long-primitive=1234567891 +quarkus.btrt.all-values.double-primitive=3.1415926535897932384 +quarkus.btrt.all-values.long-value=1234567892 +quarkus.btrt.all-values.opt-long-value=1234567893 +quarkus.btrt.all-values.opt-double-value=3.1415926535897932384 +quarkus.btrt.all-values.optional-long-value=1234567894 +quarkus.btrt.all-values.nested-config-map.key1.nested-value=value1 +quarkus.btrt.all-values.nested-config-map.key1.oov=value1.1+value1.2 +quarkus.btrt.all-values.nested-config-map.key2.nested-value=value2 +quarkus.btrt.all-values.nested-config-map.key2.oov=value2.1+value2.2 +quarkus.btrt.all-values.string-list=value1,value2 +quarkus.btrt.all-values.long-list=1,2,3 +# The expansion value is not available in runtime so we need to set it directly. +quarkus.btrt.all-values.expanded-default=1234 + +### Configuration settings for the TestRunTimeConfig config root +quarkus.rt.rt-string-opt=rtStringOptValue +quarkus.rt.rt-string-opt-with-default=rtStringOptWithDefaultValue +quarkus.rt.all-values.oov=configPart1+configPart2 +quarkus.rt.all-values.ovo=configPart1+configPart2 +quarkus.rt.all-values.long-primitive=12345678911 +quarkus.rt.all-values.double-primitive=3.1415926535897932384 +quarkus.rt.all-values.long-value=12345678921 +quarkus.rt.all-values.opt-long-value=12345678931 +quarkus.rt.all-values.opt-double-value=3.1415926535897932384 +quarkus.rt.all-values.optional-long-value=12345678941 +quarkus.rt.all-values.nested-config-map.key1.nested-value=value1 +quarkus.rt.all-values.nested-config-map.key1.oov=value1.1+value1.2 +quarkus.rt.all-values.nested-config-map.key2.nested-value=value2 +quarkus.rt.all-values.nested-config-map.key2.oov=value2.1+value2.2 +quarkus.rt.all-values.string-list=value1,value2 +quarkus.rt.all-values.long-list=1,2,3 +# A nested map of properties +quarkus.rt.all-values.string-map.key1=value1 +quarkus.rt.all-values.string-map.key2=value2 +quarkus.rt.all-values.string-map.key3=value3 +# And list form +quarkus.rt.all-values.string-list-map.key1=value1,value2,value3 +quarkus.rt.all-values.string-list-map.key2=value4,value5 +quarkus.rt.all-values.string-list-map.key3=value6 +# A root map of properties +quarkus.rt.string-map.key1=value1 +quarkus.rt.string-map.key2=value2 +quarkus.rt.string-map.key3=value3 +# And list form +quarkus.rt.string-list-map.key1=value1 +quarkus.rt.string-list-map.key2=value2,value3 +quarkus.rt.string-list-map.key3=value4,value5,value6 + +### run time configuration using enhanced converters +quarkus.rt.my-enum=enum-two +quarkus.rt.my-enums=enum-one,enum-two +quarkus.rt.my-optional-enums=optional +quarkus.rt.no-hyphenate-first-enum=ENUM_ONE +quarkus.rt.no-hyphenate-second-enum=Enum_Two +quarkus.rt.primitive-boolean=YES +quarkus.rt.object-boolean=NO +quarkus.rt.primitive-integer=two +quarkus.rt.object-integer=nine +quarkus.rt.one-to-nine=one,two,three,four,five,six,seven,eight,nine +quarkus.rt.map-of-numbers.key1=one +quarkus.rt.map-of-numbers.key2=two + +### map configurations +quarkus.rt.leaf-map.key.first=first-key-value +quarkus.rt.leaf-map.key.second=second-key-value +quarkus.rt.config-group-map.key.group.nested-value=value +quarkus.rt.config-group-map.key.group.oov=value2.1+value2.2 + +### build time and run time configuration using enhanced converters +quarkus.btrt.map-of-numbers.key1=one +quarkus.btrt.map-of-numbers.key2=two +quarkus.btrt.my-enum=optional +quarkus.btrt.my-enums=optional,enum-one,enum-two + +### anonymous root property +quarkus.test-property=foo + +### map of map of strings +quarkus.rt.map-map.outer-key.inner-key=1234 +quarkus.btrt.map-map.outer-key.inner-key=1234 +quarkus.bt.map-map.outer-key.inner-key=1234 + +# Test config root with "RuntimeConfig" suffix +quarkus.foo.bar=huhu + +### named map with profiles +quarkus.btrt.map-map.main-profile.property=1234 +%test.quarkus.btrt.map-map.test-profile.property=5678 + +### ordinal and default values source +config_ordinal=1000 +my.prop=1234 +%prod.my.prop=1234 +%dev.my.prop=5678 +%test.my.prop=1234 + +### Unknown properties +quarkus.unknown.prop=1234 +quarkus.http.non-application-root-path=/1234 +quarkus.http.ssl-port=4443 +# This is how Env Source will output property names (for maps) +QUARKUS_HTTP_NON_APPLICATION_ROOT_PATH=/1234 +quarkus.http.non.application.root.path=/1234 +QUARKUS_HTTP_SSL_PORT=4443 +quarkus.http.ssl.port=4443 +quarkus.arc.unremovable-types=foo +# The YAML source may add an indexed property (depending on how the YAML is layed out). This is not supported by @ConfigRoot +quarkus.arc.unremovable-types[0]=foo + +### Do not record env values in build time +bt.do.not.record=properties +%test.bt.profile.record=properties + +### prefix +my.prefix.prop=1234 +my.prefix.map.prop=1234 +my.prefix.nested.nested-value=nested-1234 +my.prefix.nested.oov=nested-1234+nested-5678 +my.prefix.named.prop=1234 +my.prefix.named.map.prop=1234 +my.prefix.named.nested.nested-value=nested-1234 +my.prefix.named.nested.oov=nested-1234+nested-5678 + +my.prefix.bt.prop=1234 +my.prefix.bt.nested.nested-value=nested-1234 +my.prefix.bt.nested.oov=nested-1234+nested-5678 + +another.another-prefix.prop=5678 +another.another-prefix.map.prop=5678 diff --git a/integration-tests/logging-json/src/test/resources/config.xml b/integration-tests/logging-json/src/test/resources/config.xml new file mode 100644 index 0000000000000..6d0057ee81257 --- /dev/null +++ b/integration-tests/logging-json/src/test/resources/config.xml @@ -0,0 +1,17 @@ + + +

localhost
+ 12345 + + + name1 + model1 + 2019-03-21T02:40:38Z + + + name2 + model2 + 2019-03-23T11:44:00Z + + + \ No newline at end of file diff --git a/integration-tests/logging-socket/src/main/java/io/quarkus/logging/socket/it/LoggingSocketResource.java b/integration-tests/logging-socket/src/main/java/io/quarkus/logging/socket/it/LoggingSocketResource.java new file mode 100644 index 0000000000000..b11c88228c712 --- /dev/null +++ b/integration-tests/logging-socket/src/main/java/io/quarkus/logging/socket/it/LoggingSocketResource.java @@ -0,0 +1,32 @@ +/* +* Licensed to the Apache Software Foundation (ASF) under one or more +* contributor license agreements. See the NOTICE file distributed with +* this work for additional information regarding copyright ownership. +* The ASF licenses this file to You 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.quarkus.logging.network.it; + +import javax.enterprise.context.ApplicationScoped; +import javax.ws.rs.GET; +import javax.ws.rs.Path; + +@Path("/logging-socket") +@ApplicationScoped +public class LoggingSocketResource { + // add some rest methods here + + @GET + public String hello() { + return "Hello logging-socket"; + } +} diff --git a/integration-tests/logging-socket/src/test/java/io/quarkus/logging/socket/it/LoggingSocketResourceTest.java b/integration-tests/logging-socket/src/test/java/io/quarkus/logging/socket/it/LoggingSocketResourceTest.java new file mode 100644 index 0000000000000..893e07ee37379 --- /dev/null +++ b/integration-tests/logging-socket/src/test/java/io/quarkus/logging/socket/it/LoggingSocketResourceTest.java @@ -0,0 +1,21 @@ +package io.quarkus.logging.network.it; + +import static io.restassured.RestAssured.given; +import static org.hamcrest.Matchers.is; + +import org.junit.jupiter.api.Test; + +import io.quarkus.test.junit.QuarkusTest; + +@QuarkusTest +public class LoggingSocketResourceTest { + + @Test + public void testHelloEndpoint() { + given() + .when().get("/logging-socket") + .then() + .statusCode(200) + .body(is("Hello logging-socket")); + } +} diff --git a/integration-tests/logging-socket/src/test/java/io/quarkus/logging/socket/it/NativeLoggingSocketResourceIT.java b/integration-tests/logging-socket/src/test/java/io/quarkus/logging/socket/it/NativeLoggingSocketResourceIT.java new file mode 100644 index 0000000000000..36a7ca3208fd9 --- /dev/null +++ b/integration-tests/logging-socket/src/test/java/io/quarkus/logging/socket/it/NativeLoggingSocketResourceIT.java @@ -0,0 +1,7 @@ +package io.quarkus.logging.network.it; + +import io.quarkus.test.junit.NativeImageTest; + +@NativeImageTest +public class NativeLoggingSocketResourceIT extends LoggingSocketResourceTest { +}