aboutsummaryrefslogblamecommitdiff
path: root/kamon-core/src/main/scala/kamon/metric/UserMetrics.scala
blob: b511b4bc98a1024c818ea70de978e9e69b859be4 (plain) (tree)
1
2
3
4
5
6
7
8
9
10


                    
                                                                           


                                                                           


                                                                                 
                      
 

                                                                                   
 


                                                                                                          
 
















                                                                                                                 


                                                                                                      


                                                                                                                     

   




                                                                                                      
 




                                                                                                     

                                                                                              




                                                                                                                            

                                           
                                                    

                                         
                                                  

                                               
                                                        

                                       
                                                

 
                                                                                       
                                                           
 

                                                                                                           
                              



               
                                                                                           
















                                                                                                       

   



             
                                                                                         
                               

   





                                                                                
 

                                                                                                 
 

                                                                                           
 

                                                                                    
 


                   
 
                                                                                               

                                     
 


                                                                                                  
 

                                             
 

                                                                                                               
 

                                                                                                       
 

                                                                                                   
 


           
 
                                                                                       

                             
 


                                                                          
 

                                     
 

                                                                                               
 

                                                                                       
 

                                                                                           
 



                                                                                                     
 

                                                                                   

 
 
package kamon.metric

import akka.actor
import akka.actor.{ ExtendedActorSystem, ExtensionIdProvider, ExtensionId }
import kamon.Kamon
import kamon.metric.instrument.{ Gauge, MinMaxCounter, Counter, Histogram }

import scala.concurrent.duration.FiniteDuration

class UserMetricsExtension(system: ExtendedActorSystem) extends Kamon.Extension {
  import UserMetrics._

  lazy val metricsExtension = Kamon(Metrics)(system)
  val precisionConfig = system.settings.config.getConfig("kamon.metrics.precision")

  val defaultHistogramPrecisionConfig = precisionConfig.getConfig("default-histogram-precision")
  val defaultMinMaxCounterPrecisionConfig = precisionConfig.getConfig("default-min-max-counter-precision")
  val defaultGaugePrecisionConfig = precisionConfig.getConfig("default-gauge-precision")

  def registerHistogram(name: String, precision: Histogram.Precision, highestTrackableValue: Long): Histogram = {
    metricsExtension.storage.getOrElseUpdate(UserHistogram(name), {
      UserHistogramRecorder(Histogram(highestTrackableValue, precision, Scale.Unit))
    }).asInstanceOf[UserHistogramRecorder].histogram
  }

  def registerHistogram(name: String): Histogram = {
    metricsExtension.storage.getOrElseUpdate(UserHistogram(name), {
      UserHistogramRecorder(Histogram.fromConfig(defaultHistogramPrecisionConfig))
    }).asInstanceOf[UserHistogramRecorder].histogram
  }

  def registerCounter(name: String): Counter = {
    metricsExtension.storage.getOrElseUpdate(UserCounter(name), {
      UserCounterRecorder(Counter())
    }).asInstanceOf[UserCounterRecorder].counter
  }

  def registerMinMaxCounter(name: String, precision: Histogram.Precision, highestTrackableValue: Long,
    refreshInterval: FiniteDuration): MinMaxCounter = {
    metricsExtension.storage.getOrElseUpdate(UserMinMaxCounter(name), {
      UserMinMaxCounterRecorder(MinMaxCounter(highestTrackableValue, precision, Scale.Unit, refreshInterval, system))
    }).asInstanceOf[UserMinMaxCounterRecorder].minMaxCounter
  }

  def registerMinMaxCounter(name: String): MinMaxCounter = {
    metricsExtension.storage.getOrElseUpdate(UserMinMaxCounter(name), {
      UserMinMaxCounterRecorder(MinMaxCounter.fromConfig(defaultMinMaxCounterPrecisionConfig, system))
    }).asInstanceOf[UserMinMaxCounterRecorder].minMaxCounter
  }

  def registerGauge(name: String)(currentValueCollector: Gauge.CurrentValueCollector): Gauge = {
    metricsExtension.storage.getOrElseUpdate(UserGauge(name), {
      UserGaugeRecorder(Gauge.fromConfig(defaultGaugePrecisionConfig, system)(currentValueCollector))
    }).asInstanceOf[UserGaugeRecorder].gauge
  }

  def registerGauge(name: String, precision: Histogram.Precision, highestTrackableValue: Long,
    refreshInterval: FiniteDuration)(currentValueCollector: Gauge.CurrentValueCollector): Gauge = {
    metricsExtension.storage.getOrElseUpdate(UserGauge(name), {
      UserGaugeRecorder(Gauge(precision, highestTrackableValue, Scale.Unit, refreshInterval, system)(currentValueCollector))
    }).asInstanceOf[UserGaugeRecorder].gauge
  }

  def removeHistogram(name: String): Unit =
    metricsExtension.unregister(UserHistogram(name))

  def removeCounter(name: String): Unit =
    metricsExtension.unregister(UserCounter(name))

