|
Akka/Scala example source code file (MetricsKit.scala)
The MetricsKit.scala Akka example source code/** * Copyright (C) 2009-2014 Typesafe Inc. <http://www.typesafe.com> */ package akka.testkit.metrics import com.codahale.metrics._ import java.net.InetSocketAddress import java.util.concurrent.TimeUnit import scala.concurrent.duration._ import com.typesafe.config.Config import java.util import scala.util.matching.Regex import scala.collection.mutable import akka.testkit.metrics.reporter.{ GraphiteClient, AkkaGraphiteReporter, AkkaConsoleReporter } import org.scalatest.Notifying import scala.reflect.ClassTag /** * Allows to easily measure performance / memory / file descriptor use in tests. * * WARNING: This trait should not be seen as utility for micro-benchmarking, * please refer to <a href="http://openjdk.java.net/projects/code-tools/jmh/">JMH</a> if that's what you're writing. * This trait instead aims to give an high level overview as well as data for trend-analysis of long running tests. * * Reporting defaults to [[ConsoleReporter]]. * In order to send registry to Graphite run sbt with the following property: `-Dakka.registry.reporting.0=graphite`. */ private[akka] trait MetricsKit extends MetricsKitOps { this: Notifying ⇒ import MetricsKit._ import collection.JavaConverters._ private var reporters: List[ScheduledReporter] = Nil /** * A configuration containing [[MetricsKitSettings]] under the key `akka.test.registry` must be provided. * This can be the ActorSystems config. * * The reason this is not handled by an Extension is thatwe do not want to enforce having to start an ActorSystem, * since code measured using this Kit may not need one (e.g. measuring plain Queue implementations). */ def metricsConfig: Config private[metrics] val registry = new MetricRegistry() with AkkaMetricRegistry initMetricReporters() def initMetricReporters() { val settings = new MetricsKitSettings(metricsConfig) def configureConsoleReporter() { if (settings.Reporters.contains("console")) { val akkaConsoleReporter = new AkkaConsoleReporter(registry, settings.ConsoleReporter.Verbose) if (settings.ConsoleReporter.ScheduledReportInterval > Duration.Zero) akkaConsoleReporter.start(settings.ConsoleReporter.ScheduledReportInterval.toMillis, TimeUnit.MILLISECONDS) reporters ::= akkaConsoleReporter } } def configureGraphiteReporter() { if (settings.Reporters.contains("graphite")) { note(s"MetricsKit: Graphite reporter enabled, sending metrics to: ${settings.GraphiteReporter.Host}:${settings.GraphiteReporter.Port}") val address = new InetSocketAddress(settings.GraphiteReporter.Host, settings.GraphiteReporter.Port) val graphite = new GraphiteClient(address) val akkaGraphiteReporter = new AkkaGraphiteReporter(registry, settings.GraphiteReporter.Prefix, graphite, settings.GraphiteReporter.Verbose) if (settings.GraphiteReporter.ScheduledReportInterval > Duration.Zero) { akkaGraphiteReporter.start(settings.GraphiteReporter.ScheduledReportInterval.toMillis, TimeUnit.MILLISECONDS) } reporters ::= akkaGraphiteReporter } } configureConsoleReporter() configureGraphiteReporter() } /** * Schedule metric reports execution iterval. Should not be used multiple times */ def scheduleMetricReports(every: FiniteDuration) { reporters foreach { _.start(every.toMillis, TimeUnit.MILLISECONDS) } } def registeredMetrics = registry.getMetrics.asScala /** * Causes immediate flush of metrics, using all registered reporters. * Afterwards all metrics are removed from the registry. * * HINT: this operation can be costy, run outside of your tested code, or rely on scheduled reporting. */ def reportAndClearMetrics() { reportMetrics() clearMetrics() } /** * Causes immediate flush of metrics, using all registered reporters. * * HINT: this operation can be costy, run outside of your tested code, or rely on scheduled reporting. */ def reportMetrics() { reporters foreach { _.report() } } /** * Causes immediate flush of only memory related metrics, using all registered reporters. * * HINT: this operation can be costy, run outside of your tested code, or rely on scheduled reporting. */ def reportMemoryMetrics() { val gauges = registry.getGauges(MemMetricsFilter) reporters foreach { _.report(gauges, empty, empty, empty, empty) } } /** * Causes immediate flush of only memory related metrics, using all registered reporters. * * HINT: this operation can be costy, run outside of your tested code, or rely on scheduled reporting. */ def reportGcMetrics() { val gauges = registry.getGauges(GcMetricsFilter) reporters foreach { _.report(gauges, empty, empty, empty, empty) } } /** * Causes immediate flush of only file descriptor metrics, using all registered reporters. * * HINT: this operation can be costy, run outside of your tested code, or rely on scheduled reporting. */ def reportFileDescriptorMetrics() { val gauges = registry.getGauges(FileDescriptorMetricsFilter) reporters foreach { _.report(gauges, empty, empty, empty, empty) } } /** * Removes registered registry from registry. * You should call this method then you're done measuring something - usually at the end of your test case, * otherwise the registry from different tests would influence each others results (avg, min, max, ...). * * Please note that, if you have registered a `timer("thing")` previously, you will need to call `timer("thing")` again, * in order to register a new timer. */ def clearMetrics(matching: MetricFilter = MetricFilter.ALL) { registry.removeMatching(matching) } /** * MUST be called after all tests have finished. */ def shutdownMetrics() { reporters foreach { _.stop() } } private[metrics] def getOrRegister[M <: Metric](key: String, metric: ⇒ M)(implicit tag: ClassTag[M]): M = { import collection.JavaConverters._ registry.getMetrics.asScala.find(_._1 == key).map(_._2) match { case Some(existing: M) ⇒ existing case Some(existing) ⇒ throw new IllegalArgumentException("Key: [%s] is already for different kind of metric! Was [%s], expected [%s]".format(key, metric.getClass.getSimpleName, tag.runtimeClass.getSimpleName)) case _ ⇒ registry.register(key, metric) } } private val emptySortedMap = new util.TreeMap[String, Nothing]() private def empty[T] = emptySortedMap.asInstanceOf[util.TreeMap[String, T]] } private[akka] object MetricsKit { class RegexMetricFilter(regex: Regex) extends MetricFilter { override def matches(name: String, metric: Metric) = regex.pattern.matcher(name).matches() } val MemMetricsFilter = new RegexMetricFilter(""".*\.mem\..*""".r) val FileDescriptorMetricsFilter = new RegexMetricFilter(""".*\.file-descriptors\..*""".r) val KnownOpsInTimespanCounterFilter = new MetricFilter { override def matches(name: String, metric: Metric) = classOf[KnownOpsInTimespanTimer].isInstance(metric) } val GcMetricsFilter = new MetricFilter { val keyPattern = """.*\.gc\..*""".r.pattern override def matches(name: String, metric: Metric) = keyPattern.matcher(name).matches() } } /** Provides access to custom Akka [[Metric]]s, with named methods. */ trait AkkaMetricRegistry { this: MetricRegistry ⇒ def getKnownOpsInTimespanCounters = filterFor(classOf[KnownOpsInTimespanTimer]) def getHdrHistograms = filterFor(classOf[HdrHistogram]) def getAveragingGauges = filterFor(classOf[AveragingGauge]) import collection.JavaConverters._ private def filterFor[T](clazz: Class[T]): mutable.Iterable[(String, T)] = for { (key, metric) ← getMetrics.asScala if clazz.isInstance(metric) } yield key -> metric.asInstanceOf[T] } private[akka] class MetricsKitSettings(config: Config) { import akka.util.Helpers._ val Reporters = config.getStringList("akka.test.metrics.reporters") object GraphiteReporter { val Prefix = config.getString("akka.test.metrics.reporter.graphite.prefix") lazy val Host = config.getString("akka.test.metrics.reporter.graphite.host").requiring(v ⇒ !v.trim.isEmpty, "akka.test.metrics.reporter.graphite.host was used but was empty!") val Port = config.getInt("akka.test.metrics.reporter.graphite.port") val Verbose = config.getBoolean("akka.test.metrics.reporter.graphite.verbose") val ScheduledReportInterval = config.getMillisDuration("akka.test.metrics.reporter.graphite.scheduled-report-interval") } object ConsoleReporter { val ScheduledReportInterval = config.getMillisDuration("akka.test.metrics.reporter.console.scheduled-report-interval") val Verbose = config.getBoolean("akka.test.metrics.reporter.console.verbose") } } Other Akka source code examplesHere is a short list of links related to this Akka MetricsKit.scala source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.