package io.dropwizard.setup;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;
import com.codahale.metrics.health.jvm.ThreadDeadlockHealthCheck;
import io.dropwizard.jetty.MutableServletContextHandler;
import io.dropwizard.jetty.setup.ServletEnvironment;
import io.dropwizard.servlets.tasks.GarbageCollectionTask;
import io.dropwizard.servlets.tasks.LogConfigurationTask;
import io.dropwizard.servlets.tasks.Task;
import io.dropwizard.servlets.tasks.TaskServlet;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.LifeCycle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static com.google.common.base.MoreObjects.firstNonNull;
import static java.util.Objects.requireNonNull;
public class AdminEnvironment extends ServletEnvironment {
private static final Logger LOGGER = LoggerFactory.getLogger(AdminEnvironment.class);
private final HealthCheckRegistry healthChecks;
private final TaskServlet tasks;
public AdminEnvironment(MutableServletContextHandler handler,
HealthCheckRegistry healthChecks, MetricRegistry metricRegistry) {
super(handler);
this.healthChecks = healthChecks;
this.healthChecks.register("deadlocks", new ThreadDeadlockHealthCheck());
this.tasks = new TaskServlet(metricRegistry);
tasks.add(new GarbageCollectionTask());
tasks.add(new LogConfigurationTask());
addServlet("tasks", tasks).addMapping("/tasks/*");
handler.addLifeCycleListener(new AbstractLifeCycle.AbstractLifeCycleListener() {
@Override
public void lifeCycleStarting(LifeCycle event) {
logTasks();
logHealthChecks();
}
});
}
public void addTask(Task task) {
tasks.add(requireNonNull(task));
}
private void logTasks() {
final StringBuilder stringBuilder = new StringBuilder(1024).append(String.format("%n%n"));
for (Task task : tasks.getTasks()) {
final String taskClassName = firstNonNull(task.getClass().getCanonicalName(), task.getClass().getName());
stringBuilder.append(String.format(" %-7s /tasks/%s (%s)%n",
"POST",
task.getName(),
taskClassName));
}
LOGGER.info("tasks = {}", stringBuilder.toString());
}
private void logHealthChecks() {
if (healthChecks.getNames().size() <= 1) {
LOGGER.warn(String.format(
"%n" +
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%n" +
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%n" +
"! THIS APPLICATION HAS NO HEALTHCHECKS. THIS MEANS YOU WILL NEVER KNOW !%n" +
"! IF IT DIES IN PRODUCTION, WHICH MEANS YOU WILL NEVER KNOW IF YOU'RE !%n" +
"! LETTING YOUR USERS DOWN. YOU SHOULD ADD A HEALTHCHECK FOR EACH OF YOUR !%n" +
"! APPLICATION'S DEPENDENCIES WHICH FULLY (BUT LIGHTLY) TESTS IT. !%n" +
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!%n" +
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
));
}
LOGGER.debug("health checks = {}", healthChecks.getNames());
}
}