package edu.uncc.cs.watsonsim;
import java.util.function.Consumer;
/**
* Wrapper logger
*
* Loggers already allow many modules to log to many places.
* But we need each module to log to some (but not all) places. So basically,
* want to pass around a fancy many-to-many channel.
*
* @author Sean
*
*/
public class Log {
private Consumer<String> listener;
private final Log parent;
private final Class<?> speaker;
private final long start;
private enum Level {ERROR, WARNING, INFO, DEBUG};
public static final Log NIL = new Log(Object.class, x->{});
// Start a root logger
public Log(Object speaker, Consumer<String> listener) {
this.parent = null;
this.speaker = speaker.getClass();
this.start = System.currentTimeMillis();
this.listener = listener;
}
// Start a child logger
private Log(Object speaker, Log parent) {
this.parent = parent;
this.speaker = speaker.getClass();
this.start = parent.start;
}
/**
* Make a new writable subchannel.
*/
public Log kid(Class<?> speaker) {
return new Log(speaker, this);
}
public void setListener(Consumer<String> listener) {
this.listener = listener;
}
/**
* Push some notifications. Listeners may lose interest.
*/
private void push(String content, Level level) {
if (listener != null) {
listener.accept(String.format("%.2f [%s %s] %s",
(System.currentTimeMillis()-start) / 1000.0,
level.name(),
speaker.getSimpleName(),
content));
} else if (parent != null) {
parent.push(content, level);
}
}
public void error(String message) {
push(message, Level.ERROR);
}
public void warn(String message) {
push(message, Level.WARNING);
}
public void info(String message) {
push(message, Level.INFO);
}
public void debug(String message) {
push(message, Level.DEBUG);
}
}