From 5c141733ad39cf2730cf34dc8f3f4a82f0c1b516 Mon Sep 17 00:00:00 2001 From: Diego Date: Tue, 24 Jun 2014 23:35:14 -0300 Subject: ! kamon-system-metrics: introducing System and JVM metrics module --- .../scala/kamon/metrics/SystemMetricsSpec.scala | 331 +++++++++++++++++++++ 1 file changed, 331 insertions(+) create mode 100644 kamon-system-metrics/src/test/scala/kamon/metrics/SystemMetricsSpec.scala (limited to 'kamon-system-metrics/src/test/scala/kamon/metrics/SystemMetricsSpec.scala') diff --git a/kamon-system-metrics/src/test/scala/kamon/metrics/SystemMetricsSpec.scala b/kamon-system-metrics/src/test/scala/kamon/metrics/SystemMetricsSpec.scala new file mode 100644 index 00000000..ed10903f --- /dev/null +++ b/kamon-system-metrics/src/test/scala/kamon/metrics/SystemMetricsSpec.scala @@ -0,0 +1,331 @@ +/* ========================================================================================= + * 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.metric + +import akka.actor.ActorSystem +import akka.testkit.{ TestKitBase, TestProbe } +import com.typesafe.config.ConfigFactory +import kamon.Kamon +import kamon.metric.Subscriptions.TickMetricSnapshot +import kamon.metrics.HeapMetrics.HeapMetricSnapshot +import kamon.metrics.MemoryMetrics.MemoryMetricSnapshot +import kamon.metrics.NetworkMetrics.NetworkMetricSnapshot +import kamon.metrics.ProcessCPUMetrics.ProcessCPUMetricsSnapshot +import kamon.metrics._ +import kamon.metrics.CPUMetrics.CPUMetricSnapshot +import kamon.metrics.GCMetrics.GCMetricSnapshot +import kamon.system.SystemMetricsExtension +import org.scalatest.{ Matchers, WordSpecLike } + +import scala.concurrent.duration._ + +class SystemMetricsSpec extends TestKitBase with WordSpecLike with Matchers { + implicit lazy val system: ActorSystem = ActorSystem("system-metrics-spec", ConfigFactory.parseString( + """ + |akka { + | extensions = ["kamon.system.SystemMetrics"] + |} + | + |kamon.metrics { + | + | disable-aspectj-weaver-missing-error = true + | + | tick-interval = 1 second + | + | system { + | cpu { + | user { + | highest-trackable-value = 999999999 + | significant-value-digits = 2 + | } + | system { + | highest-trackable-value = 999999999 + | significant-value-digits = 2 + | } + | wait { + | highest-trackable-value = 999999999 + | significant-value-digits = 2 + | } + | idle { + | highest-trackable-value = 999999999 + | significant-value-digits = 2 + | } + | } + | process-cpu { + | user { + | highest-trackable-value = 999999999 + | significant-value-digits = 2 + | } + | system { + | highest-trackable-value = 999999999 + | significant-value-digits = 2 + | } + | } + | memory { + | used { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | free { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | buffer { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | cache { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | swap-used { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | swap-free { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | } + | network { + | rx-bytes { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | tx-bytes { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | rx-errors { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | tx-errors { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | } + | heap { + | used { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | max { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | committed { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | } + | gc { + | count { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | time { + | highest-trackable-value = 3600000000000 + | significant-value-digits = 2 + | } + | } + | } + |} + """.stripMargin)) + + "the Kamon CPU Metrics" should { + "record user, system, wait, idle metrics" in new CPUMetricsListenerFixture { + val metricsListener = subscribeToMetrics() + + val CPUMetrics = expectCPUMetrics(metricsListener, 3 seconds) + CPUMetrics.user.max should be > 0L + CPUMetrics.system.max should be > 0L + CPUMetrics.cpuWait.max should be > 0L + CPUMetrics.idle.max should be > 0L + } + } + "the Kamon GC Metrics" should { + "record count, time metrics" in new GCMetricsListenerFixture { + val metricsListener = subscribeToMetrics() + + val GCMetrics = expectGCMetrics(metricsListener, 3 seconds) + GCMetrics.count.max should be > 0L + GCMetrics.time.max should be > 0L + } + } + + "the Kamon Heap Metrics" should { + "record used, max, commited metrics" in new HeapMetricsListenerFixture { + val metricsListener = subscribeToMetrics() + + val HeapMetrics = expectHeapMetrics(metricsListener, 3 seconds) + HeapMetrics.used.max should be >= 0L + HeapMetrics.max.max should be >= 0L + HeapMetrics.committed.max should be >= 0L + } + } + + "the Kamon Memory Metrics" should { + "record used, free, buffer, cache, swap used, swap free metrics" in new MemoryMetricsListenerFixture { + val metricsListener = subscribeToMetrics() + + val MemoryMetrics = expectMemoryMetrics(metricsListener, 3 seconds) + MemoryMetrics.used.max should be >= 0L + MemoryMetrics.free.max should be >= 0L + MemoryMetrics.buffer.max should be >= 0L + MemoryMetrics.cache.max should be >= 0L + MemoryMetrics.swapUsed.max should be >= 0L + MemoryMetrics.swapFree.max should be >= 0L + } + } + + "the Kamon Network Metrics" should { + "record rxBytes, txBytes, rxErrors, txErrors metrics" in new NetworkMetricsListenerFixture { + val metricsListener = subscribeToMetrics() + + val NetworkMetrics = expectNetworkMetrics(metricsListener, 3 seconds) + NetworkMetrics.rxBytes.max should be >= 0L + NetworkMetrics.txBytes.max should be >= 0L + NetworkMetrics.rxErrors.max should be >= 0L + NetworkMetrics.txErrors.max should be >= 0L + } + } + + "the Kamon Process CPU Metrics" should { + "record user, system metrics" in new ProcessCPUMetricsListenerFixture { + val metricsListener = subscribeToMetrics() + + val ProcessCPUMetrics = expectProcessCPUMetrics(metricsListener, 3 seconds) + ProcessCPUMetrics.user.max should be > 0L + ProcessCPUMetrics.system.max should be > 0L + } + } + + def expectCPUMetrics(listener: TestProbe, waitTime: FiniteDuration): CPUMetricSnapshot = { + val tickSnapshot = within(waitTime) { + listener.expectMsgType[TickMetricSnapshot] + } + val cpuMetricsOption = tickSnapshot.metrics.get(CPUMetrics(SystemMetricsExtension.CPU)) + cpuMetricsOption should not be empty + cpuMetricsOption.get.asInstanceOf[CPUMetricSnapshot] + } + + trait CPUMetricsListenerFixture { + def subscribeToMetrics(): TestProbe = { + val metricsListener = TestProbe() + Kamon(Metrics).subscribe(CPUMetrics, "*", metricsListener.ref, permanently = true) + // Wait for one empty snapshot before proceeding to the test. + metricsListener.expectMsgType[TickMetricSnapshot] + metricsListener + } + } + + def expectGCMetrics(listener: TestProbe, waitTime: FiniteDuration): GCMetricSnapshot = { + val tickSnapshot = within(waitTime) { + listener.expectMsgType[TickMetricSnapshot] + } + + val gcMetricsOption = tickSnapshot.metrics.get(GCMetrics(SystemMetricsExtension.garbageCollectors(0).getName)) + gcMetricsOption should not be empty + gcMetricsOption.get.asInstanceOf[GCMetricSnapshot] + } + + trait GCMetricsListenerFixture { + def subscribeToMetrics(): TestProbe = { + val metricsListener = TestProbe() + Kamon(Metrics).subscribe(GCMetrics, "*", metricsListener.ref, permanently = true) + // Wait for one empty snapshot before proceeding to the test. + metricsListener.expectMsgType[TickMetricSnapshot] + metricsListener + } + } + + def expectHeapMetrics(listener: TestProbe, waitTime: FiniteDuration): HeapMetricSnapshot = { + val tickSnapshot = within(waitTime) { + listener.expectMsgType[TickMetricSnapshot] + } + val heapMetricsOption = tickSnapshot.metrics.get(HeapMetrics(SystemMetricsExtension.Heap)) + heapMetricsOption should not be empty + heapMetricsOption.get.asInstanceOf[HeapMetricSnapshot] + } + + trait HeapMetricsListenerFixture { + def subscribeToMetrics(): TestProbe = { + val metricsListener = TestProbe() + Kamon(Metrics).subscribe(HeapMetrics, "*", metricsListener.ref, permanently = true) + // Wait for one empty snapshot before proceeding to the test. + metricsListener.expectMsgType[TickMetricSnapshot] + metricsListener + } + } + + def expectMemoryMetrics(listener: TestProbe, waitTime: FiniteDuration): MemoryMetricSnapshot = { + val tickSnapshot = within(waitTime) { + listener.expectMsgType[TickMetricSnapshot] + } + val memoryMetricsOption = tickSnapshot.metrics.get(MemoryMetrics(SystemMetricsExtension.Memory)) + memoryMetricsOption should not be empty + memoryMetricsOption.get.asInstanceOf[MemoryMetricSnapshot] + } + + trait MemoryMetricsListenerFixture { + def subscribeToMetrics(): TestProbe = { + val metricsListener = TestProbe() + Kamon(Metrics).subscribe(MemoryMetrics, "*", metricsListener.ref, permanently = true) + // Wait for one empty snapshot before proceeding to the test. + metricsListener.expectMsgType[TickMetricSnapshot] + metricsListener + } + } + + def expectNetworkMetrics(listener: TestProbe, waitTime: FiniteDuration): NetworkMetricSnapshot = { + val tickSnapshot = within(waitTime) { + listener.expectMsgType[TickMetricSnapshot] + } + val networkMetricsOption = tickSnapshot.metrics.get(NetworkMetrics(SystemMetricsExtension.Network)) + networkMetricsOption should not be empty + networkMetricsOption.get.asInstanceOf[NetworkMetricSnapshot] + } + + trait NetworkMetricsListenerFixture { + def subscribeToMetrics(): TestProbe = { + val metricsListener = TestProbe() + Kamon(Metrics).subscribe(NetworkMetrics, "*", metricsListener.ref, permanently = true) + // Wait for one empty snapshot before proceeding to the test. + metricsListener.expectMsgType[TickMetricSnapshot] + metricsListener + } + } + + def expectProcessCPUMetrics(listener: TestProbe, waitTime: FiniteDuration): ProcessCPUMetricsSnapshot = { + val tickSnapshot = within(waitTime) { + listener.expectMsgType[TickMetricSnapshot] + } + val processCPUMetricsOption = tickSnapshot.metrics.get(ProcessCPUMetrics(SystemMetricsExtension.ProcessCPU)) + processCPUMetricsOption should not be empty + processCPUMetricsOption.get.asInstanceOf[ProcessCPUMetricsSnapshot] + } + + trait ProcessCPUMetricsListenerFixture { + def subscribeToMetrics(): TestProbe = { + val metricsListener = TestProbe() + Kamon(Metrics).subscribe(ProcessCPUMetrics, "*", metricsListener.ref, permanently = true) + // Wait for one empty snapshot before proceeding to the test. + metricsListener.expectMsgType[TickMetricSnapshot] + metricsListener + } + } +} -- cgit v1.2.3