MarginaliaSearch/code/services-application/status-service/java/nu/marginalia/status/StatusService.java
Viktor Lofgren 3791ea1e18 (service) Add a new application service for external liveness monitoring
The new service 'status-service' will poll public endpoints periodically, and publish a basic read-only UI with the results, as well as publish the results to prometheus.
2024-11-17 18:01:08 +01:00

66 lines
2.3 KiB
Java

package nu.marginalia.status;
import com.google.inject.Inject;
import nu.marginalia.renderer.RendererFactory;
import nu.marginalia.service.server.BaseServiceParams;
import nu.marginalia.service.server.Service;
import nu.marginalia.status.db.StatusMetricDb;
import nu.marginalia.status.endpoints.ApiEndpoint;
import nu.marginalia.status.endpoints.MainSearchEndpoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import static spark.Spark.get;
public class StatusService extends Service {
private final ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(5);
private final StatusMetricDb statusMetricDb;
private final List<StatusMetric> metrics = new ArrayList<>();
private static final Logger logger = LoggerFactory.getLogger(StatusService.class);
@Inject
public StatusService(BaseServiceParams params,
StatusMetricDb statusMetricDb,
ApiEndpoint apiEndpoint,
RendererFactory rendererFactory,
MainSearchEndpoint mainSearchEndpoint
) throws Exception {
super(params);
this.statusMetricDb = statusMetricDb;
metrics.add(new StatusMetric("Public JSON Api", apiEndpoint::check));
metrics.add(new StatusMetric("Public HTML Endpoint", mainSearchEndpoint::check));
scheduledExecutorService.scheduleAtFixedRate(this::poll, 0, 15, TimeUnit.SECONDS);
scheduledExecutorService.scheduleAtFixedRate(statusMetricDb::pruneOldResults, 0, 1, TimeUnit.HOURS);
var statusRenderer = rendererFactory.renderer("status");
get("/", (req, res) -> statusRenderer.render(
Map.of("measurements", statusMetricDb.getAllStatistics()))
);
}
private void poll() {
for (StatusMetric metric : metrics) {
try {
statusMetricDb.saveResult(metric.update());
}
catch (Exception e) {
logger.error("Failed to update metric " + metric.getName(), e);
}
}
}
}