  def removeMinMaxCounter(name: String): Unit =
    metricsExtension.unregister(UserMinMaxCounter(name))

  def removeGauge(name: String): Unit =
    metricsExtension.unregister(UserGauge(name))
}

object UserMetrics extends ExtensionId[UserMetricsExtension] with ExtensionIdProvider {
  def lookup(): ExtensionId[_ <: actor.Extension] = Metrics

  def createExtension(system: ExtendedActorSystem): UserMetricsExtension = new UserMetricsExtension(system)

  sealed trait UserMetricGroup
  //
  // Histograms
  //

  case class UserHistogram(name: String) extends MetricGroupIdentity with UserMetricGroup {
    val category = UserHistograms
  }

  case class UserHistogramRecorder(histogram: Histogram) extends MetricGroupRecorder {
    def collect(context: CollectionContext): MetricGroupSnapshot =
      UserHistogramSnapshot(histogram.collect(context))

    def cleanup: Unit = histogram.cleanup
  }

  case class UserHistogramSnapshot(histogramSnapshot: Histogram.Snapshot) extends MetricGroupSnapshot {
    type GroupSnapshotType = UserHistogramSnapshot

    def merge(that: UserHistogramSnapshot, context: CollectionContext): UserHistogramSnapshot =
      UserHistogramSnapshot(that.histogramSnapshot.merge(histogramSnapshot, context))

    def metrics: Map[MetricIdentity, MetricSnapshot] = Map((RecordedValues, histogramSnapshot))
  }

  //
  // Counters
  //

  case class UserCounter(name: String) extends MetricGroupIdentity with UserMetricGroup {
    val category = UserCounters
  }

  case class UserCounterRecorder(counter: Counter) extends MetricGroupRecorder {
    def collect(context: CollectionContext): MetricGroupSnapshot =
      UserCounterSnapshot(counter.collect(context))

    def cleanup: Unit = counter.cleanup
  }

  case class UserCounterSnapshot(counterSnapshot: Counter.Snapshot) extends MetricGroupSnapshot {
    type GroupSnapshotType = UserCounterSnapshot

    def merge(that: UserCounterSnapshot, context: CollectionContext): UserCounterSnapshot =
      UserCounterSnapshot(that.counterSnapshot.merge(counterSnapshot, context))

    def metrics: Map[MetricIdentity, MetricSnapshot] = Map((Count, counterSnapshot))
  }

  //
  // MinMaxCounters
  //

  case class UserMinMaxCounter(name: String) extends MetricGroupIdentity with UserMetricGroup {
    val category = UserMinMaxCounters
  }

  case class UserMinMaxCounterRecorder(minMaxCounter: MinMaxCounter) extends MetricGroupRecorder {
    def collect(context: CollectionContext): MetricGroupSnapshot =
      UserMinMaxCounterSnapshot(minMaxCounter.collect(context))

    def cleanup: Unit = minMaxCounter.cleanup
  }

  case class UserMinMaxCounterSnapshot(minMaxCounterSnapshot: Histogram.Snapshot) extends MetricGroupSnapshot {
    type GroupSnapshotType = UserMinMaxCounterSnapshot

    def merge(that: UserMinMaxCounterSnapshot, context: CollectionContext): UserMinMaxCounterSnapshot =
      UserMinMaxCounterSnapshot(that.minMaxCounterSnapshot.merge(minMaxCounterSnapshot, context))

    def metrics: Map[MetricIdentity, MetricSnapshot] = Map((RecordedValues, minMaxCounterSnapshot))
  }

  //
  // Gauges
  //

  case class UserGauge(name: String) extends MetricGroupIdentity with UserMetricGroup {
    val category = UserGauges
  }

  case class UserGaugeRecorder(gauge: Gauge) extends MetricGroupRecorder {
    def collect(context: CollectionContext): MetricGroupSnapshot =
      UserGaugeSnapshot(gauge.collect(context))

    def cleanup: Unit = gauge.cleanup
  }

  case class UserGaugeSnapshot(gaugeSnapshot: Histogram.Snapshot) extends MetricGroupSnapshot {
    type GroupSnapshotType = UserGaugeSnapshot

    def merge(that: UserGaugeSnapshot, context: CollectionContext): UserGaugeSnapshot =
      UserGaugeSnapshot(that.gaugeSnapshot.merge(gaugeSnapshot, context))

    def metrics: Map[MetricIdentity, MetricSnapshot] = Map((RecordedValues, gaugeSnapshot))
  }

  case object UserHistograms extends MetricGroupCategory { val name: String = "histogram" }
  case object UserCounters extends MetricGroupCategory { val name: String = "counter" }
  case object UserMinMaxCounters extends MetricGroupCategory { val name: String = "min-max-counter" }
  case object UserGauges extends MetricGroupCategory { val name: String = "gauge" }

  case object RecordedValues extends MetricIdentity { val name: String = "values" }
  case object Count extends MetricIdentity { val name: String = "count" }

}