aboutsummaryrefslogblamecommitdiff
path: root/kamon-system-metrics/src/test/scala/kamon/metrics/SystemMetricsSpec.scala
blob: 8115c2e9900e355b2ae7220281b7226cded6ef9c (plain) (tree)
























































































































































                                                                                                       



                                            













































































































































































                                                                                                                  
/* =========================================================================================
 * 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.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
    }
  }
}