diff --git a/nucleus/glassfish-jul-extension/pom.xml b/nucleus/glassfish-jul-extension/pom.xml index 93333a05c6e..26690962a4a 100644 --- a/nucleus/glassfish-jul-extension/pom.xml +++ b/nucleus/glassfish-jul-extension/pom.xml @@ -34,6 +34,7 @@ org.glassfish.main.jul.GlassFishLogManager + false diff --git a/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/GlassFishLogManager.java b/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/GlassFishLogManager.java index 1b6a944af44..2a4b97128da 100644 --- a/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/GlassFishLogManager.java +++ b/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/GlassFishLogManager.java @@ -47,8 +47,10 @@ import org.glassfish.main.jul.cfg.ConfigurationHelper; import org.glassfish.main.jul.cfg.GlassFishLogManagerConfiguration; import org.glassfish.main.jul.cfg.GlassFishLogManagerProperty; +import org.glassfish.main.jul.cfg.GlassFishLoggingConstants; import org.glassfish.main.jul.cfg.LoggingProperties; import org.glassfish.main.jul.env.LoggingSystemEnvironment; +import org.glassfish.main.jul.handler.BlockingExternallyManagedLogHandler; import org.glassfish.main.jul.handler.ExternallyManagedLogHandler; import org.glassfish.main.jul.handler.SimpleLogHandler; import org.glassfish.main.jul.handler.SimpleLogHandler.SimpleLogHandlerProperty; @@ -88,8 +90,10 @@ * @author David Matejcek */ public class GlassFishLogManager extends LogManager { + /** Empty string - standard root logger name */ public static final String ROOT_LOGGER_NAME = ""; + private static final String LOGGING_PROPERTIES = "logging.properties"; private static final ReentrantLock LOCK = new ReentrantLock(); @@ -104,6 +108,10 @@ public class GlassFishLogManager extends LogManager { private GlassFishLogManagerConfiguration configuration; + /** + * @deprecated Too late - if user enables ie GC logging, it initiates the JDK LogManager before this. + */ + @Deprecated static boolean initialize(final Properties configuration) { trace(GlassFishLogManager.class, "initialize(configuration)"); if (status.ordinal() > GlassFishLoggingStatus.UNINITIALIZED.ordinal()) { @@ -697,21 +705,29 @@ private static LoggingProperties ensureSortedProperties(final Properties propert private static LoggingProperties provideProperties() { try { - final LoggingProperties propertiesFromJvmOption = toProperties(System.getProperty(JVM_OPT_LOGGING_CFG_FILE)); + if (Boolean.getBoolean(GlassFishLoggingConstants.JVM_OPT_LOGGING_CFG_BLOCK)) { + final LoggingProperties cfg = new LoggingProperties(); + cfg.setProperty(KEY_ROOT_HANDLERS.getPropertyName(), + BlockingExternallyManagedLogHandler.class.getName()); + return cfg; + } + final String file = System.getProperty(JVM_OPT_LOGGING_CFG_FILE); + final LoggingProperties propertiesFromJvmOption = toProperties(file); if (propertiesFromJvmOption != null) { + trace(GlassFishLogManager.class, () -> "Using file " + file); return propertiesFromJvmOption; } + if (Boolean.getBoolean(JVM_OPT_LOGGING_CFG_USE_DEFAULTS)) { + return createDefaultProperties(); + } final LoggingProperties propertiesFromClasspath = loadFromClasspath(); if (propertiesFromClasspath != null) { return propertiesFromClasspath; } - if (Boolean.getBoolean(JVM_OPT_LOGGING_CFG_USE_DEFAULTS)) { - return createDefaultProperties(); - } throw new IllegalStateException( - "Could not find any logging.properties configuration file neither from JVM option (" - + JVM_OPT_LOGGING_CFG_FILE + ") nor from classpath and even " + JVM_OPT_LOGGING_CFG_USE_DEFAULTS - + " wasn't set to true."); + "Could not find any configuration. The JVM option " + + JVM_OPT_LOGGING_CFG_FILE + " was not set, the JVM option " + JVM_OPT_LOGGING_CFG_USE_DEFAULTS + + " was disabled and no " + LOGGING_PROPERTIES + " were found on classpath."); } catch (final IOException e) { throw new IllegalStateException("Could not load logging configuration file.", e); } @@ -725,6 +741,7 @@ private static LoggingProperties createDefaultProperties() { cfg.setProperty(KEY_USR_ROOT_LOGGER_LEVEL.getPropertyName(), level); cfg.setProperty(KEY_ROOT_HANDLERS.getPropertyName(), SimpleLogHandler.class.getName()); cfg.setProperty(SimpleLogHandlerProperty.LEVEL.getPropertyFullName(), level); + trace(GlassFishLogManager.class, () -> "Using internal defaults: " + cfg); return cfg; } @@ -744,10 +761,12 @@ private static LoggingProperties toProperties(final String absolutePath) throws private static LoggingProperties loadFromClasspath() throws IOException { final ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); trace(GlassFishLogManager.class, () -> "loadFromClasspath(); classloader: " + classLoader); - try (InputStream input = classLoader.getResourceAsStream("logging.properties")) { + try (InputStream input = classLoader.getResourceAsStream(LOGGING_PROPERTIES)) { if (input == null) { return null; } + trace(GlassFishLogManager.class, + () -> "Using file from classpath: " + classLoader.getResource(LOGGING_PROPERTIES)); return LoggingProperties.loadFrom(input); } } diff --git a/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/GlassFishLogManagerInitializer.java b/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/GlassFishLogManagerInitializer.java index 66bce2f36a4..d69a5c527da 100644 --- a/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/GlassFishLogManagerInitializer.java +++ b/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/GlassFishLogManagerInitializer.java @@ -20,6 +20,8 @@ import java.util.logging.LogManager; import java.util.logging.Logger; +import org.glassfish.main.jul.cfg.GlassFishLoggingConstants; + import static org.glassfish.main.jul.cfg.GlassFishLoggingConstants.CLASS_LOG_MANAGER_GLASSFISH; import static org.glassfish.main.jul.cfg.GlassFishLoggingConstants.JVM_OPT_LOGGING_MANAGER; import static org.glassfish.main.jul.tracing.GlassFishLoggingTracer.stacktrace; @@ -33,9 +35,15 @@ * in the JVM starts the initialization. *

* Simply said - this must be the first thing application must execute. + *

+ * As an example, when you enable GC logging, it will be always faster than this class. + * That is why is this class deprecated and we recommend to use the + * {@link GlassFishLoggingConstants#JVM_OPT_LOGGING_MANAGER} and other related options + * which guarantee that the log manager will be set. * * @author David Matejcek */ +@Deprecated public final class GlassFishLogManagerInitializer { private GlassFishLogManagerInitializer() { @@ -43,7 +51,6 @@ private GlassFishLogManagerInitializer() { } - /** * Tries to set the {@link GlassFishLogManager}as the JVM's {@link LogManager} implementation. * This must be done before any JUL component is used and remains set until JVM shutdown. diff --git a/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/cfg/GlassFishLoggingConstants.java b/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/cfg/GlassFishLoggingConstants.java index 2e17a4cc72a..414377f17d4 100644 --- a/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/cfg/GlassFishLoggingConstants.java +++ b/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/cfg/GlassFishLoggingConstants.java @@ -45,6 +45,13 @@ public class GlassFishLoggingConstants { * existence. */ public static final String JVM_OPT_LOGGING_MANAGER = "java.util.logging.manager"; + + /** + * System property name to ask the starting log manager to block until application finishes + * the configuration. + */ + public static final String JVM_OPT_LOGGING_CFG_BLOCK = "java.util.logging.config.block"; + /** * System property name defining property file which will be automatically loaded on startup. * Usually it is named logging.properties @@ -52,7 +59,7 @@ public class GlassFishLoggingConstants { public static final String JVM_OPT_LOGGING_CFG_FILE = "java.util.logging.config.file"; /** * System property telling the GlassFishLogManager to use defaults if there would not be any - * logging.properties neither set by {@value #JVM_OPT_LOGGING_CFG_FILE} nor available on classpath. + * logging.properties set by {@value #JVM_OPT_LOGGING_CFG_FILE}. *

* Defaults use the SimpleLogHandler and level INFO or level set by * {@value #JVM_OPT_LOGGING_CFG_DEFAULT_LEVEL} @@ -76,6 +83,9 @@ public class GlassFishLoggingConstants { *

* If the property is not set, GJULE makes the decision based on the (*.printSource * property) - if any formatter requires this feature, the feature is enabled. + * This applies just when the formatter is set from the supplied log manager configuration, + * not when you configure formatter from your code. + * *

* It is disabled otherwise. */ diff --git a/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/formatter/OneLineFormatter.java b/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/formatter/OneLineFormatter.java index 0dd0e1dd801..2500d80967d 100644 --- a/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/formatter/OneLineFormatter.java +++ b/nucleus/glassfish-jul-extension/src/main/java/org/glassfish/main/jul/formatter/OneLineFormatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022 Eclipse Foundation and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024 Eclipse Foundation and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -19,7 +19,9 @@ import java.util.Arrays; import java.util.logging.Formatter; import java.util.logging.LogRecord; +import java.util.logging.Logger; +import org.glassfish.main.jul.cfg.GlassFishLoggingConstants; import org.glassfish.main.jul.cfg.LogProperty; import org.glassfish.main.jul.record.GlassFishLogRecord; @@ -31,6 +33,12 @@ /** * Fast {@link Formatter} usable in tests or even in production if you need only simple logs with * time, level and messages. + *

+ * Note that if you configured the formatter from your code (and not a property file), + * if you want to source class and method automatically detected, you have to enable + * {@link GlassFishLoggingConstants#KEY_CLASS_AND_METHOD_DETECTION_ENABLED}. Without that the output + * will contain just class and method fields manually set to the LogRecord or using {@link Logger} + * methods which have these parameters to do that. * * @author David Matejcek */ diff --git a/nucleus/glassfish-jul-extension/src/test/java/org/glassfish/main/jul/GlassFishLogManagerLifeCycleTest.java b/nucleus/glassfish-jul-extension/src/test/java/org/glassfish/main/jul/GlassFishLogManagerLifeCycleTest.java index e54895824df..285682e4c7f 100644 --- a/nucleus/glassfish-jul-extension/src/test/java/org/glassfish/main/jul/GlassFishLogManagerLifeCycleTest.java +++ b/nucleus/glassfish-jul-extension/src/test/java/org/glassfish/main/jul/GlassFishLogManagerLifeCycleTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023 Eclipse Foundation and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024 Eclipse Foundation and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0, which is available at @@ -98,7 +98,6 @@ public static void resetConfiguration() throws Exception { * {@link BlockingExternallyManagedLogHandler} to block logging system in * {@link GlassFishLoggingStatus#CONFIGURING} state, so it is just collecting * log records to the StartupQueue. - *

*/ @Test @Order(1) diff --git a/nucleus/parent/pom.xml b/nucleus/parent/pom.xml index 0423a28a29f..faf623f6f25 100644 --- a/nucleus/parent/pom.xml +++ b/nucleus/parent/pom.xml @@ -186,6 +186,7 @@ java.util.logging.LogManager INFO + true @@ -883,7 +884,7 @@ ${test.logManager} - true + ${test.enableDefaultLogCfg} ${test.logLevel} ${glassfish.suspend} @@ -906,7 +907,7 @@ ${test.logManager} - true + ${test.enableDefaultLogCfg} ${test.logLevel}