package com.netflix.eureka.util; import java.lang.management.ManagementFactory; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Map; import com.netflix.appinfo.ApplicationInfoManager; import com.netflix.appinfo.InstanceInfo; import com.netflix.config.ConfigurationManager; import com.netflix.discovery.provider.Serializer; import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamOmitField; /** * An utility class for exposing status information of an instance. * * @author Greg Kim */ @Serializer("com.netflix.discovery.converters.EntityBodyConverter") @XStreamAlias("status") public class StatusInfo { private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss Z"; public static final class Builder { @XStreamOmitField private StatusInfo result; private Builder() { result = new StatusInfo(); } public static Builder newBuilder() { return new Builder(); } public Builder isHealthy(boolean b) { result.isHeathly = Boolean.valueOf(b); return this; } public Builder withInstanceInfo(InstanceInfo instanceInfo) { result.instanceInfo = instanceInfo; return this; } /** * Add any application specific status data. */ public Builder add(String key, String value) { if (result.applicationStats == null) { result.applicationStats = new HashMap<String, String>(); } result.applicationStats.put(key, value); return this; } /** * Build the {@link StatusInfo}. General information are automatically * built here too. */ public StatusInfo build() { if (result.instanceInfo == null) { throw new IllegalStateException("instanceInfo can not be null"); } result.generalStats.put("server-uptime", getUpTime()); result.generalStats.put("environment", ConfigurationManager .getDeploymentContext().getDeploymentEnvironment()); Runtime runtime = Runtime.getRuntime(); int totalMem = (int) (runtime.totalMemory() / 1048576); int freeMem = (int) (runtime.freeMemory() / 1048576); int usedPercent = (int) (((float) totalMem - freeMem) / (totalMem) * 100.0); result.generalStats.put("num-of-cpus", String.valueOf(runtime.availableProcessors())); result.generalStats.put("total-avail-memory", String.valueOf(totalMem) + "mb"); result.generalStats.put("current-memory-usage", String.valueOf(totalMem - freeMem) + "mb" + " (" + usedPercent + "%)"); return result; } } private Map<String, String> generalStats = new HashMap<String, String>(); private Map<String, String> applicationStats; private InstanceInfo instanceInfo; private Boolean isHeathly; private StatusInfo() { } public InstanceInfo getInstanceInfo() { return instanceInfo; } public boolean isHealthy() { return isHeathly.booleanValue(); } public Map<String, String> getGeneralStats() { return generalStats; } public Map<String, String> getApplicationStats() { return applicationStats; } /** * Output the amount of time that has elapsed since the given date in the * format x days, xx:xx. * * @return A string representing the formatted interval. */ public static String getUpTime() { long diff = ManagementFactory.getRuntimeMXBean().getUptime(); diff /= 1000 * 60; long minutes = diff % 60; diff /= 60; long hours = diff % 24; diff /= 24; long days = diff; StringBuilder buf = new StringBuilder(); if (days == 1) { buf.append("1 day "); } else if (days > 1) { buf.append(Long.valueOf(days).toString()).append(" days "); } DecimalFormat format = new DecimalFormat(); format.setMinimumIntegerDigits(2); buf.append(format.format(hours)).append(":") .append(format.format(minutes)); return buf.toString(); } public static String getCurrentTimeAsString() { SimpleDateFormat format = new SimpleDateFormat(DATE_FORMAT); return format.format(new Date()); } }