com.transferwise.tasks.health.TasksIncidentGenerator Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tw-tasks-incidents Show documentation
Show all versions of tw-tasks-incidents Show documentation
Reports stuck tasks and tasks in ERROR state in a form of incidents supported by
TransferWise incidents library - https://github.com/transferwise/tw-incidents.
Note that extension is deprecated and soon will be dropped, build alerting using metrics instead!
package com.transferwise.tasks.health;
import com.transferwise.common.incidents.Incident;
import com.transferwise.common.incidents.IncidentGenerator;
import com.transferwise.tasks.TasksProperties;
import com.transferwise.tasks.domain.TaskStatus;
import com.transferwise.tasks.entrypoints.EntryPoint;
import com.transferwise.tasks.entrypoints.EntryPointsGroups;
import com.transferwise.tasks.entrypoints.IEntryPointsService;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import lombok.Setter;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
public class TasksIncidentGenerator implements IncidentGenerator {
/**
* Key for the Incident metaData entry storing the number of stuck tasks.
*/
public static final String TASK_CNT_KEY = "cnt";
@Autowired
private TasksProperties tasksProperties;
@Autowired
private ITasksStateMonitor tasksStateMonitor;
@Autowired
@Setter
private IEntryPointsService entryPointsHelper;
private Incident errorIncident;
private Incident stuckIncident;
@Override
@EntryPoint(usesExisting = true)
public List getActiveIncidents() {
return entryPointsHelper.continueOrCreate(EntryPointsGroups.TW_TASKS_ENGINE, "ActiveIncidentsFinder",
() -> {
Map erroneousTasksCountByType = tasksStateMonitor.getErroneousTasksCountByType();
if (erroneousTasksCountByType != null && !erroneousTasksCountByType.isEmpty()) {
int cnt = erroneousTasksCountByType.values().stream().mapToInt(Integer::intValue).sum();
if (errorIncident == null) {
errorIncident = new Incident()
.setId("twTasks/error")
.setMessage(buildDetailedErrorReport(erroneousTasksCountByType, "in ERROR"))
.setSummary(cnt + " tasks in ERROR state.")
.setMetaData(Collections.singletonMap(TASK_CNT_KEY, String.valueOf(cnt)));
}
} else {
errorIncident = null;
}
Map, Integer> stuckTasksCountByStatusAndType = tasksStateMonitor.getStuckTasksCountByType();
if (stuckTasksCountByStatusAndType != null && !stuckTasksCountByStatusAndType.isEmpty()) {
int cnt = stuckTasksCountByStatusAndType.values().stream().mapToInt(Integer::intValue).sum();
if (stuckIncident == null) {
stuckIncident = new Incident()
.setId("twTasks/stuck")
.setMessage(buildDetailedStuckReport(stuckTasksCountByStatusAndType, "stuck"))
.setSummary("" + cnt + " tasks are stuck.")
.setMetaData(Collections.singletonMap(TASK_CNT_KEY, String.valueOf(cnt)));
}
} else {
stuckIncident = null;
}
return Arrays.asList(errorIncident, stuckIncident);
});
}
@Override
public Duration getPollingInterval() {
return tasksProperties.getStuckTasksPollingInterval();
}
private static String buildDetailedErrorReport(Map tasksInErrorPerType, String status) {
StringBuilder msg = new StringBuilder();
tasksInErrorPerType.forEach((type, count) -> {
msg.append("- ")
.append(count)
.append(" tasks of type ")
.append(type)
.append(" ").append(status).append("\n");
});
return msg.toString();
}
private static String buildDetailedStuckReport(Map, Integer> stuckTaskPerStatusAndType, String status) {
StringBuilder msg = new StringBuilder();
stuckTaskPerStatusAndType.forEach((statusAndType, count) -> {
msg.append("- ")
.append(count)
.append(" tasks of type ")
.append(statusAndType.getRight())
.append(" in status ")
.append(statusAndType.getLeft().name())
.append(" ").append(status).append("\n");
});
return msg.toString();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy