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.
}
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
/*
* INTERNAL CLASSES
*/
-
+
private class ThinLogger implements System.Logger {
private final String name;
// 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));
}
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();
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:
logEntry.put(KEY_THREAD, thread.getName());
// should be unmodifiable for security reasons
- submit(Collections.unmodifiableMap(logEntry));
+ if (!isClosed())
+ submit(Collections.unmodifiableMap(logEntry));
}
}
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());
}
}