Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
b73fb40
Add ability to post task metadata to a task
wsorenson Feb 4, 2016
e245e38
Merge branch 'master' into add_task_diagnostic_state
wsorenson Feb 5, 2016
d7506e0
Merge branch 'hedge_against_zk_tx' into add_task_diagnostic_state
wsorenson Feb 5, 2016
22ba559
add buffer to task persistence
wsorenson Feb 5, 2016
bf7bbc9
add a queue for sending task finished mails (WIP)
wsorenson Feb 5, 2016
1f18d1b
Merge branch 'master' into add_task_diagnostic_state
wsorenson Feb 9, 2016
e4ff25a
actually send mails
wsorenson Feb 9, 2016
aa5eeac
bind this
wsorenson Feb 9, 2016
330fc99
fix error
wsorenson Feb 9, 2016
8e8d94c
make find bugs happy
wsorenson Feb 9, 2016
aed6618
check rate limit before queueing mail in ZK
wsorenson Feb 9, 2016
437986f
change to use an API object
wsorenson Feb 9, 2016
6b14edd
refactor config, allow mail to send immediately if metadata type is a…
wsorenson Feb 9, 2016
25cf9ef
fix test due to default config change
wsorenson Feb 9, 2016
cd16aa9
Merge branch 'master' into add_task_diagnostic_state
wsorenson Feb 10, 2016
07018c5
Add check that task still resides in ZK.
wsorenson Feb 22, 2016
20b1939
Merge branch 'add_task_diagnostic_state' of github.com:HubSpot/Singul…
wsorenson Feb 22, 2016
088ea9a
Merge branch 'master' into add_task_diagnostic_state
wsorenson Mar 8, 2016
1b8fd56
Draft UI And Email template for Task Metadata.
Mar 10, 2016
6f4adc5
Add 'level' field to TaskMetadata with options 'INFO', 'WARN' and 'ER…
Mar 11, 2016
74d75f2
Task metadata levels implemented in the UI and emails
Mar 11, 2016
e14ac0a
Correct formatting
Calvinp Mar 11, 2016
f09f138
Fix Intentation
Calvinp Mar 11, 2016
201e719
Merge branch 'master' into add_task_diagnostic_state_ui
Mar 14, 2016
4df6f5c
Humanize timestamp is a helper function to fix compiler error caused …
Mar 14, 2016
daef747
Merge branch 'die-brunch' into linkify_text_in_p_tags
Mar 16, 2016
8838d06
Merge remote-tracking branch 'origin/die-brunch' into add_task_diagno…
ssalinas Mar 17, 2016
5365040
linkify text in p tags
ssalinas Mar 17, 2016
764d3d0
Merge branch 'master' into linkify_text_in_p_tags
ssalinas Mar 17, 2016
456ffb8
Merge branch 'add_task_diagnostic_state_ui' into linkify_text_in_p_tags
ssalinas Mar 17, 2016
df1fd6c
Merge branch 'master' into add_task_diagnostic_state_ui
ssalinas Mar 17, 2016
58561a6
Merge branch 'add_task_diagnostic_state_ui' into linkify_text_in_p_tags
ssalinas Mar 17, 2016
48332af
Linkify items with a linkify class instead of all p tags
Mar 17, 2016
72aa92c
Fix stray '-' that was preventing task email from sending when it had…
Mar 18, 2016
8dee2e7
Merge branch 'linkify_text_in_p_tags' into add_task_diagnostic_state_ui
Mar 18, 2016
d46a459
Merge branch 'master' into add_task_diagnostic_state
ssalinas Mar 23, 2016
dce3e0b
Better metadata templating in emails
Mar 23, 2016
3150c92
Render metadata message in a pre to ensure it formats well
Mar 24, 2016
15490c5
fix merge conflicts with master
ssalinas Apr 11, 2016
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.hubspot.singularity;


public enum MetadataLevel {

INFO, WARN, ERROR

}
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,26 @@ public int compareTo(SingularityTaskHealthcheckResult o) {

@Override
public int hashCode() {
return Objects.hashCode(statusCode, durationMillis, responseBody, errorMessage, timestamp);
return Objects.hashCode(getTaskId(), statusCode, durationMillis, responseBody, errorMessage, timestamp);
}

@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || other.getClass() != this.getClass()) {
return false;
}

