All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.transferwise.tasks.health.TasksIncidentGenerator Maven / Gradle / Ivy

Go to download

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!

There is a newer version: 1.48.2
Show newest version
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