diff options
author | Ivan Topolnjak <ivantopo@gmail.com> | 2015-05-09 15:36:16 +0200 |
---|---|---|
committer | Ivan Topolnjak <ivantopo@gmail.com> | 2015-05-09 15:36:16 +0200 |
commit | 76f503b8f954e1b149bea3adb8927704f7095876 (patch) | |
tree | 59cabc6055e855c006115c5847a85f879dc36dd9 /kamon-newrelic/src/main/scala | |
parent | 520895a6a9a6b48b83efe01cf289708efd045b42 (diff) | |
parent | d69f14710b1d933d58412edd63b465b13a09a9d0 (diff) | |
download | Kamon-76f503b8f954e1b149bea3adb8927704f7095876.tar.gz Kamon-76f503b8f954e1b149bea3adb8927704f7095876.tar.bz2 Kamon-76f503b8f954e1b149bea3adb8927704f7095876.zip |
Merge branch 'master' into release-legacy-akka-2.2
Conflicts:
kamon-akka/src/test/scala/kamon/akka/RouterMetricsSpec.scala
kamon-akka/src/test/scala/kamon/akka/instrumentation/ActorCellInstrumentationSpec.scala
kamon-akka/src/test/scala/kamon/akka/instrumentation/AskPatternInstrumentationSpec.scala
kamon-core/src/test/scala/kamon/metric/TraceMetricsSpec.scala
kamon-core/src/test/scala/kamon/testkit/BaseKamonSpec.scala
kamon-play/src/main/scala/kamon/play/action/KamonTraceActions.scala
kamon-play/src/main/scala/kamon/play/instrumentation/RequestInstrumentation.scala
kamon-play/src/main/scala/kamon/play/instrumentation/WSInstrumentation.scala
kamon-play/src/test/scala/kamon/play/RequestInstrumentationSpec.scala
project/Dependencies.scala
project/Settings.scala
Diffstat (limited to 'kamon-newrelic/src/main/scala')
6 files changed, 49 insertions, 42 deletions
diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/Agent.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/Agent.scala index 91ccd547..66ca5578 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/Agent.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/Agent.scala @@ -132,9 +132,11 @@ object AgentSettings { // Name has the format of 'pid'@'host' val runtimeName = ManagementFactory.getRuntimeMXBean.getName.split('@') val newRelicConfig = config.getConfig("kamon.newrelic") + val licenseKey = newRelicConfig.getString("license-key") + assert(licenseKey != "<put-your-key-here>", "You forgot to include your New Relic license key in the configuration settings!") AgentSettings( - newRelicConfig.getString("license-key"), + licenseKey, newRelicConfig.getString("app-name"), runtimeName(1), runtimeName(0).toInt, diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala index 3b1b8cb3..6919a967 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/CustomMetricExtractor.scala @@ -16,17 +16,22 @@ package kamon.newrelic -import kamon.metric.{ UserMetricsExtensionImpl, EntitySnapshot, Entity } +import kamon.metric.{ EntitySnapshot, Entity } import kamon.metric.instrument.CollectionContext object CustomMetricExtractor extends MetricExtractor { def extract(settings: AgentSettings, collectionContext: CollectionContext, metrics: Map[Entity, EntitySnapshot]): Map[MetricID, MetricData] = { - metrics.get(UserMetricsExtensionImpl.UserMetricEntity).map { allUserMetrics ⇒ - allUserMetrics.metrics.map { - case (key, snapshot) ⇒ Metric(snapshot, key.unitOfMeasurement, s"Custom/${key.name}", None) - } + def onlySimpleMetrics(kv: (Entity, EntitySnapshot)): Boolean = + kamon.metric.SingleInstrumentEntityRecorder.AllCategories.contains(kv._1.category) - } getOrElse (Map.empty) + def toNewRelicMetric(kv: (Entity, EntitySnapshot)): (MetricID, MetricData) = { + val (entity, entitySnapshot) = kv + val (metricKey, instrumentSnapshot) = entitySnapshot.metrics.head + + Metric(instrumentSnapshot, metricKey.unitOfMeasurement, s"Custom/${entity.name}", None) + } + + metrics.filter(onlySimpleMetrics).map(toNewRelicMetric) } } diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/Metric.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/Metric.scala index 20204b79..6fb645f5 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/Metric.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/Metric.scala @@ -18,9 +18,9 @@ case class MetricData(callCount: Long, total: Double, totalExclusive: Double, mi object Metric { - def scaleFunction(uom: UnitOfMeasurement): Long ⇒ Double = uom match { + def scaleFunction(uom: UnitOfMeasurement): Double ⇒ Double = uom match { case time: Time ⇒ time.scale(Time.Seconds) - case other ⇒ _.toDouble + case other ⇒ a ⇒ a } def apply(snapshot: InstrumentSnapshot, snapshotUnit: UnitOfMeasurement, name: String, scope: Option[String]): Metric = { diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/MetricReporter.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/MetricReporter.scala index 7ee7d1e6..8de493b2 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/MetricReporter.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/MetricReporter.scala @@ -90,6 +90,7 @@ class MetricReporter(settings: AgentSettings) extends Actor with ActorLogging wi def subscribeToMetrics(): Unit = { metricsExtension.subscribe("trace", "*", metricsSubscriber, permanently = true) + metricsExtension.subscribe("trace-segment", "*", metricsSubscriber, permanently = true) metricsExtension.subscribe("user-metrics", "*", metricsSubscriber, permanently = true) } } diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelicErrorLogger.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelicErrorLogger.scala index 7f56d931..2af94c22 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelicErrorLogger.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/NewRelicErrorLogger.scala @@ -22,7 +22,7 @@ import akka.actor.{ Actor, ActorLogging } import akka.event.Logging.{ Error, InitializeLogger, LoggerInitialized } import com.newrelic.api.agent.{ NewRelic ⇒ NR } import kamon.trace.TraceLocal.HttpContextKey -import kamon.trace.{ TraceContext, TraceLocal, TraceContextAware } +import kamon.trace.{ Tracer, TraceLocal, TraceContextAware } trait CustomParamsSupport { this: NewRelicErrorLogger ⇒ @@ -64,7 +64,7 @@ class NewRelicErrorLogger extends Actor with ActorLogging with CustomParamsSuppo //Really ugly, but temporal hack until next release... def runInFakeTransaction[T](thunk: ⇒ T): T = { val oldName = Thread.currentThread.getName - Thread.currentThread.setName(TraceContext.currentContext.name) + Thread.currentThread.setName(Tracer.currentContext.name) try thunk finally Thread.currentThread.setName(oldName) } }
\ No newline at end of file diff --git a/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetricExtractor.scala b/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetricExtractor.scala index d0144f4b..7e057407 100644 --- a/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetricExtractor.scala +++ b/kamon-newrelic/src/main/scala/kamon/newrelic/WebTransactionMetricExtractor.scala @@ -17,6 +17,7 @@ package kamon.newrelic import kamon.metric.{ EntitySnapshot, Entity } +import kamon.trace.SegmentCategory import scala.collection.mutable import kamon.metric.instrument.{ Time, CollectionContext, Histogram } @@ -35,62 +36,60 @@ object WebTransactionMetricExtractor extends MetricExtractor { val externalScopedByHostAndLibrarySnapshots = mutable.Map.empty[(String, String, String), List[Histogram.Snapshot]] val transactionMetrics = metrics.filterKeys(_.category == "trace").map { - case (entity: Entity, es: EntitySnapshot) ⇒ - // Trace metrics only have elapsed-time and segments and all of them are Histograms. - es.histograms.foreach { - case (key, segmentSnapshot) if key.metadata.get("category").filter(_ == "http-client").nonEmpty ⇒ - val library = key.metadata("library") - accumulatedExternalServices = accumulatedExternalServices.merge(segmentSnapshot, collectionContext) - - // Accumulate externals by host - externalByHostSnapshots.update(key.name, segmentSnapshot :: externalByHostSnapshots.getOrElse(key.name, Nil)) + case (entity, entitySnapshot) ⇒ + val elapsedTime = entitySnapshot.histogram("elapsed-time").get + accumulatedHttpDispatcher = accumulatedHttpDispatcher.merge(elapsedTime, collectionContext) + elapsedTime.recordsIterator.foreach { record ⇒ + apdexBuilder.record(Time.Nanoseconds.scale(Time.Seconds)(record.level), record.count) + } - // Accumulate externals by host and library - externalByHostAndLibrarySnapshots.update((key.name, library), - segmentSnapshot :: externalByHostAndLibrarySnapshots.getOrElse((key.name, library), Nil)) + Metric(elapsedTime, Time.Nanoseconds, "WebTransaction/Custom/" + entity.name, None) + } - // Accumulate externals by host and library, including the transaction as scope. - externalScopedByHostAndLibrarySnapshots.update((key.name, library, entity.name), - segmentSnapshot :: externalScopedByHostAndLibrarySnapshots.getOrElse((key.name, library, entity.name), Nil)) + // Accumulate all segment metrics + metrics.filterKeys(_.category == "trace-segment").map { + case (entity, entitySnapshot) if entity.tags("category") == SegmentCategory.HttpClient ⇒ + val library = entity.tags("library") + val trace = entity.tags("trace") + val elapsedTime = entitySnapshot.histogram("elapsed-time").get - case otherSegments ⇒ + accumulatedExternalServices = accumulatedExternalServices.merge(elapsedTime, collectionContext) - } + // Accumulate externals by host + externalByHostSnapshots.update(entity.name, elapsedTime :: externalByHostSnapshots.getOrElse(entity.name, Nil)) - es.histograms.collect { - case (key, elapsedTime) if key.name == "elapsed-time" ⇒ - accumulatedHttpDispatcher = accumulatedHttpDispatcher.merge(elapsedTime, collectionContext) - elapsedTime.recordsIterator.foreach { record ⇒ - apdexBuilder.record(Time.Nanoseconds.scale(Time.Seconds)(record.level), record.count) - } + // Accumulate externals by host and library + externalByHostAndLibrarySnapshots.update((entity.name, library), + elapsedTime :: externalByHostAndLibrarySnapshots.getOrElse((entity.name, library), Nil)) - Metric(elapsedTime, key.unitOfMeasurement, "WebTransaction/Custom/" + entity.name, None) - } - } flatten + // Accumulate externals by host and library, including the transaction as scope. + externalScopedByHostAndLibrarySnapshots.update((entity.name, library, trace), + elapsedTime :: externalScopedByHostAndLibrarySnapshots.getOrElse((entity.name, library, trace), Nil)) + } - val httpDispatcher = Metric(accumulatedHttpDispatcher, Time.Seconds, "HttpDispatcher", None) + val httpDispatcher = Metric(accumulatedHttpDispatcher, Time.Nanoseconds, "HttpDispatcher", None) val webTransaction = httpDispatcher.copy(MetricID("WebTransaction", None)) val webTransactionTotal = httpDispatcher.copy(MetricID("WebTransactionTotalTime", None)) - val externalAllWeb = Metric(accumulatedExternalServices, Time.Seconds, "External/allWeb", None) + val externalAllWeb = Metric(accumulatedExternalServices, Time.Nanoseconds, "External/allWeb", None) val externalAll = externalAllWeb.copy(MetricID("External/all", None)) val externalByHost = externalByHostSnapshots.map { case (host, snapshots) ⇒ val mergedSnapshots = snapshots.foldLeft(Histogram.Snapshot.empty)(_.merge(_, collectionContext)) - Metric(mergedSnapshots, Time.Seconds, s"External/$host/all", None) + Metric(mergedSnapshots, Time.Nanoseconds, s"External/$host/all", None) } val externalByHostAndLibrary = externalByHostAndLibrarySnapshots.map { case ((host, library), snapshots) ⇒ val mergedSnapshots = snapshots.foldLeft(Histogram.Snapshot.empty)(_.merge(_, collectionContext)) - Metric(mergedSnapshots, Time.Seconds, s"External/$host/$library", None) + Metric(mergedSnapshots, Time.Nanoseconds, s"External/$host/$library", None) } val externalScopedByHostAndLibrary = externalScopedByHostAndLibrarySnapshots.map { case ((host, library, traceName), snapshots) ⇒ val mergedSnapshots = snapshots.foldLeft(Histogram.Snapshot.empty)(_.merge(_, collectionContext)) - Metric(mergedSnapshots, Time.Seconds, s"External/$host/$library", Some("WebTransaction/Custom/" + traceName)) + Metric(mergedSnapshots, Time.Nanoseconds, s"External/$host/$library", Some("WebTransaction/Custom/" + traceName)) } Map(httpDispatcher, webTransaction, webTransactionTotal, externalAllWeb, externalAll, apdexBuilder.build) ++ |