From f14c1818405114f8bcfc919b7dc55bfdac5b63fe Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Sat, 12 Apr 2014 14:14:18 -0700 Subject: [PATCH] Add host system metrics. --- .../textsecuregcm/WhisperServerService.java | 12 ++++-- .../textsecuregcm/metrics/CpuUsageGauge.java | 16 ++++++++ .../metrics/FreeMemoryGauge.java | 20 ++++++++++ .../textsecuregcm/metrics/NetworkGauge.java | 37 +++++++++++++++++++ .../metrics/NetworkReceivedGauge.java | 36 ++++++++++++++++++ .../metrics/NetworkSentGauge.java | 35 ++++++++++++++++++ 6 files changed, 153 insertions(+), 3 deletions(-) create mode 100644 src/main/java/org/whispersystems/textsecuregcm/metrics/CpuUsageGauge.java create mode 100644 src/main/java/org/whispersystems/textsecuregcm/metrics/FreeMemoryGauge.java create mode 100644 src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkGauge.java create mode 100644 src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkReceivedGauge.java create mode 100644 src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkSentGauge.java diff --git a/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index a481a73b7..03485fcff 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -25,9 +25,6 @@ import com.yammer.dropwizard.db.DatabaseConfiguration; import com.yammer.dropwizard.jdbi.DBIFactory; import com.yammer.dropwizard.migrations.MigrationsBundle; import com.yammer.metrics.Metrics; -import com.yammer.metrics.core.Clock; -import com.yammer.metrics.core.MetricPredicate; -import com.yammer.metrics.reporting.DatadogReporter; import com.yammer.metrics.reporting.GraphiteReporter; import net.spy.memcached.MemcachedClient; import org.bouncycastle.jce.provider.BouncyCastleProvider; @@ -49,7 +46,11 @@ import org.whispersystems.textsecuregcm.federation.FederatedPeer; import org.whispersystems.textsecuregcm.limits.RateLimiters; import org.whispersystems.textsecuregcm.mappers.IOExceptionMapper; import org.whispersystems.textsecuregcm.mappers.RateLimitExceededExceptionMapper; +import org.whispersystems.textsecuregcm.metrics.CpuUsageGauge; +import org.whispersystems.textsecuregcm.metrics.FreeMemoryGauge; import org.whispersystems.textsecuregcm.metrics.JsonMetricsReporter; +import org.whispersystems.textsecuregcm.metrics.NetworkReceivedGauge; +import org.whispersystems.textsecuregcm.metrics.NetworkSentGauge; import org.whispersystems.textsecuregcm.providers.MemcacheHealthCheck; import org.whispersystems.textsecuregcm.providers.MemcachedClientFactory; import org.whispersystems.textsecuregcm.providers.RedisClientFactory; @@ -164,6 +165,11 @@ public class WhisperServerService extends Service { environment.addProvider(new IOExceptionMapper()); environment.addProvider(new RateLimitExceededExceptionMapper()); + Metrics.newGauge(CpuUsageGauge.class, "cpu", new CpuUsageGauge()); + Metrics.newGauge(FreeMemoryGauge.class, "free_memory", new FreeMemoryGauge()); + Metrics.newGauge(NetworkSentGauge.class, "bytes_sent", new NetworkSentGauge()); + Metrics.newGauge(NetworkReceivedGauge.class, "bytes_received", new NetworkReceivedGauge()); + if (config.getGraphiteConfiguration().isEnabled()) { GraphiteReporter.enable(15, TimeUnit.SECONDS, config.getGraphiteConfiguration().getHost(), diff --git a/src/main/java/org/whispersystems/textsecuregcm/metrics/CpuUsageGauge.java b/src/main/java/org/whispersystems/textsecuregcm/metrics/CpuUsageGauge.java new file mode 100644 index 000000000..f5ca9a7a0 --- /dev/null +++ b/src/main/java/org/whispersystems/textsecuregcm/metrics/CpuUsageGauge.java @@ -0,0 +1,16 @@ +package org.whispersystems.textsecuregcm.metrics; + +import com.sun.management.OperatingSystemMXBean; +import com.yammer.metrics.core.Gauge; + +import java.lang.management.ManagementFactory; + +public class CpuUsageGauge extends Gauge { + @Override + public Integer value() { + OperatingSystemMXBean mbean = (com.sun.management.OperatingSystemMXBean) + ManagementFactory.getOperatingSystemMXBean(); + + return (int) Math.ceil(mbean.getSystemCpuLoad() * 100); + } +} diff --git a/src/main/java/org/whispersystems/textsecuregcm/metrics/FreeMemoryGauge.java b/src/main/java/org/whispersystems/textsecuregcm/metrics/FreeMemoryGauge.java new file mode 100644 index 000000000..c2b959ff5 --- /dev/null +++ b/src/main/java/org/whispersystems/textsecuregcm/metrics/FreeMemoryGauge.java @@ -0,0 +1,20 @@ +package org.whispersystems.textsecuregcm.metrics; + +import com.sun.management.OperatingSystemMXBean; +import com.yammer.metrics.core.Gauge; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.lang.management.ManagementFactory; + +public class FreeMemoryGauge extends Gauge { + + @Override + public Long value() { + OperatingSystemMXBean mbean = (com.sun.management.OperatingSystemMXBean) + ManagementFactory.getOperatingSystemMXBean(); + + return mbean.getFreePhysicalMemorySize(); + } +} \ No newline at end of file diff --git a/src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkGauge.java b/src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkGauge.java new file mode 100644 index 000000000..08e03816f --- /dev/null +++ b/src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkGauge.java @@ -0,0 +1,37 @@ +package org.whispersystems.textsecuregcm.metrics; + + +import com.yammer.metrics.core.Gauge; +import org.whispersystems.textsecuregcm.util.Pair; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; + +public abstract class NetworkGauge extends Gauge { + + protected Pair getSentReceived() throws IOException { + File proc = new File("/proc/net/dev"); + BufferedReader reader = new BufferedReader(new FileReader(proc)); + String header = reader.readLine(); + String header2 = reader.readLine(); + + long bytesSent = 0; + long bytesReceived = 0; + + String interfaceStats; + + while ((interfaceStats = reader.readLine()) != null) { + String[] stats = interfaceStats.split("\\s+"); + + if (!stats[1].equals("lo:")) { + bytesReceived += Long.parseLong(stats[2]); + bytesSent += Long.parseLong(stats[10]); + } + } + + return new Pair<>(bytesSent, bytesReceived); + } +} diff --git a/src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkReceivedGauge.java b/src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkReceivedGauge.java new file mode 100644 index 000000000..5d6437a19 --- /dev/null +++ b/src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkReceivedGauge.java @@ -0,0 +1,36 @@ +package org.whispersystems.textsecuregcm.metrics; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.whispersystems.textsecuregcm.util.Pair; + +import java.io.IOException; + +public class NetworkReceivedGauge extends NetworkGauge { + + private final Logger logger = LoggerFactory.getLogger(NetworkSentGauge.class); + + private long lastTimestamp; + private long lastReceived; + + @Override + public Long value() { + try { + long timestamp = System.currentTimeMillis(); + Pair sentAndReceived = getSentReceived(); + long result = 0; + + if (lastTimestamp != 0) { + result = sentAndReceived.second() - lastReceived; + lastReceived = sentAndReceived.second(); + } + + lastTimestamp = timestamp; + return result; + } catch (IOException e) { + logger.warn("NetworkReceivedGauge", e); + return -1L; + } + } + +} diff --git a/src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkSentGauge.java b/src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkSentGauge.java new file mode 100644 index 000000000..e8b1b4ef1 --- /dev/null +++ b/src/main/java/org/whispersystems/textsecuregcm/metrics/NetworkSentGauge.java @@ -0,0 +1,35 @@ +package org.whispersystems.textsecuregcm.metrics; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.whispersystems.textsecuregcm.util.Pair; + +import java.io.IOException; + +public class NetworkSentGauge extends NetworkGauge { + + private final Logger logger = LoggerFactory.getLogger(NetworkSentGauge.class); + + private long lastTimestamp; + private long lastSent; + + @Override + public Long value() { + try { + long timestamp = System.currentTimeMillis(); + Pair sentAndReceived = getSentReceived(); + long result = 0; + + if (lastTimestamp != 0) { + result = sentAndReceived.first() - lastSent; + lastSent = sentAndReceived.first(); + } + + lastTimestamp = timestamp; + return result; + } catch (IOException e) { + logger.warn("NetworkSentGauge", e); + return -1L; + } + } +}