com.hubspot.singularity.smtp.MailTemplateHelpers Maven / Gradle / Ivy
package com.hubspot.singularity.smtp;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang3.text.WordUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import com.hubspot.mesos.MesosUtils;
import com.hubspot.mesos.json.MesosFileChunkObject;
import com.hubspot.singularity.ExtendedTaskState;
import com.hubspot.singularity.SingularityEmailType;
import com.hubspot.singularity.SingularityTask;
import com.hubspot.singularity.SingularityTaskHistoryUpdate;
import com.hubspot.singularity.SingularityTaskId;
import com.hubspot.singularity.config.SMTPConfiguration;
import com.hubspot.singularity.config.SingularityConfiguration;
import com.hubspot.singularity.data.SandboxManager;
@Singleton
public class MailTemplateHelpers {
private static final Logger LOG = LoggerFactory.getLogger(MailTemplateHelpers.class);
private static final String TASK_DATE_PATTERN = "MMM dd HH:mm:ss";
private static final String TASK_LINK_FORMAT = "%s/task/%s";
private static final String REQUEST_LINK_FORMAT = "%s/request/%s";
private static final String LOG_LINK_FORMAT = "%s/task/%s/tail/%s";
private final SandboxManager sandboxManager;
private final Optional uiBaseUrl;
private final Optional smtpConfiguration;
@Inject
public MailTemplateHelpers(SandboxManager sandboxManager, SingularityConfiguration singularityConfiguration) {
this.uiBaseUrl = singularityConfiguration.getUiConfiguration().getBaseUrl();
this.sandboxManager = sandboxManager;
this.smtpConfiguration = singularityConfiguration.getSmtpConfiguration();
}
public List getJadeTaskHistory(Collection taskHistory) {
List output = Lists.newArrayListWithCapacity(taskHistory.size());
for (SingularityTaskHistoryUpdate taskUpdate : taskHistory) {
output.add(
new SingularityMailTaskHistoryUpdate(
DateFormatUtils.formatUTC(taskUpdate.getTimestamp(), TASK_DATE_PATTERN),
WordUtils.capitalize(taskUpdate.getTaskState().getDisplayName()),
taskUpdate.getStatusMessage().or("")));
}
return output;
}
public List getTaskLogs(SingularityTaskId taskId, Optional task, Optional directory) {
if (!smtpConfiguration.isPresent()) {
LOG.warn("Tried to getTaskLogs for sending email without SMTP configuration set.");
return Collections.emptyList();
}
List taskEmailTailFiles = smtpConfiguration.get().getTaskEmailTailFiles();
List logTails = Lists.newArrayListWithCapacity(taskEmailTailFiles.size());
for (String filePath : taskEmailTailFiles) {
// To enable support for tailing the service.log file, replace instances of $MESOS_TASK_ID.
filePath = filePath.replaceAll("\\$MESOS_TASK_ID", MesosUtils.getSafeTaskIdForDirectory(taskId.getId()));
logTails.add(
new SingularityMailTaskLog(
filePath,
getFileName(filePath),
getSingularityLogLink(filePath, taskId.getId()),
getTaskLogFile(taskId, filePath, task, directory).or("")));
}
return logTails;
}
private Optional getTaskLogFile(final SingularityTaskId taskId, final String filename, final Optional task, final Optional directory) {
if (!smtpConfiguration.isPresent()) {
LOG.warn("Tried to get a task log file without SMTP configuration set up.");
return Optional.absent();
}
if (!task.isPresent() || !directory.isPresent()) {
LOG.warn("Couldn't retrieve {} for {} because task ({}) or directory ({}) wasn't present", filename, taskId, task.isPresent(), directory.isPresent());
return Optional.absent();
}
final String slaveHostname = task.get().getOffer().getHostname();
final String fullPath = String.format("%s/%s", directory.get(), filename);
final Long logLength = (long) smtpConfiguration.get().getTaskLogLength();
final Optional logChunkObject;
try {
logChunkObject = sandboxManager.read(slaveHostname, fullPath, Optional.of(0L), Optional.of(logLength));
} catch (RuntimeException e) {
LOG.error("Sandboxmanager failed to read {}/{} on slave {}", directory.get(), filename, slaveHostname, e);
return Optional.absent();
}
if (logChunkObject.isPresent()) {
return Optional.of(logChunkObject.get().getData());
} else {
LOG.error("Failed to get {} log for {}", filename, taskId.getId());
return Optional.absent();
}
}
public String getFileName(String path) {
String[] splitPath = path.split("/");
return splitPath[splitPath.length - 1];
}
public String getSingularityTaskLink(String taskId) {
if (!uiBaseUrl.isPresent()) {
return "";
}
return String.format(TASK_LINK_FORMAT, uiBaseUrl.get(), taskId);
}
public String getSingularityRequestLink(String requestId) {
if (!uiBaseUrl.isPresent()) {
return "";
}
return String.format(REQUEST_LINK_FORMAT, uiBaseUrl.get(), requestId);
}
public String getSingularityLogLink(String logPath, String taskId) {
if (!uiBaseUrl.isPresent()) {
return "";
}
return String.format(LOG_LINK_FORMAT, uiBaseUrl.get(), taskId, logPath);
}
public String getSubjectForTaskHistory(SingularityTaskId taskId, ExtendedTaskState state, SingularityEmailType type, Collection history) {
if (type == SingularityEmailType.TASK_SCHEDULED_OVERDUE_TO_FINISH) {
return String.format("Task is overdue to finish (%s)", taskId.toString());
}
if (!didTaskRun(history)) {
return String.format("Task never started and was %s (%s)", state.getDisplayName(), taskId.toString());
}
return String.format("Task %s (%s)", state.getDisplayName(), taskId.toString());
}
public boolean didTaskRun(Collection history) {
SingularityTaskHistoryUpdate.SimplifiedTaskState simplifiedTaskState = SingularityTaskHistoryUpdate.getCurrentState(history);
return simplifiedTaskState == SingularityTaskHistoryUpdate.SimplifiedTaskState.DONE || simplifiedTaskState == SingularityTaskHistoryUpdate.SimplifiedTaskState.RUNNING;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy