java-commons/commons-logger/src/main/java/io/gitlab/jfronny/commons/logger/HotswapLoggerFactory.java

76 lines
2.4 KiB
Java

package io.gitlab.jfronny.commons.logger;
import org.jetbrains.annotations.Nullable;
import org.slf4j.ILoggerFactory;
import org.slf4j.Logger;
import org.slf4j.event.Level;
import java.util.Objects;
public class HotswapLoggerFactory implements LeveledLoggerFactory {
private LeveledLoggerFactory defaultFactory = StdoutLogger::fancy;
private Level minimumLevel = Level.INFO;
private int version = 0;
public void resetStrategy() {
updateStrategy(StdoutLogger::fancy);
}
public void updateStrategy(ILoggerFactory factory) {
if (factory instanceof LeveledLoggerFactory f) {
updateStrategy(f);
} else {
updateStrategy((name, level) -> factory.getLogger(name));
}
}
public void updateStrategy(LeveledLoggerFactory factory) {
synchronized (this) {
defaultFactory = Objects.requireNonNull(factory);
version++;
}
}
public void updateDefaultLevel(Level minimumLevel) {
synchronized (this) {
this.minimumLevel = Objects.requireNonNull(minimumLevel);
version++;
}
}
@Override
public Logger getLogger(String name, @Nullable Level level) {
return new SwappableDelegateLogger(name, level);
}
private class SwappableDelegateLogger extends DelegateLogger {
private final String name;
private final boolean keepLevel;
private Level lastMinimumLevel;
private Logger delegate;
int version = -1;
private SwappableDelegateLogger(String name, @Nullable Level level) {
this.name = name == null ? "null" : name;
this.keepLevel = level != null;
this.lastMinimumLevel = level == null ? HotswapLoggerFactory.this.minimumLevel : level;
updateStrategy();
}
public void updateStrategy() {
if (this.version == HotswapLoggerFactory.this.version) return;
synchronized (HotswapLoggerFactory.this) {
this.version = HotswapLoggerFactory.this.version;
if (!keepLevel) this.lastMinimumLevel = HotswapLoggerFactory.this.minimumLevel;
this.delegate = HotswapLoggerFactory.this.defaultFactory.getLogger(this.name, this.lastMinimumLevel);
}
}
@Override
protected Logger getDelegate() {
updateStrategy();
return delegate;
}
}
}