From: Mathieu Baudier Date: Thu, 30 Dec 2021 07:59:31 +0000 (+0100) Subject: Fall back to java.util.logging in a pure OSGi environment X-Git-Tag: argeo-commons-2.3.5~116 X-Git-Url: https://git.argeo.org/?a=commitdiff_plain;h=01b972e4abce933b3ce06bd18e933b08d3b35464;p=lgpl%2Fargeo-commons.git Fall back to java.util.logging in a pure OSGi environment --- diff --git a/demo/argeo-init.properties b/demo/argeo-init.properties new file mode 100644 index 000000000..08df826be --- /dev/null +++ b/demo/argeo-init.properties @@ -0,0 +1,24 @@ +#argeo.osgi.baseUrl=http://forge.argeo.org/data/java/argeo-2.1/ +#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.sdk/2.1.65/org.argeo.dep.cms.sdk-2.1.65.jar +#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.sdk/2.1.67/org.argeo.dep.cms.sdk-2.1.67.jar +#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.sdk/2.1.68-SNAPSHOT/org.argeo.dep.cms.sdk-2.1.68-SNAPSHOT.jar + +#argeo.osgi.boot.debug=true + +argeo.osgi.start.1.osgiboot=org.argeo.init +#argeo.osgi.start.2.node=org.eclipse.equinox.http.servlet,org.eclipse.equinox.http.jetty,org.eclipse.equinox.cm,org.eclipse.rap.rwt.osgi +#argeo.osgi.start.3.node=org.argeo.cms,org.eclipse.gemini.blueprint.extender,org.eclipse.equinox.http.registry + +#java.security.manager= +#java.security.policy=file:../../all.policy + +argeo.node.repo.type=localfs +org.osgi.service.http.port=7070 +log4j.configuration=file:../../log4j.properties + +#java.util.logging.config.file=../../logging.properties + + +# DON'T CHANGE BELOW +org.eclipse.rap.workbenchAutostart=false +org.eclipse.equinox.http.jetty.autostart=false \ No newline at end of file diff --git a/demo/argeo_node_osgiboot.properties b/demo/argeo_node_osgiboot.properties deleted file mode 100644 index 2a8c3513b..000000000 --- a/demo/argeo_node_osgiboot.properties +++ /dev/null @@ -1,21 +0,0 @@ -#argeo.osgi.baseUrl=http://forge.argeo.org/data/java/argeo-2.1/ -#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.sdk/2.1.65/org.argeo.dep.cms.sdk-2.1.65.jar -#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.sdk/2.1.67/org.argeo.dep.cms.sdk-2.1.67.jar -#argeo.osgi.distributionUrl=org/argeo/commons/org.argeo.dep.cms.sdk/2.1.68-SNAPSHOT/org.argeo.dep.cms.sdk-2.1.68-SNAPSHOT.jar - -#argeo.osgi.boot.debug=true - -argeo.osgi.start.1.osgiboot=org.argeo.osgi.boot -#argeo.osgi.start.2.node=org.eclipse.equinox.http.servlet,org.eclipse.equinox.http.jetty,org.eclipse.equinox.cm,org.eclipse.rap.rwt.osgi -#argeo.osgi.start.3.node=org.argeo.cms,org.eclipse.gemini.blueprint.extender,org.eclipse.equinox.http.registry - -#java.security.manager= -#java.security.policy=file:../../all.policy - -argeo.node.repo.type=localfs -org.osgi.service.http.port=7070 -log4j.configuration=file:../../log4j.properties - -# DON'T CHANGE BELOW -org.eclipse.rap.workbenchAutostart=false -org.eclipse.equinox.http.jetty.autostart=false \ No newline at end of file diff --git a/demo/cms-e4-rap.properties b/demo/cms-e4-rap.properties index feeab0748..5e1e6545d 100644 --- a/demo/cms-e4-rap.properties +++ b/demo/cms-e4-rap.properties @@ -3,7 +3,8 @@ org.eclipse.equinox.http.servlet,\ org.eclipse.equinox.metatype,\ org.eclipse.equinox.cm,\ org.eclipse.equinox.ds,\ -org.eclipse.rap.rwt.osgi +org.eclipse.rap.rwt.osgi,\ +org.argeo.init argeo.osgi.start.3.node=\ org.argeo.cms diff --git a/demo/logging.properties b/demo/logging.properties new file mode 100644 index 000000000..bf86d0947 --- /dev/null +++ b/demo/logging.properties @@ -0,0 +1,65 @@ +############################################################ +# Default Logging Configuration File +# +# You can use a different file by specifying a filename +# with the java.util.logging.config.file system property. +# For example java -Djava.util.logging.config.file=myfile +############################################################ + +############################################################ +# Global properties +############################################################ + +# "handlers" specifies a comma separated list of log Handler +# classes. These handlers will be installed during VM startup. +# Note that these classes must be on the system classpath. +# By default we only configure a ConsoleHandler, which will only +# show messages at the INFO and above levels. +#handlers= java.util.logging.ConsoleHandler +#handlers=org.argeo.init.logging.jse.ThinHandler +handlers= + +# To also add the FileHandler, use the following line instead. +#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler + +# Default global logging level. +# This specifies which kinds of events are logged across +# all loggers. For any given facility this global level +# can be overriden by a facility specific level +# Note that the ConsoleHandler also has a separate level +# setting to limit messages printed to the console. +.level= INFO + +############################################################ +# Handler specific properties. +# Describes specific configuration info for Handlers. +############################################################ + +# default file output is in user's home directory. +java.util.logging.FileHandler.pattern = %h/java%u.log +java.util.logging.FileHandler.limit = 50000 +java.util.logging.FileHandler.count = 1 +# Default number of locks FileHandler can obtain synchronously. +# This specifies maximum number of attempts to obtain lock file by FileHandler +# implemented by incrementing the unique field %u as per FileHandler API documentation. +java.util.logging.FileHandler.maxLocks = 100 +java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter + +# Limit the message that are printed on the console to INFO and above. +java.util.logging.ConsoleHandler.level = INFO +java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter + +# Example to customize the SimpleFormatter output format +# to print one-line log message like this: +# : [] +# +# java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n + +############################################################ +# Facility specific properties. +# Provides extra control for each logger. +############################################################ + +# For example, set the com.xyz.foo logger to only log SEVERE +# messages: +com.xyz.foo.level = SEVERE diff --git a/org.argeo.init/bnd.bnd b/org.argeo.init/bnd.bnd index f42151273..734c77440 100644 --- a/org.argeo.init/bnd.bnd +++ b/org.argeo.init/bnd.bnd @@ -3,6 +3,8 @@ Class-Path: org.eclipse.osgi.jar Bundle-Activator: org.argeo.init.osgi.Activator -Import-Package: org.osgi.*;version=0.0.0 +Import-Package: \ +org.osgi.*;version=0.0.0,\ +java.util.logging.*;resolution:=optional Private-Package: * Export-Package: !* diff --git a/org.argeo.init/src/org/argeo/init/logging/ThinHandler.java b/org.argeo.init/src/org/argeo/init/logging/ThinHandler.java new file mode 100644 index 000000000..e6f4c62ca --- /dev/null +++ b/org.argeo.init/src/org/argeo/init/logging/ThinHandler.java @@ -0,0 +1,45 @@ +package org.argeo.init.logging; + +import java.lang.System.Logger.Level; +import java.util.logging.Handler; +import java.util.logging.LogRecord; + +/** + * A fallback {@link Handler} forwarding only messages and logger name (all + * other {@link LogRecord} information is lost. + */ +class ThinHandler extends Handler { + @Override + public void publish(LogRecord record) { + java.lang.System.Logger systemLogger = ThinLoggerFinder.getLogger(record.getLoggerName()); + systemLogger.log(fromJulLevel(record.getLevel()), record.getMessage()); + } + + protected Level fromJulLevel(java.util.logging.Level julLevel) { + if (java.util.logging.Level.ALL.equals(julLevel)) + return Level.ALL; + else if (java.util.logging.Level.FINER.equals(julLevel)) + return Level.TRACE; + else if (java.util.logging.Level.FINE.equals(julLevel)) + return Level.DEBUG; + else if (java.util.logging.Level.INFO.equals(julLevel)) + return Level.INFO; + else if (java.util.logging.Level.WARNING.equals(julLevel)) + return Level.WARNING; + else if (java.util.logging.Level.SEVERE.equals(julLevel)) + return Level.ERROR; + else if (java.util.logging.Level.OFF.equals(julLevel)) + return Level.OFF; + else + throw new IllegalArgumentException("Unsupported JUL level " + julLevel); + } + + @Override + public void flush() { + } + + @Override + public void close() throws SecurityException { + } + +} \ No newline at end of file diff --git a/org.argeo.init/src/org/argeo/init/logging/ThinJavaUtilLogging.java b/org.argeo.init/src/org/argeo/init/logging/ThinJavaUtilLogging.java new file mode 100644 index 000000000..5b51d00bd --- /dev/null +++ b/org.argeo.init/src/org/argeo/init/logging/ThinJavaUtilLogging.java @@ -0,0 +1,18 @@ +package org.argeo.init.logging; + +import java.util.logging.LogManager; +import java.util.logging.Logger; + +/** + * Fallback wrapper around the java.util.logging framework, when thinb logging + * could not be instantiated directly. + */ +class ThinJavaUtilLogging { + public static void init() { + LogManager logManager = LogManager.getLogManager(); + logManager.reset(); + Logger rootLogger = logManager.getLogger(""); + rootLogger.addHandler(new ThinHandler()); + rootLogger.setLevel(java.util.logging.Level.FINE); + } +} diff --git a/org.argeo.init/src/org/argeo/init/logging/ThinLoggerFinder.java b/org.argeo.init/src/org/argeo/init/logging/ThinLoggerFinder.java index 784930946..9607c9478 100644 --- a/org.argeo.init/src/org/argeo/init/logging/ThinLoggerFinder.java +++ b/org.argeo.init/src/org/argeo/init/logging/ThinLoggerFinder.java @@ -5,9 +5,11 @@ import java.lang.System.LoggerFinder; /** Factory for Java system logging. */ public class ThinLoggerFinder extends LoggerFinder { - private ThinLogging logging; + private static ThinLogging logging; public ThinLoggerFinder() { + if (logging != null) + throw new IllegalStateException("Only one logging can be initialised."); logging = new ThinLogging(); } @@ -16,4 +18,17 @@ public class ThinLoggerFinder extends LoggerFinder { return logging.getLogger(name, module); } + /** + * Falls back to java.util.logging if thin logging was not already initialised. + */ + public static void lazyInit() { + if (logging != null) + return; + logging = new ThinLogging(); + ThinJavaUtilLogging.init(); + } + + public static Logger getLogger(String name) { + return logging.getLogger(name, null); + } } diff --git a/org.argeo.init/src/org/argeo/init/logging/ThinLogging.java b/org.argeo.init/src/org/argeo/init/logging/ThinLogging.java index e7edc19a8..44baa6919 100644 --- a/org.argeo.init/src/org/argeo/init/logging/ThinLogging.java +++ b/org.argeo.init/src/org/argeo/init/logging/ThinLogging.java @@ -22,8 +22,6 @@ import java.util.concurrent.TimeUnit; /** A thin logging system based on the {@link Logger} framework. */ class ThinLogging { -// private static ThinLogging instance; - private SortedMap loggers = new TreeMap<>(); private NavigableMap levels = new TreeMap<>(); @@ -31,10 +29,6 @@ class ThinLogging { private final LogEntryPublisher publisher; ThinLogging() { -// if (instance != null) -// throw new IllegalStateException("Only one logger finder cann be instantiated"); -// instance = this; - executor = Executors.newCachedThreadPool((r) -> { Thread t = new Thread(r); t.setDaemon(true); @@ -46,6 +40,8 @@ class ThinLogging { publisher.subscribe(subscriber); Runtime.getRuntime().addShutdownHook(new Thread(() -> close(), "Log shutdown")); + + setDefaultLevel(Level.DEBUG); } protected void close() { diff --git a/org.argeo.init/src/org/argeo/init/osgi/Activator.java b/org.argeo.init/src/org/argeo/init/osgi/Activator.java index 5a9527041..3e0d8e117 100644 --- a/org.argeo.init/src/org/argeo/init/osgi/Activator.java +++ b/org.argeo.init/src/org/argeo/init/osgi/Activator.java @@ -1,9 +1,9 @@ package org.argeo.init.osgi; -import java.util.Enumeration; -import java.util.ResourceBundle; -import java.util.Vector; +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import org.argeo.init.logging.ThinLoggerFinder; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; @@ -13,9 +13,17 @@ import org.osgi.framework.BundleContext; * //wiki.eclipse.org/Configurator */ public class Activator implements BundleActivator { + static { + // must be called first + ThinLoggerFinder.lazyInit(); + } + Logger logger = System.getLogger(Activator.class.getName()); + private Long checkpoint = null; public void start(final BundleContext bundleContext) throws Exception { + logger.log(Level.DEBUG, () -> "Argeo init via OSGi activator"); + // admin thread Thread adminThread = new AdminThread(bundleContext); adminThread.start(); @@ -33,24 +41,4 @@ public class Activator implements BundleActivator { public void stop(BundleContext context) throws Exception { } - - class JournaldResourceBundle extends ResourceBundle { - - @Override - protected Object handleGetObject(String key) { - switch (key) { - case "ERROR": - return "<5>"; - } - return null; - } - - @Override - public Enumeration getKeys() { - Vector keys = new Vector<>(); - keys.add("ERROR"); - return keys.elements(); - } - - } }