这个神秘的Scala对象来自哪里?

时间:2017-07-21 18:19:06

标签: scala dropwizard metrics

请注意:虽然这个问题与流行的Dropwizard Metrics库及其Scala API类似物Metrics Scala有关,但这是 - 在其核心 - 严格斯卡拉问题。因此,我相信任何知识渊博的Scala开发人员都可以回答这个问题!

我是Scala的新手,我正在尝试构建一个简单的应用程序,它将利用这个Metrics-Scala库(这也是DW Metrics的Scala API)。我发现了一个非常有用的GitHub项目,展示了如何在现实世界中设置Metrics-Scala,以及我在can be found here下面引用的源文件。

我将源文件切割成一个更小,更简单的版本来说明我的问题:

object Metrics extends App {
  val metricRegistry = new com.codahale.metrics.MetricRegistry()
  val healthCheckRegistry = new com.codahale.metrics.health.HealthCheckRegistry()

  ConsoleReporter.forRegistry(metricRegistry)
    .convertRatesTo(TimeUnit.SECONDS)
    .convertDurationsTo(TimeUnit.MILLISECONDS)
    .build().start(10, TimeUnit.SECONDS)

  run()

  while(true){}

  def run() {
    new TimerExample().longRunningInstrumentedMethod()

    spawn {
      val gaugeExample = new RandomNumberGaugeExample()

      while (true) {
        Thread.sleep(500)
        gaugeExample.fetchingRandomNumber()
      }
    }
  }
}

trait Instrumented extends InstrumentedBuilder {
  val metricRegistry = Metrics.metricRegistry
}

class RandomNumberGaugeExample() extends Instrumented {
  def fetchingRandomNumber(): Int = {
    metrics.gauge("random-number") {
      Math.abs(new Random().nextInt() % 1000)
    }.value
  }
}

我关心的是这个神秘的metrics对象及其用法。

我了解RandomNumberGaugeExample继承了metricsRegistry个实例,因为它扩展了Instrumented。但是我没有看到metrics实例的定义位置,类型是什么,以及RandomNumberGaugeExample如何获取它。 RandomNumberGaugeExample只能访问metricsRegistry吗?!

这个恶魔是什么:

metrics.gauge("random-number") {
  Math.abs(new Random().nextInt() % 1000)
}.value

metrics.guage如何返回整数值?

2 个答案:

答案 0 :(得分:2)

  

我知道RandomNumberGaugeExample继承了metricsRegistry实例,因为它扩展了Instrumented。但是,我没有看到该度量标准实例的定义位置,类型,以及RandomNumberGaugeExample如何获取它。 RandomNumberGaugeExample不能访问metricsRegistry吗?!

metrics实例继承自InstrumentedBuilder特征,如源代码所示。

trait InstrumentedBuilder extends BaseBuilder {
  protected lazy val metricBuilder = new MetricBuilder(metricBaseName, metricRegistry)

  /**
   * The MetricBuilder that can be used for creating timers, counters, etc.
   */
  def metrics: MetricBuilder = metricBuilder

  /**
   * The MetricRegistry where created metrics are registered.
   */
  val metricRegistry: MetricRegistry
}
  

这个恶魔是什么......

Gauge对象定义了apply方法:

object Gauge {
  def apply[A](f: => A) = new Gauge[A](new DropwizardGauge[A] {
    def getValue: A = f
  })
}

这允许将返回的Gauge对象视为接受一个参数的函数,该参数本身就是一个返回值的函数。

为了进一步参考,我建议在Scala tutorials

中使用这些章节

答案 1 :(得分:2)

Instrumented扩展InstrumentedBuilder,这是我们找到metrics的地方。 metricsMetricsBuilder

至于metrics.gauge,让我们看一下gauge方法:

def gauge[A](name: String, scope: String = null)(f: => A): Gauge[A] = {
  wrapDwGauge(metricNameFor(name, scope), new DropwizardGauge[A] { def getValue: A = f })
}

此方法有两个参数列表。第二个参数列表(f: => A)具有名为f的名为A的名称调用参数,其类型为DropwizardGauge。使用f创建新的Gauge并传递给wrapDwGauge,这会创建一个新的metrics.gauge("random-number") { Math.abs(new Random().nextInt() % 1000) }.value 实例。所以下面的恶魔...

gauge

...基本上是调用String方法,传递两个参数("random-number" IntMath.abs(new Random().nextInt() % 1000) .value结果,然后在结果上调用.valueInt会返回.value,因为我们可以看到heregetValue只会在创建的DropwizardGauge上调用temperature, time, coeff... 0.32, 12:00:23, 2,.. 0.43, 11:22:23, 3,.. 方法。