Improve Argeo Init shutdown sequence.
[lgpl/argeo-commons.git] / org.argeo.init / src / org / argeo / init / logging / ThinLogging.java
index 9866a1f232e2a218d9c98d8699b089f619ca7d01..e21899394dda63abdef24514b9bad69516974472 100644 (file)
@@ -26,6 +26,9 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 import java.util.function.Consumer;
 
+import org.argeo.init.RuntimeContext;
+import org.argeo.init.Service;
+
 /**
  * A thin logging system based on the {@link Logger} framework. It is a
  * {@link Consumer} of configuration, and can be registered as such.
@@ -115,6 +118,15 @@ class ThinLogging implements Consumer<Map<String, Object>> {
        }
 
        private void close() {
+               RuntimeContext runtimeContext = Service.getRuntimeContext();
+               if (runtimeContext != null) {
+                       try {
+                               runtimeContext.waitForStop(0);
+                       } catch (InterruptedException e) {
+                               // silent
+                       }
+               }
+
                publisher.close();
                try {
                        // we ait a bit in order to make sure all messages are flushed
@@ -216,7 +228,7 @@ class ThinLogging implements Consumer<Map<String, Object>> {
        /*
         * INTERNAL CLASSES
         */
-       
+
        private class ThinLogger implements System.Logger {
                private final String name;
 
@@ -274,6 +286,8 @@ class ThinLogging implements Consumer<Map<String, Object>> {
 
                        // NOTE: this is the method called when logging a plain message without
                        // exception, so it should be considered as a format only when args are not null
+                       if (format.contains("{}"))// workaround for weird Jetty formatting
+                               params = null;
                        String msg = params == null ? format : MessageFormat.format(format, params);
                        publisher.log(this, level, bundle, msg, now, thread, (Throwable) null, findCallLocation(level, thread));
                }
@@ -285,6 +299,7 @@ class ThinLogging implements Consumer<Map<String, Object>> {
                private StackTraceElement findCallLocation(Level level, Thread thread) {
                        assert level != null;
                        assert thread != null;
+                       // TODO rather use a StackWalker and make it smarter
                        StackTraceElement callLocation = null;
                        if (level.getSeverity() >= callLocationLevel.getSeverity()) {
                                StackTraceElement[] stack = thread.getStackTrace();
@@ -293,13 +308,17 @@ class ThinLogging implements Consumer<Map<String, Object>> {
                                        String className = stack[i].getClassName();
                                        switch (className) {
                                        // TODO make it more configurable
+                                       // FIXME deal with privileges stacks (in Equinox)
                                        case "java.lang.System$Logger":
                                        case "java.util.logging.Logger":
                                        case "org.apache.commons.logging.Log":
                                        case "org.osgi.service.log.Logger":
-                                       case "org.argeo.cms.Log":
+                                       case "org.eclipse.osgi.internal.log.LoggerImpl":
+                                       case "org.argeo.api.cms.CmsLog":
                                        case "org.slf4j.impl.ArgeoLogger":
+                                       case "org.argeo.cms.internal.osgi.CmsOsgiLogger":
                                        case "org.eclipse.jetty.util.log.Slf4jLog":
+                                       case "sun.util.logging.internal.LoggingProviderImpl$JULWrapper":
                                                lowestLoggerInterface = i;
                                                continue stack;
                                        default:
@@ -353,7 +372,8 @@ class ThinLogging implements Consumer<Map<String, Object>> {
                        logEntry.put(KEY_THREAD, thread.getName());
 
                        // should be unmodifiable for security reasons
-                       submit(Collections.unmodifiableMap(logEntry));
+                       if (!isClosed())
+                               submit(Collections.unmodifiableMap(logEntry));
                }
 
        }
@@ -519,12 +539,13 @@ class ThinLogging implements Consumer<Map<String, Object>> {
                        sb.append('\n');
                        for (StackTraceElement ste : throwable.getStackTrace()) {
                                sb.append(prefix);
+                               sb.append('\t');
                                sb.append(ste.toString());
                                sb.append('\n');
                        }
                        if (throwable.getCause() != null) {
                                sb.append(prefix);
-                               sb.append("caused by ");
+                               sb.append("Caused by: ");
                                addThrowable(sb, prefix, throwable.getCause());
                        }
                }