Commit 68173d87 by Johannes Edmeier

Add details to the StatusInfo

The StatusInfo has a new details field. The StatusUpdater puts either the reponse from the health endpoint or the exception message in the details. This allows us to see the details over time (via the journal) and also to use `em in a bit more mail notifications. closes #329
parent c8a1ae9e
package de.codecentric.boot.admin.model; package de.codecentric.boot.admin.model;
import java.io.Serializable; import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/** /**
* Represents a certain status a certain time. * Represents a certain status a certain time.
...@@ -8,34 +11,51 @@ import java.io.Serializable; ...@@ -8,34 +11,51 @@ import java.io.Serializable;
* @author Johannes Stelzer * @author Johannes Stelzer
*/ */
public class StatusInfo implements Serializable { public class StatusInfo implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 2L;
private final String status; private final String status;
private final long timestamp; private final long timestamp;
private final Map<String, ? extends Serializable> details;
protected StatusInfo(String status, long timestamp) { protected StatusInfo(String status, long timestamp,
Map<String, ? extends Serializable> details) {
this.status = status.toUpperCase(); this.status = status.toUpperCase();
this.timestamp = timestamp; this.timestamp = timestamp;
this.details = details != null ? Collections.unmodifiableMap(new HashMap<>(details))
: Collections.<String, Serializable>emptyMap();
} }
public static StatusInfo valueOf(String statusCode) { public static StatusInfo valueOf(String statusCode,
return new StatusInfo(statusCode, System.currentTimeMillis()); Map<String, ? extends Serializable> details) {
return new StatusInfo(statusCode, System.currentTimeMillis(), details);
} }
public static StatusInfo ofUnknown() { public static StatusInfo ofUnknown() {
return valueOf("UNKNOWN"); return valueOf("UNKNOWN", null);
} }
public static StatusInfo ofUp() { public static StatusInfo ofUp() {
return valueOf("UP"); return ofUp(null);
} }
public static StatusInfo ofDown() { public static StatusInfo ofDown() {
return valueOf("DOWN"); return ofDown(null);
} }
public static StatusInfo ofOffline() { public static StatusInfo ofOffline() {
return valueOf("OFFLINE"); return ofOffline(null);
}
public static StatusInfo ofUp(Map<String, ? extends Serializable> details) {
return valueOf("UP", details);
}
public static StatusInfo ofDown(Map<String, ? extends Serializable> details) {
return valueOf("DOWN", details);
}
public static StatusInfo ofOffline(Map<String, ? extends Serializable> details) {
return valueOf("OFFLINE", details);
} }
public String getStatus() { public String getStatus() {
...@@ -46,6 +66,10 @@ public class StatusInfo implements Serializable { ...@@ -46,6 +66,10 @@ public class StatusInfo implements Serializable {
return timestamp; return timestamp;
} }
public Map<String, ? extends Serializable> getDetails() {
return details;
}
@Override @Override
public int hashCode() { public int hashCode() {
final int prime = 31; final int prime = 31;
......
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
*/ */
package de.codecentric.boot.admin.registry; package de.codecentric.boot.admin.registry;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.slf4j.Logger; import org.slf4j.Logger;
...@@ -75,28 +77,36 @@ public class StatusUpdater implements ApplicationEventPublisherAware { ...@@ -75,28 +77,36 @@ public class StatusUpdater implements ApplicationEventPublisherAware {
try { try {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
ResponseEntity<Map<String, Object>> response = restTemplate.getForEntity( ResponseEntity<Map<String, Serializable>> response = restTemplate.getForEntity(
application.getHealthUrl(), (Class<Map<String, Object>>) (Class<?>) Map.class); application.getHealthUrl(),
(Class<Map<String, Serializable>>) (Class<?>) Map.class);
LOGGER.debug("/health for {} responded with {}", application, response); LOGGER.debug("/health for {} responded with {}", application, response);
if (response.hasBody() && response.getBody().get("status") instanceof String) { if (response.hasBody() && response.getBody().get("status") instanceof String) {
return StatusInfo.valueOf((String) response.getBody().get("status")); return StatusInfo.valueOf((String) response.getBody().get("status"),
response.getBody());
} else if (response.getStatusCode().is2xxSuccessful()) { } else if (response.getStatusCode().is2xxSuccessful()) {
return StatusInfo.ofUp(); return StatusInfo.ofUp();
} else { } else {
return StatusInfo.ofDown(); return StatusInfo.ofDown();
} }
} catch (Exception ex) { } catch (Exception ex) {
if ("OFFLINE".equals(application.getStatusInfo().getStatus())) { if ("OFFLINE".equals(application.getStatusInfo().getStatus())) {
LOGGER.debug("Couldn't retrieve status for {}", application, ex); LOGGER.debug("Couldn't retrieve status for {}", application, ex);
} else { } else {
LOGGER.warn("Couldn't retrieve status for {}", application, ex); LOGGER.warn("Couldn't retrieve status for {}", application, ex);
} }
return StatusInfo.ofOffline(); return StatusInfo.ofOffline(toDetails(ex));
} }
} }
protected Map<String, Serializable> toDetails(Exception ex) {
Map<String, Serializable> details = new HashMap<>();
details.put("message", ex.getMessage());
details.put("exception", ex.getClass().getName());
return details;
}
public void setStatusLifetime(long statusLifetime) { public void setStatusLifetime(long statusLifetime) {
this.statusLifetime = statusLifetime; this.statusLifetime = statusLifetime;
} }
......
...@@ -11,8 +11,8 @@ public class StatusInfoTest { ...@@ -11,8 +11,8 @@ public class StatusInfoTest {
@Test @Test
public void test_equals_hashcode() { public void test_equals_hashcode() {
StatusInfo up = StatusInfo.ofUp(); StatusInfo up = StatusInfo.ofUp();
StatusInfo up2 = StatusInfo.valueOf("UP"); StatusInfo up2 = StatusInfo.ofUp();
StatusInfo down = StatusInfo.valueOf("DOWN"); StatusInfo down = StatusInfo.ofDown();
assertThat(up, is(up2)); assertThat(up, is(up2));
assertThat(up, not(is(down))); assertThat(up, not(is(down)));
......
...@@ -123,7 +123,7 @@ public class StatusUpdaterTest { ...@@ -123,7 +123,7 @@ public class StatusUpdaterTest {
store.save(app1); store.save(app1);
Application app2 = Application.create("foo").withId("id-2").withHealthUrl("health-2") Application app2 = Application.create("foo").withId("id-2").withHealthUrl("health-2")
.withStatusInfo(StatusInfo.valueOf("UP")).build(); .withStatusInfo(StatusInfo.ofUp()).build();
store.save(app2); store.save(app2);
when(template.getForEntity("health-2", Map.class)) when(template.getForEntity("health-2", Map.class))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment