aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego <diegolparra@gmail.com>2014-07-25 20:40:12 -0300
committerDiego <diegolparra@gmail.com>2014-07-25 20:40:12 -0300
commit9b9484380d508e24afdbcae0bbdf0b76215aedee (patch)
tree54e00d7b593b5e63f016a6e305dba11ed9d36ea1
parentef5e1c0de024c4d768b202754045dcfc4843b0d8 (diff)
downloadKamon-9b9484380d508e24afdbcae0bbdf0b76215aedee.tar.gz
Kamon-9b9484380d508e24afdbcae0bbdf0b76215aedee.tar.bz2
Kamon-9b9484380d508e24afdbcae0bbdf0b76215aedee.zip
= kamon-system-metrics: collector actor refactor
-rw-r--r--kamon-system-metrics/src/main/java/kamon/system/SigarHolder.java1
-rw-r--r--kamon-system-metrics/src/main/java/kamon/system/SynchronizedSigar.java429
-rw-r--r--kamon-system-metrics/src/main/resources/reference.conf28
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/metrics/HeapMetrics.scala7
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/metrics/MemoryMetrics.scala12
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/SystemMetrics.scala94
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsCollector.scala113
-rw-r--r--kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarLoader.scala7
8 files changed, 145 insertions, 546 deletions
diff --git a/kamon-system-metrics/src/main/java/kamon/system/SigarHolder.java b/kamon-system-metrics/src/main/java/kamon/system/SigarHolder.java
index d00750df..7c8cd695 100644
--- a/kamon-system-metrics/src/main/java/kamon/system/SigarHolder.java
+++ b/kamon-system-metrics/src/main/java/kamon/system/SigarHolder.java
@@ -13,7 +13,6 @@
* and limitations under the License.
* =========================================================================================
*/
-
package kamon.system;
import kamon.system.sigar.SigarLoader;
diff --git a/kamon-system-metrics/src/main/java/kamon/system/SynchronizedSigar.java b/kamon-system-metrics/src/main/java/kamon/system/SynchronizedSigar.java
deleted file mode 100644
index 20453d43..00000000
--- a/kamon-system-metrics/src/main/java/kamon/system/SynchronizedSigar.java
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
- * =========================================================================================
- * Copyright © 2013-2014 the kamon project <http://kamon.io/>
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the
- * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
- * either express or implied. See the License for the specific language governing permissions
- * and limitations under the License.
- * =========================================================================================
- */
-
-package kamon.system;
-
-import org.hyperic.sigar.*;
-
-import java.util.List;
-import java.util.Map;
-
-/**
- * Safely share a single Sigar instance between multiple threads.
- * The Sigar object is thread-safe given that each thread has its
- * own Sigar instance. In order to share a single Sigar instance
- * the methods implemented here are synchronized. All data returned
- * by the Sigar methods is read-only and hence thread-safe.
- */
-public class SynchronizedSigar implements SigarProxy {
-
- private Sigar sigar;
-
- public SynchronizedSigar() {
- this.sigar = new Sigar();
- }
-
- public synchronized long getPid()
- {
- return this.sigar.getPid();
- }
-
- public synchronized long getServicePid(String name) throws SigarException {
- return this.sigar.getServicePid(name);
- }
-
- public synchronized Mem getMem()
- throws SigarException
- {
- return this.sigar.getMem();
- }
-
- public synchronized Swap getSwap()
- throws SigarException
- {
- return this.sigar.getSwap();
- }
-
- public synchronized Cpu getCpu()
- throws SigarException
- {
- return this.sigar.getCpu();
- }
-
- public synchronized CpuPerc getCpuPerc()
- throws SigarException
- {
- return this.sigar.getCpuPerc();
- }
-
- public synchronized Uptime getUptime()
- throws SigarException
- {
- return this.sigar.getUptime();
- }
-
-
- public ResourceLimit getResourceLimit() throws SigarException {
- return null;
- }
-
- public synchronized double[] getLoadAverage()
- throws SigarException
- {
- return this.sigar.getLoadAverage();
- }
-
- public synchronized long[] getProcList()
- throws SigarException
- {
- return this.sigar.getProcList();
- }
-
- public synchronized ProcStat getProcStat()
- throws SigarException
- {
- return this.sigar.getProcStat();
- }
-
- public synchronized ProcMem getProcMem(long pid)
- throws SigarException
- {
- return this.sigar.getProcMem(pid);
- }
-
- public synchronized ProcMem getProcMem(String pid)
- throws SigarException
- {
- return this.sigar.getProcMem(pid);
- }
-
-
- public ProcMem getMultiProcMem(String s) throws SigarException {
- return null;
- }
-
- public synchronized ProcState getProcState(long pid)
- throws SigarException
- {
- return this.sigar.getProcState(pid);
- }
-
- public synchronized ProcState getProcState(String pid)
- throws SigarException
- {
- return this.sigar.getProcState(pid);
- }
-
- public synchronized ProcTime getProcTime(long pid)
- throws SigarException
- {
- return this.sigar.getProcTime(pid);
- }
-
- public synchronized ProcTime getProcTime(String pid)
- throws SigarException
- {
- return this.sigar.getProcTime(pid);
- }
-
- public synchronized ProcCpu getProcCpu(long pid)
- throws SigarException
- {
- return this.sigar.getProcCpu(pid);
- }
-
- public synchronized ProcCpu getProcCpu(String pid)
- throws SigarException
- {
- return this.sigar.getProcCpu(pid);
- }
-
-
- public MultiProcCpu getMultiProcCpu(String s) throws SigarException {
- return null;
- }
-
- public synchronized ProcCred getProcCred(long pid)
- throws SigarException
- {
- return this.sigar.getProcCred(pid);
- }
-
- public synchronized ProcCred getProcCred(String pid)
- throws SigarException
- {
- return this.sigar.getProcCred(pid);
- }
-
- public synchronized ProcCredName getProcCredName(long pid)
- throws SigarException
- {
- return this.sigar.getProcCredName(pid);
- }
-
- public synchronized ProcCredName getProcCredName(String pid)
- throws SigarException
- {
- return this.sigar.getProcCredName(pid);
- }
-
- public synchronized ProcFd getProcFd(long pid)
- throws SigarException
- {
- return this.sigar.getProcFd(pid);
- }
-
- public synchronized ProcFd getProcFd(String pid)
- throws SigarException
- {
- return this.sigar.getProcFd(pid);
- }
-
- public synchronized ProcExe getProcExe(long pid)
- throws SigarException
- {
- return this.sigar.getProcExe(pid);
- }
-
- public synchronized ProcExe getProcExe(String pid)
- throws SigarException
- {
- return this.sigar.getProcExe(pid);
- }
-
- public synchronized String[] getProcArgs(long pid)
- throws SigarException
- {
- return this.sigar.getProcArgs(pid);
- }
-
- public synchronized String[] getProcArgs(String pid)
- throws SigarException
- {
- return this.sigar.getProcArgs(pid);
- }
-
- public synchronized Map getProcEnv(long pid)
- throws SigarException
- {
- return this.sigar.getProcEnv(pid);
- }
-
- public synchronized Map getProcEnv(String pid)
- throws SigarException
- {
- return this.sigar.getProcEnv(pid);
- }
-
- public synchronized String getProcEnv(long pid, String key)
- throws SigarException
- {
- return this.sigar.getProcEnv(pid, key);
- }
-
- public synchronized String getProcEnv(String pid, String key)
- throws SigarException
- {
- return this.sigar.getProcEnv(pid, key);
- }
-
- public synchronized List getProcModules(long pid)
- throws SigarException
- {
- return this.sigar.getProcModules(pid);
- }
-
- public synchronized List getProcModules(String pid)
- throws SigarException
- {
- return this.sigar.getProcModules(pid);
- }
-
-
- public long getProcPort(int i, long l) throws SigarException {
- return 0;
- }
-
-
- public long getProcPort(String s, String s2) throws SigarException {
- return 0;
- }
-
- public synchronized FileSystem[] getFileSystemList()
- throws SigarException
- {
- return this.sigar.getFileSystemList();
- }
-
- public synchronized FileSystemMap getFileSystemMap()
- throws SigarException
- {
- return this.sigar.getFileSystemMap();
- }
-
- public synchronized FileSystemUsage getMountedFileSystemUsage(String name)
- throws SigarException
- {
- return this.sigar.getMountedFileSystemUsage(name);
- }
-
- public synchronized FileSystemUsage getFileSystemUsage(String name)
- throws SigarException
- {
- return this.sigar.getFileSystemUsage(name);
- }
-
-
- public DiskUsage getDiskUsage(String s) throws SigarException {
- return null;
- }
-
- public synchronized FileInfo getFileInfo(String name)
- throws SigarException
- {
- return this.sigar.getFileInfo(name);
- }
-
- public synchronized FileInfo getLinkInfo(String name)
- throws SigarException
- {
- return this.sigar.getLinkInfo(name);
- }
-
- public synchronized DirStat getDirStat(String name)
- throws SigarException
- {
- return this.sigar.getDirStat(name);
- }
-
-
- public DirUsage getDirUsage(String s) throws SigarException {
- return null;
- }
-
- public synchronized CpuInfo[] getCpuInfoList()
- throws SigarException
- {
- return this.sigar.getCpuInfoList();
- }
-
- public synchronized Cpu[] getCpuList()
- throws SigarException
- {
- return this.sigar.getCpuList();
- }
-
- public synchronized CpuPerc[] getCpuPercList()
- throws SigarException
- {
- return this.sigar.getCpuPercList();
- }
-
- public synchronized NetRoute[] getNetRouteList()
- throws SigarException
- {
- return this.sigar.getNetRouteList();
- }
-
- public synchronized NetInterfaceConfig getNetInterfaceConfig(String name)
- throws SigarException
- {
- return this.sigar.getNetInterfaceConfig(name);
- }
-
-
- public synchronized NetInterfaceConfig getNetInterfaceConfig() throws SigarException {
- return null;
- }
-
- public synchronized NetInterfaceStat getNetInterfaceStat(String name)
- throws SigarException
- {
- return this.sigar.getNetInterfaceStat(name);
- }
-
- public synchronized String[] getNetInterfaceList()
- throws SigarException
- {
- return this.sigar.getNetInterfaceList();
- }
-
-
- public synchronized NetConnection[] getNetConnectionList(int i) throws SigarException {
- return this.sigar.getNetConnectionList(i);
- }
-
-
- public synchronized String getNetListenAddress(long l) throws SigarException {
- return this.sigar.getNetListenAddress(l);
- }
-
-
- public synchronized String getNetListenAddress(String s) throws SigarException {
- return this.sigar.getNetListenAddress(s);
- }
-
-
- public synchronized NetStat getNetStat() throws SigarException {
- return this.sigar.getNetStat();
- }
-
-
- public synchronized String getNetServicesName(int i, long l) {
- return this.sigar.getNetServicesName(i,l);
- }
-
-
- public synchronized Who[] getWhoList() throws SigarException {
- return this.sigar.getWhoList();
- }
-
-
- public synchronized Tcp getTcp() throws SigarException {
- return this.sigar.getTcp();
- }
-
-
- public synchronized NfsClientV2 getNfsClientV2() throws SigarException {
- return this.sigar.getNfsClientV2();
- }
-
-
- public synchronized NfsServerV2 getNfsServerV2() throws SigarException {
- return this.sigar.getNfsServerV2();
- }
-
-
- public synchronized NfsClientV3 getNfsClientV3() throws SigarException {
- return this.sigar.getNfsClientV3();
- }
-
-
- public synchronized NfsServerV3 getNfsServerV3() throws SigarException {
- return this.sigar.getNfsServerV3();
- }
-
-
- public synchronized NetInfo getNetInfo() throws SigarException {
- return this.sigar.getNetInfo();
- }
-
- public synchronized String getFQDN()
- throws SigarException
- {
- return this.sigar.getFQDN();
- }
-} \ No newline at end of file
diff --git a/kamon-system-metrics/src/main/resources/reference.conf b/kamon-system-metrics/src/main/resources/reference.conf
index d6eb0576..0600388d 100644
--- a/kamon-system-metrics/src/main/resources/reference.conf
+++ b/kamon-system-metrics/src/main/resources/reference.conf
@@ -22,40 +22,40 @@ kamon {
cpu {
user = {
refresh-interval = 100 milliseconds
- highest-trackable-value = 999999999
+ highest-trackable-value = 999
significant-value-digits = 2
}
system = {
refresh-interval = 100 milliseconds
- highest-trackable-value = 999999999
+ highest-trackable-value = 999
significant-value-digits = 2
}
wait = {
refresh-interval = 100 milliseconds
- highest-trackable-value = 999999999
+ highest-trackable-value = 999
significant-value-digits = 2
}
idle ={
refresh-interval = 100 milliseconds
- highest-trackable-value = 999999999
+ highest-trackable-value = 999
significant-value-digits = 2
}
}
network {
- rx-bytes = ${kamon.metrics.precision.default-gauge-precision}
- tx-bytes = ${kamon.metrics.precision.default-gauge-precision}
- rx-errors = ${kamon.metrics.precision.default-gauge-precision}
- tx-errors = ${kamon.metrics.precision.default-gauge-precision}
+ rx-bytes = ${kamon.metrics.precision.default-histogram-precision}
+ tx-bytes = ${kamon.metrics.precision.default-histogram-precision}
+ rx-errors = ${kamon.metrics.precision.default-histogram-precision}
+ tx-errors = ${kamon.metrics.precision.default-histogram-precision}
}
memory {
- used = ${kamon.metrics.precision.default-gauge-precision}
- free = ${kamon.metrics.precision.default-gauge-precision}
- buffer = ${kamon.metrics.precision.default-gauge-precision}
- cache = ${kamon.metrics.precision.default-gauge-precision}
- swap-used = ${kamon.metrics.precision.default-gauge-precision}
- swap-free = ${kamon.metrics.precision.default-gauge-precision}
+ used = ${kamon.metrics.precision.default-histogram-precision}
+ free = ${kamon.metrics.precision.default-histogram-precision}
+ buffer = ${kamon.metrics.precision.default-histogram-precision}
+ cache = ${kamon.metrics.precision.default-histogram-precision}
+ swap-used = ${kamon.metrics.precision.default-histogram-precision}
+ swap-free = ${kamon.metrics.precision.default-histogram-precision}
}
}
diff --git a/kamon-system-metrics/src/main/scala/kamon/metrics/HeapMetrics.scala b/kamon-system-metrics/src/main/scala/kamon/metrics/HeapMetrics.scala
index 09174f47..96e030ae 100644
--- a/kamon-system-metrics/src/main/scala/kamon/metrics/HeapMetrics.scala
+++ b/kamon-system-metrics/src/main/scala/kamon/metrics/HeapMetrics.scala
@@ -59,6 +59,7 @@ object HeapMetrics extends MetricGroupCategory {
}
val Factory = new MetricGroupFactory {
+ import kamon.system.SystemMetricsExtension._
val memory = ManagementFactory.getMemoryMXBean
def heap = memory.getHeapMemoryUsage
@@ -73,9 +74,9 @@ object HeapMetrics extends MetricGroupCategory {
val committedHeapConfig = settings.getConfig("committed")
new HeapMetricRecorder(
- Gauge.fromConfig(usedHeapConfig, system)(() ⇒ heap.getUsed),
- Gauge.fromConfig(maxHeapConfig, system)(() ⇒ heap.getMax),
- Gauge.fromConfig(committedHeapConfig, system)(() ⇒ heap.getCommitted))
+ Gauge.fromConfig(usedHeapConfig, system,Scale.Mega)(() ⇒ toMB(heap.getUsed)),
+ Gauge.fromConfig(maxHeapConfig, system, Scale.Mega)(() ⇒ toMB(heap.getMax)),
+ Gauge.fromConfig(committedHeapConfig, system, Scale.Mega)(() ⇒ toMB(heap.getCommitted)))
}
}
}
diff --git a/kamon-system-metrics/src/main/scala/kamon/metrics/MemoryMetrics.scala b/kamon-system-metrics/src/main/scala/kamon/metrics/MemoryMetrics.scala
index b2b713af..6f3eb6df 100644
--- a/kamon-system-metrics/src/main/scala/kamon/metrics/MemoryMetrics.scala
+++ b/kamon-system-metrics/src/main/scala/kamon/metrics/MemoryMetrics.scala
@@ -77,12 +77,12 @@ object MemoryMetrics extends MetricGroupCategory {
val swapFreeConfig = settings.getConfig("swap-free")
new MemoryMetricRecorder(
- Histogram.fromConfig(usedConfig, Scale.Kilo),
- Histogram.fromConfig(freeConfig, Scale.Kilo),
- Histogram.fromConfig(swapUsedConfig, Scale.Kilo),
- Histogram.fromConfig(swapFreeConfig, Scale.Kilo),
- Histogram.fromConfig(bufferConfig, Scale.Kilo),
- Histogram.fromConfig(cacheConfig, Scale.Kilo))
+ Histogram.fromConfig(usedConfig, Scale.Mega),
+ Histogram.fromConfig(freeConfig, Scale.Mega),
+ Histogram.fromConfig(swapUsedConfig, Scale.Mega),
+ Histogram.fromConfig(swapFreeConfig, Scale.Mega),
+ Histogram.fromConfig(bufferConfig, Scale.Mega),
+ Histogram.fromConfig(cacheConfig, Scale.Mega))
}
}
} \ No newline at end of file
diff --git a/kamon-system-metrics/src/main/scala/kamon/system/SystemMetrics.scala b/kamon-system-metrics/src/main/scala/kamon/system/SystemMetrics.scala
index 15566d7b..140e4577 100644
--- a/kamon-system-metrics/src/main/scala/kamon/system/SystemMetrics.scala
+++ b/kamon-system-metrics/src/main/scala/kamon/system/SystemMetrics.scala
@@ -22,12 +22,9 @@ import akka.event.Logging
import kamon.Kamon
import kamon.metric.Metrics
import kamon.metrics._
-import kamon.system.SystemMetricsCollectorActor.Collect
-import org.hyperic.sigar.{ NetInterfaceStat, SigarProxy, Mem }
-import scala.concurrent.duration._
import scala.collection.JavaConverters._
-import scala.concurrent.duration.FiniteDuration
+import scala.concurrent.duration._
object SystemMetrics extends ExtensionId[SystemMetricsExtension] with ExtensionIdProvider {
override def lookup(): ExtensionId[_ <: Extension] = SystemMetrics
@@ -49,7 +46,7 @@ class SystemMetricsExtension(private val system: ExtendedActorSystem) extends Ka
garbageCollectors.map { gc ⇒ systemMetricsExtension.register(GCMetrics(gc.getName), GCMetrics.Factory(gc)) }
//System Metrics
- system.actorOf(SystemMetricsCollectorActor.props(1 second), "system-metrics-collector")
+ system.actorOf(SystemMetricsCollector.props(1 second), "system-metrics-collector")
}
object SystemMetricsExtension {
@@ -60,89 +57,8 @@ object SystemMetricsExtension {
val Heap = "heap"
val garbageCollectors = ManagementFactory.getGarbageCollectorMXBeans.asScala.filter(_.isValid)
-}
-trait SigarExtensionProvider {
- lazy val sigar = SigarHolder.instance()
+ def toKB(value:Long):Long = value / 1024
+ def toMB(value:Long):Long = value / 1024 / 1024
+ def toLong(value:Double):Long = (value * 100L) toLong
}
-
-class SystemMetricsCollectorActor(collectInterval: FiniteDuration) extends Actor with SigarExtensionProvider {
- import kamon.system.SystemMetricsExtension._
-
- val collectSchedule = context.system.scheduler.schedule(collectInterval, collectInterval, self, Collect)(context.dispatcher)
-
- val systemMetricsExtension = Kamon(Metrics)(context.system)
-
- val cpuRecorder = systemMetricsExtension.register(CPUMetrics(CPU), CPUMetrics.Factory)
- val processCpuRecorder = systemMetricsExtension.register(ProcessCPUMetrics(ProcessCPU), ProcessCPUMetrics.Factory)
- val memoryRecorder = systemMetricsExtension.register(MemoryMetrics(Memory), MemoryMetrics.Factory)
- val networkRecorder = systemMetricsExtension.register(NetworkMetrics(Network), NetworkMetrics.Factory)
-
- def receive: Receive = {
- case Collect ⇒ collectMetrics()
- case anything ⇒
- }
-
- override def postStop() = collectSchedule.cancel()
-
- def pid = sigar.getPid
- def procCpu = sigar.getProcCpu(pid)
- def cpu = sigar.getCpuPerc
- def mem = sigar.getMem
- def swap = sigar.getSwap
-
- val interfaces: Set[String] = sigar.getNetInterfaceList.toSet
-
- def collectMetrics() = {
- cpuRecorder.map {
- cpur ⇒
- cpur.user.record((cpu.getUser * 100L).toLong)
- cpur.system.record((cpu.getSys * 100L).toLong)
- cpur.cpuWait.record((cpu.getWait() * 100L).toLong)
- cpur.idle.record((cpu.getIdle * 100L).toLong)
- }
-
- processCpuRecorder.map {
- pcpur ⇒
- pcpur.user.record(procCpu.getUser)
- pcpur.system.record(procCpu.getSys)
- }
-
- memoryRecorder.map {
- mr ⇒
- mr.used.record(mem.getUsed)
- mr.free.record(mem.getFree)
- mr.swapUsed.record(swap.getUsed)
- mr.swapFree.record(swap.getFree)
- mr.buffer.record(collectBuffer(mem))
- mr.cache.record(collectCache(mem))
- }
-
- networkRecorder.map {
- nr ⇒
- nr.rxBytes.record(collect(sigar, interfaces)(net ⇒ net.getRxBytes))
- nr.txBytes.record(collect(sigar, interfaces)(net ⇒ net.getTxBytes))
- nr.rxErrors.record(collect(sigar, interfaces)(net ⇒ net.getRxErrors))
- nr.txErrors.record(collect(sigar, interfaces)(net ⇒ net.getTxErrors))
- }
- }
-
- private def collectBuffer(mem: Mem): Long = if (mem.getUsed() != mem.getActualUsed()) mem.getActualUsed() else 0L
- private def collectCache(mem: Mem): Long = if (mem.getFree() != mem.getActualFree()) mem.getActualFree() else 0L
-
- private def collect(sigar: SigarProxy, interfaces: Set[String])(block: NetInterfaceStat ⇒ Long): Long = {
- interfaces.foldLeft(0L) { (totalBytes, interface) ⇒
- {
- val net = sigar.getNetInterfaceStat(interface)
- totalBytes + block(net)
- }
- }
- }
-}
-
-object SystemMetricsCollectorActor {
- case object Collect
-
- def props(collectInterval: FiniteDuration): Props =
- Props[SystemMetricsCollectorActor](new SystemMetricsCollectorActor(collectInterval))
-} \ No newline at end of file
diff --git a/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsCollector.scala b/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsCollector.scala
new file mode 100644
index 00000000..735a3c79
--- /dev/null
+++ b/kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsCollector.scala
@@ -0,0 +1,113 @@
+/*
+ * =========================================================================================
+ * Copyright © 2013-2014 the kamon project <http://kamon.io/>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific language governing permissions
+ * and limitations under the License.
+ * =========================================================================================
+ */
+package kamon.system
+
+import akka.actor.{Props, Actor}
+import kamon.Kamon
+import kamon.metric.Metrics
+import kamon.metrics.CPUMetrics.CPUMetricRecorder
+import kamon.metrics.MemoryMetrics.MemoryMetricRecorder
+import kamon.metrics.NetworkMetrics.NetworkMetricRecorder
+import kamon.metrics.ProcessCPUMetrics.ProcessCPUMetricsRecorder
+import kamon.metrics.{NetworkMetrics, MemoryMetrics, ProcessCPUMetrics, CPUMetrics}
+import org.hyperic.sigar.{NetInterfaceStat, SigarProxy, Mem}
+
+import scala.concurrent.duration.FiniteDuration
+
+class SystemMetricsCollector(collectInterval: FiniteDuration) extends Actor with SigarExtensionProvider {
+ import SystemMetricsCollector._
+ import kamon.system.SystemMetricsExtension._
+
+ val collectSchedule = context.system.scheduler.schedule(collectInterval, collectInterval, self, Collect)(context.dispatcher)
+
+ val systemMetricsExtension = Kamon(Metrics)(context.system)
+
+ val cpuRecorder = systemMetricsExtension.register(CPUMetrics(CPU), CPUMetrics.Factory)
+ val processCpuRecorder = systemMetricsExtension.register(ProcessCPUMetrics(ProcessCPU), ProcessCPUMetrics.Factory)
+ val memoryRecorder = systemMetricsExtension.register(MemoryMetrics(Memory), MemoryMetrics.Factory)
+ val networkRecorder = systemMetricsExtension.register(NetworkMetrics(Network), NetworkMetrics.Factory)
+
+ def receive: Receive = {
+ case Collect ⇒ collectMetrics()
+ case anything ⇒
+ }
+
+ override def postStop() = collectSchedule.cancel()
+
+ def collectMetrics() = {
+ cpuRecorder.map(recordCpu)
+ processCpuRecorder.map(recordProcessCpu)
+ memoryRecorder.map(recordMemory)
+ networkRecorder.map(recordNetwork)
+ }
+
+ private def recordCpu(cpur: CPUMetricRecorder) = {
+ cpur.user.record(toLong(cpu.getUser))
+ cpur.system.record(toLong(cpu.getSys))
+ cpur.cpuWait.record(toLong(cpu.getWait()))
+ cpur.idle.record(toLong(cpu.getIdle))
+ }
+
+ private def recordProcessCpu(pcpur:ProcessCPUMetricsRecorder) ={
+ pcpur.user.record(procCpu.getUser)
+ pcpur.system.record(procCpu.getSys)
+ }
+
+ private def recordMemory(mr:MemoryMetricRecorder) = {
+ mr.used.record(toMB(mem.getUsed))
+ mr.free.record(toMB(mem.getFree))
+ mr.swapUsed.record(toMB(swap.getUsed))
+ mr.swapFree.record(toMB(swap.getFree))
+ mr.buffer.record(toMB(collectBuffer(mem)))
+ mr.cache.record(toMB(collectCache(mem)))
+
+ def collectBuffer(mem: Mem): Long = if (mem.getUsed() != mem.getActualUsed()) mem.getActualUsed() else 0L
+ def collectCache(mem: Mem): Long = if (mem.getFree() != mem.getActualFree()) mem.getActualFree() else 0L
+ }
+
+ private def recordNetwork(nr:NetworkMetricRecorder) = {
+ nr.rxBytes.record(collect(sigar, interfaces)(net ⇒ toKB(net.getRxBytes)))
+ nr.txBytes.record(collect(sigar, interfaces)(net ⇒ toKB(net.getTxBytes)))
+ nr.rxErrors.record(collect(sigar, interfaces)(net ⇒ net.getRxErrors))
+ nr.txErrors.record(collect(sigar, interfaces)(net ⇒ net.getTxErrors))
+
+ def collect(sigar: SigarProxy, interfaces: Set[String])(block: NetInterfaceStat ⇒ Long): Long = {
+ interfaces.foldLeft(0L) { (totalBytes, interface) ⇒ {
+ val net = sigar.getNetInterfaceStat(interface)
+ totalBytes + block(net)
+ }
+ }
+ }
+ }
+}
+
+object SystemMetricsCollector {
+ case object Collect
+
+ def props(collectInterval: FiniteDuration): Props = Props[SystemMetricsCollector](new SystemMetricsCollector(collectInterval))
+}
+
+trait SigarExtensionProvider {
+ lazy val sigar = SigarHolder.instance()
+
+ def pid = sigar.getPid
+ def procCpu = sigar.getProcCpu(pid)
+ def cpu = sigar.getCpuPerc
+ def mem = sigar.getMem
+ def swap = sigar.getSwap
+
+ val interfaces: Set[String] = sigar.getNetInterfaceList.toSet
+}
diff --git a/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarLoader.scala b/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarLoader.scala
index 0c78504e..e78c71f4 100644
--- a/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarLoader.scala
+++ b/kamon-system-metrics/src/main/scala/kamon/system/sigar/SigarLoader.scala
@@ -19,10 +19,9 @@ package kamon.system.sigar
import java.io._
import java.util
import java.util.logging.Logger
-import java.util.{ ArrayList, List }
+import java.util.{ArrayList, List}
-import kamon.system.SynchronizedSigar
-import org.hyperic.sigar.SigarProxy
+import org.hyperic.sigar.{Sigar, SigarProxy}
import scala.annotation.tailrec
import scala.collection.JavaConversions._
@@ -47,7 +46,7 @@ object SigarLoader {
attachToLibraryPath(tmpDir)
try {
- val sigar = new SynchronizedSigar()
+ val sigar = new Sigar()
sigar.getPid
sigar
} catch {