SingularityTaskHealthcheckResult that = (SingularityTaskHealthcheckResult) other;

return Objects.equal(this.statusCode, that.statusCode)
&& Objects.equal(this.durationMillis, that.durationMillis)
&& Objects.equal(this.responseBody, that.responseBody)
&& Objects.equal(this.errorMessage, that.errorMessage)
&& Objects.equal(this.timestamp, that.timestamp);
if (this == other) {
return true;
}
if (other == null || other.getClass() != this.getClass()) {
return false;
}

SingularityTaskHealthcheckResult that = (SingularityTaskHealthcheckResult) other;

return Objects.equal(this.statusCode, that.statusCode)
&& Objects.equal(this.getTaskId(), that.getTaskId())
&& Objects.equal(this.durationMillis, that.durationMillis)
&& Objects.equal(this.responseBody, that.responseBody)
&& Objects.equal(this.errorMessage, that.errorMessage)
&& Objects.equal(this.timestamp, that.timestamp);
}

public Optional<Integer> getStatusCode() {
Expand Down Expand Up @@ -86,7 +87,8 @@ public boolean isFailed() {

@Override
public String toString() {
return "SingularityTaskHealthcheckResult [statusCode=" + statusCode + ", durationMillis=" + durationMillis + ", timestamp=" + timestamp + ", responseBody=" + responseBody + ", errorMessage=" + errorMessage + ", taskId=" + getTaskId() + "]";
return "SingularityTaskHealthcheckResult [statusCode=" + statusCode + ", durationMillis=" + durationMillis + ", timestamp=" + timestamp + ", responseBody="
+ responseBody + ", errorMessage=" + errorMessage + ", taskId=" + getTaskId() + "]";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import java.util.List;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Optional;
import com.hubspot.mesos.JavaUtils;

public class SingularityTaskHistory {

Expand All @@ -14,16 +16,21 @@ public class SingularityTaskHistory {
private final List<SingularityTaskHealthcheckResult> healthcheckResults;
private final List<SingularityLoadBalancerUpdate> loadBalancerUpdates;
private final List<SingularityTaskShellCommandHistory> shellCommandHistory;
private final List<SingularityTaskMetadata> taskMetadata;

@JsonCreator
public SingularityTaskHistory(@JsonProperty("taskUpdates") List<SingularityTaskHistoryUpdate> taskUpdates, @JsonProperty("directory") Optional<String> directory, @JsonProperty("healthcheckResults") List<SingularityTaskHealthcheckResult> healthcheckResults,
@JsonProperty("task") SingularityTask task, @JsonProperty("loadBalancerUpdates") List<SingularityLoadBalancerUpdate> loadBalancerUpdates, @JsonProperty("shellCommandHistory") List<SingularityTaskShellCommandHistory> shellCommandHistory) {
this.taskUpdates = taskUpdates;
this.healthcheckResults = healthcheckResults;
public SingularityTaskHistory(@JsonProperty("taskUpdates") List<SingularityTaskHistoryUpdate> taskUpdates, @JsonProperty("directory") Optional<String> directory,
@JsonProperty("healthcheckResults") List<SingularityTaskHealthcheckResult> healthcheckResults, @JsonProperty("task") SingularityTask task,
@JsonProperty("loadBalancerUpdates") List<SingularityLoadBalancerUpdate> loadBalancerUpdates,
@JsonProperty("shellCommandHistory") List<SingularityTaskShellCommandHistory> shellCommandHistory,
@JsonProperty("taskMetadata") List<SingularityTaskMetadata> taskMetadata) {
this.directory = directory;
this.task = task;
this.loadBalancerUpdates = loadBalancerUpdates;
this.shellCommandHistory = shellCommandHistory;
this.taskUpdates = JavaUtils.nonNullImmutable(taskUpdates);
this.healthcheckResults = JavaUtils.nonNullImmutable(healthcheckResults);
this.loadBalancerUpdates = JavaUtils.nonNullImmutable(loadBalancerUpdates);
this.shellCommandHistory = JavaUtils.nonNullImmutable(shellCommandHistory);
this.taskMetadata = JavaUtils.nonNullImmutable(taskMetadata);
}

public List<SingularityTaskHistoryUpdate> getTaskUpdates() {
Expand All @@ -38,6 +45,10 @@ public SingularityTask getTask() {
return task;
}

public List<SingularityTaskMetadata> getTaskMetadata() {
return taskMetadata;
}

public List<SingularityTaskHealthcheckResult> getHealthcheckResults() {
return healthcheckResults;
}
Expand All @@ -50,10 +61,15 @@ public List<SingularityTaskShellCommandHistory> getShellCommandHistory() {
return shellCommandHistory;
}

@JsonIgnore
public Optional<SingularityTaskHistoryUpdate> getLastTaskUpdate() {
return JavaUtils.getLast(getTaskUpdates());
}

@Override
public String toString() {
return "SingularityTaskHistory [taskUpdates=" + taskUpdates + ", directory=" + directory + ", task=" + task + ", healthcheckResults=" + healthcheckResults + ", loadBalancerUpdates="
+ loadBalancerUpdates + ", shellCommandHistory=" + shellCommandHistory + "]";
+ loadBalancerUpdates + ", shellCommandHistory=" + shellCommandHistory + ", taskMetadata=" + taskMetadata + "]";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.hubspot.singularity;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.collect.ComparisonChain;

public class SingularityTaskMetadata extends SingularityTaskIdHolder implements Comparable<SingularityTaskMetadata> {

private static final MetadataLevel DEFAULT_METADATA_LEVEL = MetadataLevel.INFO;
private final long timestamp;
private final String type;
private final String title;
private final MetadataLevel level;
private final Optional<String> message;
private final Optional<String> user;

@JsonCreator
public SingularityTaskMetadata(@JsonProperty("taskId") SingularityTaskId taskId, @JsonProperty("timestamp") long timestamp, @JsonProperty("type") String type, @JsonProperty("title") String title,
@JsonProperty("message") Optional<String> message, @JsonProperty("user") Optional<String> user, @JsonProperty("level") Optional<MetadataLevel> level) {
super(taskId);
Preconditions.checkNotNull(type);
Preconditions.checkState(!type.contains("/"));
this.timestamp = timestamp;
this.type = type;
this.title = title;
this.message = message;
this.user = user;
this.level = level.or(DEFAULT_METADATA_LEVEL);
}

public long getTimestamp() {
return timestamp;
}

public String getType() {
return type;
}

public String getTitle() {
return title;
}

public Optional<String> getMessage() {
return message;
}

public Optional<String> getUser() {
return user;
}

public MetadataLevel getLevel() { return level; }

@Override
public int compareTo(SingularityTaskMetadata o) {
return ComparisonChain.start()
.compare(timestamp, o.getTimestamp())
.compare(type, o.getType())
.compare(level, o.getLevel())
.compare(getTaskId().getId(), o.getTaskId().getId())
.result();
}

@Override
public int hashCode() {
return Objects.hashCode(user, type, title, message, timestamp, getTaskId());
}

@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other == null || other.getClass() != this.getClass()) {
return false;
}

SingularityTaskMetadata that = (SingularityTaskMetadata) other;

return Objects.equal(this.user, that.user)
&& Objects.equal(this.type, that.type)
&& Objects.equal(this.title, that.title)
&& Objects.equal(this.message, that.message)
&& Objects.equal(this.timestamp, that.timestamp)
&& Objects.equal(this.getTaskId(), that.getTaskId())
&& Objects.equal(this.level, that.level);
}

@Override
public String toString() {
return "SingularityTaskMetadata [timestamp=" + timestamp + ", type=" + type + ", title=" + title + ", message=" + message + ", user=" + user + ", taskId=" + getTaskId() + ", level=" + getLevel() + "]";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.hubspot.mesos.JavaUtils;

public class SingularityTaskShellCommandHistory {

Expand All @@ -14,7 +15,7 @@ public class SingularityTaskShellCommandHistory {
public SingularityTaskShellCommandHistory(@JsonProperty("shellRequest") SingularityTaskShellCommandRequest shellRequest,
@JsonProperty("shellUpdates") List<SingularityTaskShellCommandUpdate> shellUpdates) {
this.shellRequest = shellRequest;
this.shellUpdates = shellUpdates;
this.shellUpdates = JavaUtils.nonNullImmutable(shellUpdates);
}

public SingularityTaskShellCommandRequest getShellRequest() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.hubspot.singularity.api;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.hubspot.singularity.MetadataLevel;

public class SingularityTaskMetadataRequest {

private final String type;
private final String title;
private final Optional<String> message;
private final Optional<MetadataLevel> level;

@JsonCreator
public SingularityTaskMetadataRequest(@JsonProperty("type") String type, @JsonProperty("title") String title, @JsonProperty("message") Optional<String> message, @JsonProperty("level") Optional<MetadataLevel> level) {
Preconditions.checkNotNull(type);
Preconditions.checkState(!type.contains("/"));
this.type = type;
this.title = title;
this.message = message;
this.level = level;
}

public String getType() {
return type;
}

public String getTitle() {
return title;
}

public Optional<String> getMessage() {
return message;
}

public Optional<MetadataLevel> getLevel() { return level; }

@Override
public String toString() {
return "SingularityTaskMetadataRequest [type=" + type + ", title=" + title + ", message=" + message + ", level=" + level + "]";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import com.hubspot.singularity.config.SMTPConfiguration;
import com.hubspot.singularity.config.SentryConfiguration;
import com.hubspot.singularity.config.SingularityConfiguration;
import com.hubspot.singularity.config.SingularityTaskMetadataConfiguration;
import com.hubspot.singularity.config.UIConfiguration;
import com.hubspot.singularity.config.ZooKeeperConfiguration;
import com.hubspot.singularity.guice.DropwizardMetricRegistryProvider;
Expand Down Expand Up @@ -213,6 +214,12 @@ public Optional<SentryConfiguration> sentryConfiguration(final SingularityConfig
return config.getSentryConfiguration();
}

@Provides
@Singleton
public SingularityTaskMetadataConfiguration taskMetadataConfiguration(SingularityConfiguration config) {
return config.getTaskMetadataConfiguration();
}

@Provides
@Singleton
public Optional<S3Service> s3Service(Optional<S3Configuration> config) throws S3ServiceException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public class SingularityConfiguration extends Configuration {

private long cleanupEverySeconds = 5;

private long checkQueuedMailsEveryMillis = TimeUnit.SECONDS.toMillis(15);

private long closeWaitSeconds = 5;

private String commonHostnameSuffixToOmit;
Expand Down Expand Up @@ -186,6 +188,10 @@ public class SingularityConfiguration extends Configuration {
@Valid
private SentryConfiguration sentryConfiguration;

@JsonProperty("taskMetadata")
@Valid
private SingularityTaskMetadataConfiguration taskMetadataConfiguration = new SingularityTaskMetadataConfiguration();

@JsonProperty("smtp")
@Valid
private SMTPConfiguration smtpConfiguration;
Expand Down Expand Up @@ -228,7 +234,7 @@ public class SingularityConfiguration extends Configuration {

@JsonProperty("ldap")
@Valid
private LDAPConfiguration ldapConfiguration = null;
private LDAPConfiguration ldapConfiguration;

@JsonProperty("auth")
@NotNull
Expand Down Expand Up @@ -561,6 +567,14 @@ public UIConfiguration getUiConfiguration() {
return uiConfiguration;
}

public long getCheckQueuedMailsEveryMillis() {
return checkQueuedMailsEveryMillis;
}

public void setCheckQueuedMailsEveryMillis(long checkQueuedMailsEveryMillis) {
this.checkQueuedMailsEveryMillis = checkQueuedMailsEveryMillis;
}

public long getWarnIfScheduledJobIsRunningForAtLeastMillis() {
return warnIfScheduledJobIsRunningForAtLeastMillis;
}
Expand Down Expand Up @@ -949,6 +963,14 @@ public void setReserveSlavesWithAttributes(Map<String, List<String>> reserveSlav
this.reserveSlavesWithAttributes = reserveSlavesWithAttributes;
}

public SingularityTaskMetadataConfiguration getTaskMetadataConfiguration() {
return taskMetadataConfiguration;
}

public void setTaskMetadataConfiguration(SingularityTaskMetadataConfiguration taskMetadataConfiguration) {
this.taskMetadataConfiguration = taskMetadataConfiguration;
}

public GraphiteConfiguration getGraphiteConfiguration() {
return graphiteConfiguration;
}
Expand Down
Loading