diff options
Diffstat (limited to 'kamon-newrelic/src')
5 files changed, 59 insertions, 21 deletions
diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetrics.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetrics.scala new file mode 100644 index 00000000..08e0add3 --- /dev/null +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetrics.scala @@ -0,0 +1,33 @@ +/* + * ========================================================================================= + * Copyright © 2013 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.newrelic + +import akka.actor.Actor +import kamon.metrics._ + +trait CustomMetrics { + self: Actor ⇒ + + def collectCustomMetrics(metrics: Map[MetricGroupIdentity, MetricGroupSnapshot]): Seq[NewRelic.Metric] = { + metrics.collect { + case (CustomMetric(name), groupSnapshot) ⇒ + groupSnapshot.metrics collect { + case (_, snapshot) ⇒ toNewRelicMetric(Scale.Unit)(s"Custom/$name", None, snapshot) + } + }.flatten.toSeq + } +} diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/MetricTranslator.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/MetricTranslator.scala index 0162dd9c..46e22571 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/MetricTranslator.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/MetricTranslator.scala @@ -20,15 +20,16 @@ import akka.actor.{ Props, ActorRef, Actor } import kamon.metrics.Subscriptions.TickMetricSnapshot import kamon.newrelic.MetricTranslator.TimeSliceMetrics -class MetricTranslator(receiver: ActorRef) extends Actor with WebTransactionMetrics { +class MetricTranslator(receiver: ActorRef) extends Actor + with WebTransactionMetrics with CustomMetrics { def receive = { case TickMetricSnapshot(from, to, metrics) ⇒ - val scaledFrom = (from / 1E3).toInt - val scaledTo = (to / 1E3).toInt - val allMetrics = collectWebTransactionMetrics(metrics) + val fromInSeconds = (from / 1E3).toInt + val toInSeconds = (to / 1E3).toInt + val allMetrics = collectWebTransactionMetrics(metrics) ++ collectCustomMetrics(metrics) - receiver ! TimeSliceMetrics(scaledFrom, scaledTo, allMetrics) + receiver ! TimeSliceMetrics(fromInSeconds, toInSeconds, allMetrics) } } diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelic.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelic.scala index 6c7c11bd..63aa147b 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelic.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelic.scala @@ -18,20 +18,21 @@ package kamon.newrelic import akka.actor._ import scala.concurrent.duration._ import kamon.Kamon -import kamon.metrics.{ TickMetricSnapshotBuffer, TraceMetrics, Metrics } +import kamon.metrics.{ CustomMetric, TickMetricSnapshotBuffer, TraceMetrics, Metrics } import kamon.metrics.Subscriptions.TickMetricSnapshot import akka.actor class NewRelicExtension(system: ExtendedActorSystem) extends Kamon.Extension { val config = system.settings.config.getConfig("kamon.newrelic") - val manager: ActorRef = system.actorOf(Props[NewRelicManager], "kamon-newrelic") + val metricsListener = system.actorOf(Props[NewRelicMetricsListener], "kamon-newrelic") val apdexT: Double = config.getMilliseconds("apdexT") / 1E3 // scale to seconds. - Kamon(Metrics)(system).subscribe(TraceMetrics, "*", manager, permanently = true) + Kamon(Metrics)(system).subscribe(TraceMetrics, "*", metricsListener, permanently = true) + Kamon(Metrics)(system).subscribe(CustomMetric, "*", metricsListener, permanently = true) } -class NewRelicManager extends Actor with ActorLogging { +class NewRelicMetricsListener extends Actor with ActorLogging { log.info("Starting the Kamon(NewRelic) extension") val agent = context.actorOf(Props[Agent], "agent") diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetrics.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetrics.scala index 11312104..0bbc3dcc 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetrics.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetrics.scala @@ -25,8 +25,10 @@ trait WebTransactionMetrics { self: Actor ⇒ def collectWebTransactionMetrics(metrics: Map[MetricGroupIdentity, MetricGroupSnapshot]): Seq[NewRelic.Metric] = { - val apdexBuilder = new ApdexBuilder("Apdex", None, (NewRelic)(context.system).apdexT) - var accumulatedHttpDispatcher: MetricSnapshot = DefaultMetricSnapshot.empty + val apdexBuilder = new ApdexBuilder("Apdex", None, Kamon(NewRelic)(context.system).apdexT) + + // Trace metrics are recorded in nanoseconds. + var accumulatedHttpDispatcher: MetricSnapshotLike = MetricSnapshot(0, Scale.Nano, Vector.empty) val webTransactionMetrics = metrics.collect { case (TraceMetrics(name), groupSnapshot) ⇒ @@ -34,14 +36,15 @@ trait WebTransactionMetrics { groupSnapshot.metrics collect { case (ElapsedTime, snapshot) ⇒ accumulatedHttpDispatcher = accumulatedHttpDispatcher.merge(snapshot) - snapshot.measurementLevels.foreach(level ⇒ apdexBuilder.record(level.value / 1E9D, level.count)) + snapshot.measurements.foreach(level ⇒ + apdexBuilder.record(Scale.convert(snapshot.scale, Scale.Unit, level.value), level.count)) - toNewRelicMetric(s"WebTransaction/Custom/$name", None, snapshot) + toNewRelicMetric(Scale.Unit)(s"WebTransaction/Custom/$name", None, snapshot) } } - val httpDispatcher = toNewRelicMetric("HttpDispatcher", None, accumulatedHttpDispatcher) - val webTransaction = toNewRelicMetric("WebTransaction", None, accumulatedHttpDispatcher) + val httpDispatcher = toNewRelicMetric(Scale.Unit)("HttpDispatcher", None, accumulatedHttpDispatcher) + val webTransaction = toNewRelicMetric(Scale.Unit)("WebTransaction", None, accumulatedHttpDispatcher) Seq(httpDispatcher, webTransaction, apdexBuilder.build) ++ webTransactionMetrics.flatten.toSeq } diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/package.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/package.scala index 76b40748..06059c49 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/package.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/package.scala @@ -16,27 +16,27 @@ package kamon -import kamon.metrics.MetricSnapshot +import kamon.metrics.{ Scale, MetricSnapshotLike } package object newrelic { - def toNewRelicMetric(name: String, scope: Option[String], snapshot: MetricSnapshot): NewRelic.Metric = { + def toNewRelicMetric(scale: Scale)(name: String, scope: Option[String], snapshot: MetricSnapshotLike): NewRelic.Metric = { var total: Double = 0D var sumOfSquares: Double = 0D - val measurementLevels = snapshot.measurementLevels.iterator + val measurementLevels = snapshot.measurements.iterator while (measurementLevels.hasNext) { val level = measurementLevels.next() // NewRelic metrics need to be scaled to seconds. - val scaledValue = level.value / 1E9D + val scaledValue = Scale.convert(snapshot.scale, scale, level.value) total += scaledValue sumOfSquares += scaledValue * scaledValue } - val scaledMin = snapshot.min / 1E9D - val scaledMax = snapshot.max / 1E9D + val scaledMin = Scale.convert(snapshot.scale, scale, snapshot.min) + val scaledMax = Scale.convert(snapshot.scale, scale, snapshot.max) NewRelic.Metric(name, scope, snapshot.numberOfMeasurements, total, total, scaledMin, scaledMax, sumOfSquares) } |