From 9b9484380d508e24afdbcae0bbdf0b76215aedee Mon Sep 17 00:00:00 2001 From: Diego Date: Fri, 25 Jul 2014 20:40:12 -0300 Subject: = kamon-system-metrics: collector actor refactor --- .../src/main/java/kamon/system/SigarHolder.java | 1 - .../main/java/kamon/system/SynchronizedSigar.java | 429 --------------------- .../src/main/resources/reference.conf | 28 +- .../src/main/scala/kamon/metrics/HeapMetrics.scala | 7 +- .../main/scala/kamon/metrics/MemoryMetrics.scala | 12 +- .../main/scala/kamon/system/SystemMetrics.scala | 94 +---- .../kamon/system/SystemMetricsCollector.scala | 113 ++++++ .../scala/kamon/system/sigar/SigarLoader.scala | 7 +- 8 files changed, 145 insertions(+), 546 deletions(-) delete mode 100644 kamon-system-metrics/src/main/java/kamon/system/SynchronizedSigar.java create mode 100644 kamon-system-metrics/src/main/scala/kamon/system/SystemMetricsCollector.scala 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 - * - * 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 + * + * 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 { -- cgit v1.2.3