package io.dropwizard.servlets.tasks;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import org.slf4j.ILoggerFactory;
import org.slf4j.LoggerFactory;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.PrintWriter;
import java.time.Duration;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicReference;
public class LogConfigurationTask extends Task {
private final ILoggerFactory loggerContext;
private final AtomicReference<Timer> timerReference = new AtomicReference<>();
public LogConfigurationTask() {
this(LoggerFactory.getILoggerFactory());
}
public LogConfigurationTask(ILoggerFactory loggerContext) {
super("log-level");
this.loggerContext = loggerContext;
}
@Override
public void execute(Map<String, List<String>> parameters, PrintWriter output) throws Exception {
final List<String> loggerNames = getLoggerNames(parameters);
final Level loggerLevel = getLoggerLevel(parameters);
final Duration duration = getDuration(parameters);
for (String loggerName : loggerNames) {
Logger logger = ((LoggerContext) loggerContext).getLogger(loggerName);
String message = String.format("Configured logging level for %s to %s", loggerName, loggerLevel);
if (loggerLevel != null && duration != null) {
final long millis = duration.toMillis();
getTimer().schedule(new TimerTask() {
@Override
public void run() {
logger.setLevel(null);
}
}, millis);
message += String.format(" for %s milliseconds", millis);
}
logger.setLevel(loggerLevel);
output.println(message);
output.flush();
}
}
private List<String> getLoggerNames(Map<String, List<String>> parameters) {
return parameters.getOrDefault("logger", Collections.emptyList());
}
@Nullable
private Level getLoggerLevel(Map<String, List<String>> parameters) {
final List<String> loggerLevels = parameters.getOrDefault("level", Collections.emptyList());
return loggerLevels.isEmpty() ? null : Level.valueOf(loggerLevels.get(0));
}
@Nullable
private Duration getDuration(Map<String, List<String>> parameters) {
final List<String> durations = parameters.getOrDefault("duration", Collections.emptyList());
return durations.isEmpty() ? null : Duration.parse(durations.get(0));
}
@Nonnull
private Timer getTimer() {
return timerReference.updateAndGet(timer -> timer == null ? new Timer(LogConfigurationTask.class.getSimpleName(), true) : timer);
}
}