aboutsummaryrefslogtreecommitdiff
path: root/kamon-newrelic
diff options
context:
space:
mode:
authorIvan Topolnjak <ivantopo@gmail.com>2014-02-05 01:12:34 -0300
committerIvan Topolnjak <ivantopo@gmail.com>2014-02-05 01:12:34 -0300
commit522a12c90788c402a364407e146d302e6519a3da (patch)
tree3603c2172a8048b5f13c923d85e14b4f8490ca53 /kamon-newrelic
parent57e433c07a271b4e5e4159500cdc828cd7bb6a83 (diff)
downloadKamon-522a12c90788c402a364407e146d302e6519a3da.tar.gz
Kamon-522a12c90788c402a364407e146d302e6519a3da.tar.bz2
Kamon-522a12c90788c402a364407e146d302e6519a3da.zip
kamon-newrelic now uses the subscription protocol to report metrics to NewRelic
Diffstat (limited to 'kamon-newrelic')
-rw-r--r--kamon-newrelic/src/main/resources/reference.conf6
-rw-r--r--kamon-newrelic/src/main/scala/kamon/newrelic/MetricTranslator.scala4
-rw-r--r--kamon-newrelic/src/main/scala/kamon/newrelic/NewRelic.scala3
-rw-r--r--kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetrics.scala43
4 files changed, 47 insertions, 9 deletions
diff --git a/kamon-newrelic/src/main/resources/reference.conf b/kamon-newrelic/src/main/resources/reference.conf
index dacabe41..ee0acdc3 100644
--- a/kamon-newrelic/src/main/resources/reference.conf
+++ b/kamon-newrelic/src/main/resources/reference.conf
@@ -1,9 +1,7 @@
-akka {
- extensions = ["kamon.newrelic.NewRelic"]
-}
-
kamon {
newrelic {
+ apdexT = 1 second
+
app-name = "Kamon[Development]"
license-key = 2e24765acb032cb9e7207013b5ba3e2ab7d2d75c
}
diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/MetricTranslator.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/MetricTranslator.scala
index 39177e30..c3438df5 100644
--- a/kamon-newrelic/src/main/scala/kamon/newrelic/MetricTranslator.scala
+++ b/kamon-newrelic/src/main/scala/kamon/newrelic/MetricTranslator.scala
@@ -24,9 +24,11 @@ class MetricTranslator(receiver: ActorRef) extends Actor with WebTransactionMetr
def receive = {
case TickMetricSnapshot(from, to, metrics) =>
+ val scaledFrom = (from / 1E3).toInt
+ val scaledTo = (to / 1E3).toInt
val allMetrics = collectWebTransactionMetrics(metrics)
- receiver ! TimeSliceMetrics(from, to, allMetrics)
+ receiver ! TimeSliceMetrics(scaledFrom, scaledTo, allMetrics)
}
}
diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelic.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelic.scala
index ef2de343..92191842 100644
--- a/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelic.scala
+++ b/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelic.scala
@@ -24,7 +24,10 @@ 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 apdexT: Double = config.getMilliseconds("apdexT") / 1E3 // scale to seconds.
Kamon(Metrics)(system).subscribe(TraceMetrics, "*", manager, permanently = true)
}
diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetrics.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetrics.scala
index 7fe5793c..31a3669d 100644
--- a/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetrics.scala
+++ b/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetrics.scala
@@ -16,18 +16,53 @@
package kamon.newrelic
-import kamon.metrics.{ TraceMetrics, MetricGroupSnapshot, MetricGroupIdentity }
+import kamon.metrics._
import kamon.metrics.TraceMetrics.ElapsedTime
+import akka.actor.Actor
+import kamon.Kamon
trait WebTransactionMetrics {
- def collectWebTransactionMetrics(metrics: Map[MetricGroupIdentity, MetricGroupSnapshot]): List[NewRelic.Metric] = {
+ 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 webTransactionMetrics = metrics.collect {
case (TraceMetrics(name), groupSnapshot) ⇒
+
groupSnapshot.metrics collect {
- case (ElapsedTime, snapshot) => toNewRelicMetric("HttpDispatcher", None, snapshot)
+ case (ElapsedTime, snapshot) =>
+ accumulatedHttpDispatcher = accumulatedHttpDispatcher.merge(snapshot)
+ snapshot.measurementLevels.foreach(level => apdexBuilder.record(level.value / 1E9D, level.count))
+
+ toNewRelicMetric(s"WebTransaction/Custom/$name", None, snapshot)
}
}
- webTransactionMetrics.flatten.toList
+ val httpDispatcher = toNewRelicMetric("HttpDispatcher", None, accumulatedHttpDispatcher)
+ val webTransaction = toNewRelicMetric("WebTransaction", None, accumulatedHttpDispatcher)
+
+ Seq(httpDispatcher, webTransaction, apdexBuilder.build) ++ webTransactionMetrics.flatten.toSeq
}
}
+
+class ApdexBuilder(name: String, scope: Option[String], apdexT: Double) {
+ val frustratingThreshold = 4 * apdexT
+
+ var satisfying = 0L
+ var tolerating = 0L
+ var frustrating = 0L
+
+ def record(duration: Double, count: Long): Unit =
+ if(duration <= apdexT)
+ satisfying += count
+ else
+ if(duration <= frustratingThreshold)
+ tolerating += count
+ else
+ frustrating += count
+
+ // NewRelic reuses the same metric structure for recording the Apdex.. weird, but that's how it works.
+ def build: NewRelic.Metric = NewRelic.Metric(name, scope, satisfying, tolerating, frustrating, apdexT, apdexT, 0)
+}