diff --git a/README.md b/README.md index 991be3c..98be251 100644 --- a/README.md +++ b/README.md @@ -46,10 +46,6 @@ To use this in your application, simply add this in your pom.xml: Note: Replace `${logger-manager.version}` with the latest version -Then browse to [http://localhost:8080/q/logging-manager-ui/](http://localhost:8080/q/logging-manager-ui/) - -![logger_manager_log_screenshot](logstream.gif "Log stream Screenshot") - ## OpenAPI You can include the Logger Manager API in the OpenAPI document (and thus also Swagger UI). This needs to be diff --git a/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerConfig.java b/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerConfig.java index 73aad3f..2a268a5 100644 --- a/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerConfig.java +++ b/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerConfig.java @@ -31,17 +31,4 @@ public class LoggingManagerConfig { */ @ConfigItem(defaultValue = "true") boolean alwaysInclude; - - /** - * The number of history log entries to remember. - */ - @ConfigItem(defaultValue = "50") - public int historySize; - - /** - * UI configuration - */ - @ConfigItem - @ConfigDocSection - LoggingManagerUIConfig ui; } diff --git a/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerOpenAPIFilter.java b/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerOpenAPIFilter.java index e706a36..4a04530 100644 --- a/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerOpenAPIFilter.java +++ b/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerOpenAPIFilter.java @@ -11,7 +11,7 @@ import org.eclipse.microprofile.openapi.models.media.Schema; import org.eclipse.microprofile.openapi.models.parameters.Parameter; -import io.quarkus.vertx.http.runtime.logstream.LogController; +import io.quarkiverse.loggingmanager.LogController; import io.smallrye.openapi.api.models.media.SchemaImpl; /** diff --git a/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerProcessor.java b/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerProcessor.java index 2bf697e..20159ae 100644 --- a/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerProcessor.java +++ b/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerProcessor.java @@ -1,28 +1,9 @@ package io.quarkiverse.loggingmanager.deployment; -import java.io.IOException; -import java.io.InputStream; -import java.net.URI; -import java.net.URISyntaxException; -import java.nio.file.FileSystem; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Collections; -import java.util.Iterator; -import java.util.Optional; import java.util.function.BooleanSupplier; -import java.util.stream.Stream; - -import org.eclipse.microprofile.config.Config; -import org.eclipse.microprofile.config.ConfigProvider; import io.quarkiverse.loggingmanager.LoggerManagerRecorder; import io.quarkiverse.loggingmanager.LoggingManagerRuntimeConfig; -import io.quarkus.arc.deployment.AdditionalBeanBuildItem; -import io.quarkus.builder.Version; -import io.quarkus.builder.item.SimpleBuildItem; import io.quarkus.deployment.Capabilities; import io.quarkus.deployment.Capability; import io.quarkus.deployment.annotations.BuildProducer; @@ -30,45 +11,17 @@ import io.quarkus.deployment.annotations.ExecutionTime; import io.quarkus.deployment.annotations.Record; import io.quarkus.deployment.builditem.FeatureBuildItem; -import io.quarkus.deployment.builditem.GeneratedResourceBuildItem; import io.quarkus.deployment.builditem.LaunchModeBuildItem; -import io.quarkus.deployment.builditem.LogHandlerBuildItem; -import io.quarkus.deployment.builditem.nativeimage.NativeImageResourceBuildItem; -import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; -import io.quarkus.deployment.configuration.ConfigurationError; -import io.quarkus.deployment.logging.LogStreamBuildItem; -import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; -import io.quarkus.deployment.util.IoUtil; -import io.quarkus.deployment.util.WebJarUtil; -import io.quarkus.maven.dependency.ResolvedDependency; -import io.quarkus.runtime.RuntimeValue; import io.quarkus.smallrye.openapi.deployment.spi.AddToOpenAPIDefinitionBuildItem; import io.quarkus.vertx.http.deployment.BodyHandlerBuildItem; -import io.quarkus.vertx.http.deployment.HttpRootPathBuildItem; import io.quarkus.vertx.http.deployment.NonApplicationRootPathBuildItem; import io.quarkus.vertx.http.deployment.RouteBuildItem; -import io.quarkus.vertx.http.runtime.logstream.JsonFormatter; -import io.quarkus.vertx.http.runtime.logstream.LogStreamRecorder; -import io.quarkus.vertx.http.runtime.logstream.LogStreamWebSocket; -import io.quarkus.vertx.http.runtime.logstream.WebSocketLogHandler; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; class LoggingManagerProcessor { private static final String FEATURE = "logging-manager"; - // For the UI - private static final String UI_WEBJAR_GROUP_ID = "io.quarkiverse.loggingmanager"; - private static final String UI_WEBJAR_ARTIFACT_ID = "quarkus-logging-manager"; - - private static final String UI_FINAL_DESTINATION = "META-INF/logging-manager-files"; - - private static final String STATIC_RESOURCE_FOLDER = "dev-static/"; - private static final String INDEX_HTML = "index.html"; - private static final String LOGO_SVG = "quarkiverse_icon_reverse.svg"; - - private final Config config = ConfigProvider.getConfig(); - static class OpenAPIIncluded implements BooleanSupplier { LoggingManagerConfig config; @@ -127,257 +80,8 @@ public void includeInOpenAPIEndpoint(BuildProducer annotatedProducer, - BuildProducer routeProducer, - BuildProducer loggingManagerBuildProducer, - BuildProducer logStreamBuildProducer, - HttpRootPathBuildItem httpRootPathBuildItem, - NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem, - BuildProducer generatedResourceProducer, - BuildProducer nativeImageResourceProducer, - CurateOutcomeBuildItem curateOutcomeBuildItem, - LaunchModeBuildItem launchMode, - LoggingManagerConfig loggingManagerConfig) throws Exception { - - if ("/".equals(loggingManagerConfig.ui.rootPath)) { - throw new ConfigurationError( - "quarkus.logging-manager.ui.root-path was set to \"/\", this is not allowed as it blocks the application from serving anything else."); - } - - ResolvedDependency resolvedDependency = WebJarUtil.getAppArtifact(curateOutcomeBuildItem, UI_WEBJAR_GROUP_ID, - UI_WEBJAR_ARTIFACT_ID); - ResolvedDependency userApplication = curateOutcomeBuildItem.getApplicationModel().getAppArtifact(); - - String uiPath = nonApplicationRootPathBuildItem.resolvePath(loggingManagerConfig.ui.rootPath); - - if (launchMode.getLaunchMode().isDevOrTest()) { - // The static resources - Path tempPath = WebJarUtil.createResourcesDirectory(userApplication, resolvedDependency); - - Path indexHtml = Paths.get(tempPath.toString(), INDEX_HTML); - if (!Files.exists(indexHtml)) { - Files.createFile(indexHtml); - } - String indexHtmlContent = getIndexHtmlContents(nonApplicationRootPathBuildItem.getNonApplicationRootPath(), - "/dev-v1/logstream"); - - Files.write(indexHtml, indexHtmlContent.getBytes()); - - Path logoSvg = Paths.get(tempPath.toString(), LOGO_SVG); - if (!Files.exists(logoSvg)) { - Files.createFile(logoSvg); - } - byte[] logo = getLogo(); - Files.write(logoSvg, logo); - - loggingManagerBuildProducer - .produce(new LoggingManagerBuildItem(tempPath.toAbsolutePath().toString(), uiPath)); - - } else if (loggingManagerConfig.ui.alwaysInclude) { - // Indicate that we need this in production - logStreamBuildProducer.produce(new LogStreamBuildItem()); - - // Make sure the WebSocket gets included. - annotatedProducer.produce(AdditionalBeanBuildItem.unremovableOf(LogStreamWebSocket.class)); - annotatedProducer.produce(AdditionalBeanBuildItem.unremovableOf(WebSocketLogHandler.class)); - - // Get the index.html - String indexHtmlContent = getIndexHtmlContents(nonApplicationRootPathBuildItem.getNonApplicationRootPath(), - "/" + loggingManagerConfig.basePath + "/logstream"); - // Update the resource Url to be relative - String pathToBeReplaced = nonApplicationRootPathBuildItem.resolvePath("dev-v1/resources"); - indexHtmlContent = indexHtmlContent.replaceAll(pathToBeReplaced + "/", ""); - String indexHtmlFileName = UI_FINAL_DESTINATION + "/" + INDEX_HTML; - generatedResourceProducer.produce(new GeneratedResourceBuildItem(indexHtmlFileName, indexHtmlContent.getBytes())); - nativeImageResourceProducer.produce(new NativeImageResourceBuildItem(indexHtmlFileName)); - - // Get the logo - byte[] logo = getLogo(); - String logoFileName = UI_FINAL_DESTINATION + "/" + LOGO_SVG; - - generatedResourceProducer.produce(new GeneratedResourceBuildItem(logoFileName, logo)); - nativeImageResourceProducer.produce(new NativeImageResourceBuildItem(logoFileName)); - - addStaticResource(generatedResourceProducer, nativeImageResourceProducer); - - loggingManagerBuildProducer.produce(new LoggingManagerBuildItem(UI_FINAL_DESTINATION, uiPath)); - } - } - - @BuildStep - @Record(ExecutionTime.STATIC_INIT) - public HistoryHandlerBuildItem hander(BuildProducer logHandlerBuildItemBuildProducer, - LogStreamRecorder recorder, - LoggingManagerConfig loggingManagerConfig, - LaunchModeBuildItem launchMode) { - - RuntimeValue> handler = recorder.logHandler(loggingManagerConfig.historySize); - if (!launchMode.getLaunchMode().isDevOrTest() && loggingManagerConfig.ui.alwaysInclude) { - logHandlerBuildItemBuildProducer.produce(new LogHandlerBuildItem((RuntimeValue) handler)); - } - return new HistoryHandlerBuildItem(handler); - } - - @BuildStep - @Record(ExecutionTime.RUNTIME_INIT) - void registerLoggingManagerUiHandler( - BuildProducer routeProducer, - BuildProducer reflectiveClassProducer, - NonApplicationRootPathBuildItem nonApplicationRootPathBuildItem, - LoggerManagerRecorder recorder, - HistoryHandlerBuildItem historyHandlerBuildItem, - LoggingManagerRuntimeConfig runtimeConfig, - LoggingManagerBuildItem loggingManagerBuildItem, - LaunchModeBuildItem launchMode, - LoggingManagerConfig loggingManagerConfig) throws Exception { - - if (shouldIncludeUi(launchMode, loggingManagerConfig)) { - Handler handler = recorder.uiHandler(loggingManagerBuildItem.getLoggingManagerFinalDestination(), - loggingManagerBuildItem.getLoggingManagerPath(), runtimeConfig); - - routeProducer.produce(nonApplicationRootPathBuildItem.routeBuilder() - .route(loggingManagerConfig.ui.rootPath) - .handler(handler) - .displayOnNotFoundPage("Quarkus Logging manager") - .build()); - routeProducer.produce(nonApplicationRootPathBuildItem.routeBuilder() - .route(loggingManagerConfig.ui.rootPath + "/*") - .handler(handler) - .build()); - - // Add the log stream (In dev mode, the stream is already available at /dev-v1/logstream) - if (!launchMode.getLaunchMode().isDevOrTest() && loggingManagerConfig.ui.alwaysInclude) { - - reflectiveClassProducer.produce(new ReflectiveClassBuildItem(true, true, - LogStreamWebSocket.class, - WebSocketLogHandler.class, - LogStreamWebSocket.class, - JsonFormatter.class)); - - Handler logStreamWebSocketHandler = recorder.logStreamWebSocketHandler(runtimeConfig, - historyHandlerBuildItem.value); - - routeProducer.produce(nonApplicationRootPathBuildItem.routeBuilder() - .nestedRoute(loggingManagerConfig.basePath, "logstream") - .handler(logStreamWebSocketHandler) - .build()); - } - } - } - - private byte[] getLogo() throws IOException { - try (InputStream logo = LoggingManagerProcessor.class.getClassLoader() - .getResourceAsStream("META-INF/resources/template/" + LOGO_SVG)) { - return IoUtil.readBytes(logo); - } - } - - private String getIndexHtmlContents(String nonApplicationRootPath, String streamingPath) throws IOException { - // Get the loggermanager html resources from Dev UI - try (InputStream nav = LoggingManagerProcessor.class.getClassLoader() - .getResourceAsStream("dev-templates/logmanagerNav.html"); - InputStream log = LoggingManagerProcessor.class.getClassLoader() - .getResourceAsStream("dev-templates/logmanagerLog.html"); - InputStream modals = LoggingManagerProcessor.class.getClassLoader() - .getResourceAsStream("dev-templates/logmanagerModals.html")) { - - String navContent = new String(IoUtil.readBytes(nav)); - String logContent = new String(IoUtil.readBytes(log)); - String modalsContent = new String(IoUtil.readBytes(modals)); - - try (InputStream index = LoggingManagerProcessor.class.getClassLoader() - .getResourceAsStream("META-INF/resources/template/loggermanager.html")) { - - String indexHtmlContent = new String(IoUtil.readBytes(index)); - - // Add the terminal (might contain vars) - indexHtmlContent = indexHtmlContent.replaceAll("\\{navContent}", - navContent); - indexHtmlContent = indexHtmlContent.replaceAll("\\{logContent}", - logContent); - indexHtmlContent = indexHtmlContent.replaceAll("\\{modalsContent}", - modalsContent); - - // Make sure the non apllication path and streaming path is replaced - indexHtmlContent = indexHtmlContent.replaceAll("\\{frameworkRootPath}", - cleanFrameworkRootPath(nonApplicationRootPath)); - - indexHtmlContent = indexHtmlContent.replaceAll("\\{devRootAppend}", - cleanFrameworkRootPath(nonApplicationRootPath) + "/dev-v1"); - - indexHtmlContent = indexHtmlContent.replaceAll("\\{streamingPath}", - streamingPath); - - // Make sure the application name and version is replaced - indexHtmlContent = indexHtmlContent.replaceAll("\\{applicationName}", - config.getOptionalValue("quarkus.application.name", String.class).orElse("")); - indexHtmlContent = indexHtmlContent.replaceAll("\\{applicationVersion}", - config.getOptionalValue("quarkus.application.version", String.class).orElse("")); - indexHtmlContent = indexHtmlContent.replaceAll("\\{quarkusVersion}", - Version.getVersion()); - - return indexHtmlContent; - } - } - } - - /** - * This removes the last / from the path - * - * @param p the path - * @return the path without the last / - */ - private String cleanFrameworkRootPath(String p) { - if (p != null && !p.isEmpty() && p.endsWith("/")) { - return p.substring(0, p.length() - 1); - } - return p; - } - - private void addStaticResource(BuildProducer generatedResourceProducer, - BuildProducer nativeImageResourceProducer) throws IOException, URISyntaxException { - - FileSystem fileSystem = getFileSystem(); - Path myPath = fileSystem.getPath(STATIC_RESOURCE_FOLDER); - - Stream walk = Files.walk(myPath, 5); - for (Iterator it = walk.iterator(); it.hasNext();) { - Path staticResource = it.next(); - if (!Files.isDirectory(staticResource) && Files.isRegularFile(staticResource)) { - String fileName = UI_FINAL_DESTINATION + "/" - + staticResource.toString().substring(STATIC_RESOURCE_FOLDER.length()); - byte[] content = Files.readAllBytes(staticResource); - generatedResourceProducer.produce(new GeneratedResourceBuildItem(fileName, content)); - nativeImageResourceProducer.produce(new NativeImageResourceBuildItem(fileName)); - } - } - } - - private FileSystem getFileSystem() throws URISyntaxException, IOException { - URI uri = null; - try { - uri = LoggingManagerProcessor.class.getClassLoader().getResource(STATIC_RESOURCE_FOLDER).toURI(); - return FileSystems.newFileSystem(uri, Collections. emptyMap()); - } catch (java.nio.file.FileSystemAlreadyExistsException ex) { - return FileSystems.getFileSystem(uri); - } - } - - private static boolean shouldIncludeUi(LaunchModeBuildItem launchMode, LoggingManagerConfig loggingManagerConfig) { - return launchMode.getLaunchMode().isDevOrTest() || loggingManagerConfig.ui.alwaysInclude; - } - private static boolean shouldInclude(LaunchModeBuildItem launchMode, LoggingManagerConfig loggingManagerConfig) { return launchMode.getLaunchMode().isDevOrTest() || loggingManagerConfig.alwaysInclude; } - public static final class HistoryHandlerBuildItem extends SimpleBuildItem { - final RuntimeValue> value; - - public HistoryHandlerBuildItem(RuntimeValue> value) { - this.value = value; - } - } } diff --git a/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerUIConfig.java b/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerUIConfig.java deleted file mode 100644 index f93b877..0000000 --- a/deployment/src/main/java/io/quarkiverse/loggingmanager/deployment/LoggingManagerUIConfig.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.quarkiverse.loggingmanager.deployment; - -import io.quarkus.runtime.annotations.ConfigGroup; -import io.quarkus.runtime.annotations.ConfigItem; - -@ConfigGroup -public class LoggingManagerUIConfig { - - /** - * The path where Logging Manager is available. - * The value `/` is not allowed as it blocks the application from serving anything else. - */ - @ConfigItem(defaultValue = "logging-manager-ui") - String rootPath; - - /** - * Always include the UI. By default this will only be included in dev and test. - * Setting this to true will also include the UI in Prod - */ - @ConfigItem(defaultValue = "false") - boolean alwaysInclude; -} diff --git a/deployment/src/main/resources/META-INF/resources/template/loggermanager.html b/deployment/src/main/resources/META-INF/resources/template/loggermanager.html deleted file mode 100644 index 41d64b2..0000000 --- a/deployment/src/main/resources/META-INF/resources/template/loggermanager.html +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - Logging manager | {applicationName} {applicationVersion} - - - - - - - - - {logContent} - {modalsContent} - - - - - - - diff --git a/deployment/src/main/resources/META-INF/resources/template/quarkiverse_icon_reverse.svg b/deployment/src/main/resources/META-INF/resources/template/quarkiverse_icon_reverse.svg deleted file mode 100644 index 1c93f74..0000000 --- a/deployment/src/main/resources/META-INF/resources/template/quarkiverse_icon_reverse.svg +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/deployment/src/main/resources/dev-templates/embedded.html b/deployment/src/main/resources/dev-templates/embedded.html deleted file mode 100644 index e0d2543..0000000 --- a/deployment/src/main/resources/dev-templates/embedded.html +++ /dev/null @@ -1,11 +0,0 @@ - - - Logging manager UI -
-{#if config:property('quarkus.logging-manager.openapi.included') == 'true'} - - - Spec in Swagger UI -{/if} - - diff --git a/deployment/src/test/java/io/quarkiverse/loggingmanager/deployment/ErroneousConfigTest.java b/deployment/src/test/java/io/quarkiverse/loggingmanager/deployment/ErroneousConfigTest.java index e2b110e..1fee5a0 100644 --- a/deployment/src/test/java/io/quarkiverse/loggingmanager/deployment/ErroneousConfigTest.java +++ b/deployment/src/test/java/io/quarkiverse/loggingmanager/deployment/ErroneousConfigTest.java @@ -7,14 +7,14 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; -import io.quarkus.deployment.configuration.ConfigurationError; +import io.quarkus.runtime.configuration.ConfigurationException; import io.quarkus.test.QuarkusUnitTest; public class ErroneousConfigTest { @RegisterExtension static final QuarkusUnitTest config = new QuarkusUnitTest() - .setExpectedException(ConfigurationError.class) + .setExpectedException(ConfigurationException.class) .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) .addAsResource(new StringAsset("quarkus.logging-manager.ui.root-path=/\n"), "application.properties")); diff --git a/logstream.gif b/logstream.gif deleted file mode 100644 index 0252a28..0000000 Binary files a/logstream.gif and /dev/null differ diff --git a/pom.xml b/pom.xml index 51d5381..8b277a1 100644 --- a/pom.xml +++ b/pom.xml @@ -22,7 +22,7 @@ 11 11 true - 3.2.4.Final + 3.3.0 3.11.0 diff --git a/runtime/src/main/java/io/quarkiverse/loggingmanager/LevelHandler.java b/runtime/src/main/java/io/quarkiverse/loggingmanager/LevelHandler.java index f552576..99cf847 100644 --- a/runtime/src/main/java/io/quarkiverse/loggingmanager/LevelHandler.java +++ b/runtime/src/main/java/io/quarkiverse/loggingmanager/LevelHandler.java @@ -2,7 +2,6 @@ import static io.vertx.core.http.HttpMethod.GET; -import io.quarkus.vertx.http.runtime.logstream.LogController; import io.vertx.core.Handler; import io.vertx.core.http.HttpMethod; import io.vertx.core.http.HttpServerRequest; diff --git a/runtime/src/main/java/io/quarkiverse/loggingmanager/LogController.java b/runtime/src/main/java/io/quarkiverse/loggingmanager/LogController.java new file mode 100644 index 0000000..f145e3d --- /dev/null +++ b/runtime/src/main/java/io/quarkiverse/loggingmanager/LogController.java @@ -0,0 +1,125 @@ +package io.quarkiverse.loggingmanager; + +import static org.jboss.logmanager.Level.ALL; +import static org.jboss.logmanager.Level.CONFIG; +import static org.jboss.logmanager.Level.DEBUG; +import static org.jboss.logmanager.Level.ERROR; +import static org.jboss.logmanager.Level.FATAL; +import static org.jboss.logmanager.Level.FINE; +import static org.jboss.logmanager.Level.FINER; +import static org.jboss.logmanager.Level.FINEST; +import static org.jboss.logmanager.Level.INFO; +import static org.jboss.logmanager.Level.OFF; +import static org.jboss.logmanager.Level.SEVERE; +import static org.jboss.logmanager.Level.TRACE; +import static org.jboss.logmanager.Level.WARN; +import static org.jboss.logmanager.Level.WARNING; + +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.TreeMap; +import java.util.logging.Level; + +import org.jboss.logmanager.LogContext; +import org.jboss.logmanager.Logger; + +import io.quarkus.vertx.http.runtime.devmode.Json; + +/** + * Allow controlling to the log levels + */ +public class LogController { + private static final org.jboss.logging.Logger LOG = org.jboss.logging.Logger.getLogger(LogController.class); + + private LogController() { + } + + public static Json.JsonArrayBuilder getLevels() { + Json.JsonArrayBuilder array = Json.array(); + for (String level : LEVELS) { + array.add(level); + } + return array; + } + + public static Json.JsonArrayBuilder getLoggers() { + LogContext logContext = LogContext.getLogContext(); + TreeMap loggerMap = new TreeMap<>(); + + Enumeration loggerNames = logContext.getLoggerNames(); + while (loggerNames.hasMoreElements()) { + String loggerName = loggerNames.nextElement(); + Json.JsonObjectBuilder jsonObject = getLogger(loggerName); + if (jsonObject != null) { + loggerMap.put(loggerName, jsonObject); + } + } + + List orderedLoggers = new ArrayList<>(loggerMap.values()); + Json.JsonArrayBuilder jsonArray = Json.array(); + jsonArray.addAll(orderedLoggers); + return jsonArray; + } + + public static Json.JsonObjectBuilder getLogger(String loggerName) { + LogContext logContext = LogContext.getLogContext(); + if (loggerName != null && !loggerName.isEmpty()) { + Logger logger = logContext.getLogger(loggerName); + Json.JsonObjectBuilder jsonObject = Json.object(); + jsonObject.put("name", loggerName); + jsonObject.put("effectiveLevel", getEffectiveLogLevel(logger)); + jsonObject.put("configuredLevel", getConfiguredLogLevel(logger)); + return jsonObject; + } + return null; + } + + public static void updateLogLevel(String loggerName, String levelValue) { + LogContext logContext = LogContext.getLogContext(); + Logger logger = logContext.getLogger(loggerName); + java.util.logging.Level level; + if (levelValue == null || levelValue.isBlank()) { + if (logger.getParent() != null) { + level = logger.getParent().getLevel(); + } else { + throw new IllegalArgumentException("The level of the root logger cannot be set to null"); + } + } else { + level = Level.parse(levelValue); + } + logger.setLevel(level); + LOG.info("Log level updated [" + loggerName + "] changed to [" + levelValue + "]"); + } + + private static String getConfiguredLogLevel(Logger logger) { + java.util.logging.Level level = logger.getLevel(); + return level != null ? level.getName() : null; + } + + private static String getEffectiveLogLevel(Logger logger) { + if (logger == null) { + return null; + } + if (logger.getLevel() != null) { + return logger.getLevel().getName(); + } + return getEffectiveLogLevel(logger.getParent()); + } + + public static final List LEVELS = List.of( + OFF.getName(), + SEVERE.getName(), + ERROR.getName(), + FATAL.getName(), + WARNING.getName(), + WARN.getName(), + INFO.getName(), + DEBUG.getName(), + TRACE.getName(), + CONFIG.getName(), + FINE.getName(), + FINER.getName(), + FINEST.getName(), + ALL.getName()); +} diff --git a/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggerHandler.java b/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggerHandler.java index 6fe6987..7d003ce 100644 --- a/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggerHandler.java +++ b/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggerHandler.java @@ -3,7 +3,6 @@ import static io.vertx.core.http.HttpMethod.GET; import static io.vertx.core.http.HttpMethod.POST; -import io.quarkus.vertx.http.runtime.logstream.LogController; import io.vertx.core.Handler; import io.vertx.core.http.HttpMethod; import io.vertx.core.http.HttpServerRequest; diff --git a/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggerManagerRecorder.java b/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggerManagerRecorder.java index 2e53d4a..1633e22 100644 --- a/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggerManagerRecorder.java +++ b/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggerManagerRecorder.java @@ -1,12 +1,8 @@ package io.quarkiverse.loggingmanager; -import java.util.Optional; import java.util.function.Consumer; -import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.annotations.Recorder; -import io.quarkus.vertx.http.runtime.logstream.LogStreamWebSocket; -import io.quarkus.vertx.http.runtime.logstream.WebSocketLogHandler; import io.vertx.core.Handler; import io.vertx.ext.web.Route; import io.vertx.ext.web.RoutingContext; @@ -22,25 +18,6 @@ public Handler levelHandler() { return new LevelHandler(); } - public Handler uiHandler(String loggingManagerFinalDestination, String loggingManagerPath, - LoggingManagerRuntimeConfig runtimeConfig) { - - if (runtimeConfig.enableUi) { - return new LoggingManagerStaticHandler(loggingManagerFinalDestination, loggingManagerPath); - } else { - return new LoggingManagerNotFoundHandler(); - } - } - - public Handler logStreamWebSocketHandler(LoggingManagerRuntimeConfig runtimeConfig, - RuntimeValue> historyHandler) { - if (runtimeConfig.enableUi) { - return new LogStreamWebSocket(historyHandler.getValue().get()); - } else { - return new LoggingManagerNotFoundHandler(); - } - } - public Consumer routeConsumer(Handler bodyHandler, LoggingManagerRuntimeConfig runtimeConfig) { if (runtimeConfig.enable) { return new Consumer() { diff --git a/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggingManagerRuntimeConfig.java b/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggingManagerRuntimeConfig.java index 7fdbbd8..24a8aec 100644 --- a/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggingManagerRuntimeConfig.java +++ b/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggingManagerRuntimeConfig.java @@ -7,13 +7,6 @@ @ConfigRoot(name = "logging-manager", phase = ConfigPhase.RUN_TIME) public class LoggingManagerRuntimeConfig { - /** - * If Logging Manager UI should be enabled. By default, Logging Manager UI is enabled if it is included (see - * {@code always-include}). - */ - @ConfigItem(name = "ui.enable", defaultValue = "true") - boolean enableUi; - /** * If Logging Manager should be enabled. By default, Logging Manager is enabled if it is included (see * {@code always-include}). diff --git a/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggingManagerStaticHandler.java b/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggingManagerStaticHandler.java deleted file mode 100644 index 12c9fb5..0000000 --- a/runtime/src/main/java/io/quarkiverse/loggingmanager/LoggingManagerStaticHandler.java +++ /dev/null @@ -1,60 +0,0 @@ -package io.quarkiverse.loggingmanager; - -import io.vertx.core.Handler; -import io.vertx.core.http.HttpHeaders; -import io.vertx.ext.web.RoutingContext; -import io.vertx.ext.web.handler.StaticHandler; - -/** - * Handling static Logging Manager content - */ -public class LoggingManagerStaticHandler implements Handler { - - private String loggingManagerFinalDestination; - private String loggingManagerPath; - - public LoggingManagerStaticHandler() { - } - - public LoggingManagerStaticHandler(String loggingManagerFinalDestination, String loggingManagerPath) { - this.loggingManagerFinalDestination = loggingManagerFinalDestination; - this.loggingManagerPath = loggingManagerPath; - } - - public String getLoggingManagerFinalDestination() { - return loggingManagerFinalDestination; - } - - public void setLoggingManagerFinalDestination(String loggingManagerFinalDestination) { - this.loggingManagerFinalDestination = loggingManagerFinalDestination; - } - - public String getLoggingManagerPath() { - return loggingManagerPath; - } - - public void setLoggingManagerPath(String loggingManagerPath) { - this.loggingManagerPath = loggingManagerPath; - } - - @Override - public void handle(RoutingContext event) { - StaticHandler staticHandler = StaticHandler.create().setAllowRootFileSystemAccess(true) - .setWebRoot(loggingManagerFinalDestination) - .setDefaultContentEncoding("UTF-8"); - - if (event.normalizedPath().length() == loggingManagerPath.length()) { - - event.response().setStatusCode(302); - event.response().headers().set(HttpHeaders.LOCATION, loggingManagerPath + "/"); - event.response().end(); - return; - } else if (event.normalizedPath().length() == loggingManagerPath.length() + 1) { - event.reroute(loggingManagerPath + "/index.html"); - return; - } - - staticHandler.handle(event); - } - -}