From b260e19fac6fc85822c53abc4688e90b6166a0af Mon Sep 17 00:00:00 2001 From: Diego Date: Wed, 30 Apr 2014 00:35:07 -0300 Subject: ! core: new counter recorder based on LongAdder --- .../ActorMessagePassingTracing.scala | 13 +++++++- .../main/scala/kamon/metrics/ActorMetrics.scala | 17 +++++----- .../metrics/instruments/CounterRecorder.scala | 36 ++++++++++++++++++++++ 3 files changed, 58 insertions(+), 8 deletions(-) create mode 100644 kamon-core/src/main/scala/kamon/metrics/instruments/CounterRecorder.scala (limited to 'kamon-core/src/main/scala') diff --git a/kamon-core/src/main/scala/akka/instrumentation/ActorMessagePassingTracing.scala b/kamon-core/src/main/scala/akka/instrumentation/ActorMessagePassingTracing.scala index e52a66b2..ae9d20f6 100644 --- a/kamon-core/src/main/scala/akka/instrumentation/ActorMessagePassingTracing.scala +++ b/kamon-core/src/main/scala/akka/instrumentation/ActorMessagePassingTracing.scala @@ -24,6 +24,7 @@ import kamon.metrics.{ ActorMetrics, Metrics } import kamon.Kamon import kamon.metrics.ActorMetrics.ActorMetricRecorder import java.util.concurrent.atomic.AtomicInteger +import kamon.metrics.instruments.Counter @Aspect class BehaviourInvokeTracing { @@ -32,7 +33,7 @@ class BehaviourInvokeTracing { def actorCellCreation(cell: ActorCell, system: ActorSystem, ref: ActorRef, props: Props, dispatcher: MessageDispatcher, parent: ActorRef): Unit = {} @After("actorCellCreation(cell, system, ref, props, dispatcher, parent)") - def afterCreation(cell: ActorCell, system: ActorSystem, ref: ActorRef, props: Props, dispatcher: MessageDispatcher, parent: ActorRef): Unit = { + def afterCreation(cell: ActorCellMetrics, system: ActorSystem, ref: ActorRef, props: Props, dispatcher: MessageDispatcher, parent: ActorRef): Unit = { val metricsExtension = Kamon(Metrics)(system) val metricIdentity = ActorMetrics(ref.path.elements.mkString("/")) val cellWithMetrics = cell.asInstanceOf[ActorCellMetrics] @@ -89,6 +90,16 @@ class BehaviourInvokeTracing { val cellWithMetrics = cell.asInstanceOf[ActorCellMetrics] cellWithMetrics.actorMetricsRecorder.map(p ⇒ Kamon(Metrics)(cell.system).unregister(cellWithMetrics.metricIdentity)) } + + @Pointcut("execution(* akka.actor.ActorCell.handleInvokeFailure(..)) && this(cell)") + def actorInvokeFailure(cell: ActorCellMetrics): Unit = {} + + @Before("actorInvokeFailure(cell)") + def beforeInvokeFailure(cell: ActorCellMetrics): Unit = { + cell.actorMetricsRecorder.map { + am ⇒ am.errorCounter.record(1L) + } + } } trait ActorCellMetrics { diff --git a/kamon-core/src/main/scala/kamon/metrics/ActorMetrics.scala b/kamon-core/src/main/scala/kamon/metrics/ActorMetrics.scala index bd0d628b..c703d589 100644 --- a/kamon-core/src/main/scala/kamon/metrics/ActorMetrics.scala +++ b/kamon-core/src/main/scala/kamon/metrics/ActorMetrics.scala @@ -1,6 +1,6 @@ /* * ========================================================================================= - * Copyright © 2013 the kamon project + * Copyright © 2013-2014 the kamon project * * 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 @@ -17,7 +17,7 @@ package kamon.metrics import com.typesafe.config.Config -import kamon.metrics.instruments.ContinuousHdrRecorder +import kamon.metrics.instruments.{ CounterRecorder, ContinuousHdrRecorder } import org.HdrHistogram.HdrRecorder case class ActorMetrics(name: String) extends MetricGroupIdentity { @@ -30,22 +30,24 @@ object ActorMetrics extends MetricGroupCategory { case object ProcessingTime extends MetricIdentity { val name, tag = "processing-time" } case object MailboxSize extends MetricIdentity { val name, tag = "mailbox-size" } case object TimeInMailbox extends MetricIdentity { val name, tag = "time-in-mailbox" } + case object ErrorCounter extends MetricIdentity { val name, tag = "errors" } - case class ActorMetricRecorder(processingTime: MetricRecorder, mailboxSize: MetricRecorder, timeInMailbox: MetricRecorder) + case class ActorMetricRecorder(processingTime: MetricRecorder, mailboxSize: MetricRecorder, timeInMailbox: MetricRecorder, errorCounter: MetricRecorder) extends MetricGroupRecorder { def collect: MetricGroupSnapshot = { - ActorMetricSnapshot(processingTime.collect(), mailboxSize.collect(), timeInMailbox.collect()) + ActorMetricSnapshot(processingTime.collect(), mailboxSize.collect(), timeInMailbox.collect(), errorCounter.collect()) } } - case class ActorMetricSnapshot(processingTime: MetricSnapshotLike, mailboxSize: MetricSnapshotLike, timeInMailbox: MetricSnapshotLike) + case class ActorMetricSnapshot(processingTime: MetricSnapshotLike, mailboxSize: MetricSnapshotLike, timeInMailbox: MetricSnapshotLike, errorCounter: MetricSnapshotLike) extends MetricGroupSnapshot { val metrics: Map[MetricIdentity, MetricSnapshotLike] = Map( (ProcessingTime -> processingTime), (MailboxSize -> mailboxSize), - (TimeInMailbox -> timeInMailbox)) + (TimeInMailbox -> timeInMailbox), + (ErrorCounter -> errorCounter)) } val Factory = new MetricGroupFactory { @@ -61,7 +63,8 @@ object ActorMetrics extends MetricGroupCategory { new ActorMetricRecorder( HdrRecorder(processingTimeConfig.highestTrackableValue, processingTimeConfig.significantValueDigits, Scale.Nano), ContinuousHdrRecorder(mailboxSizeConfig.highestTrackableValue, mailboxSizeConfig.significantValueDigits, Scale.Unit), - HdrRecorder(timeInMailboxConfig.highestTrackableValue, timeInMailboxConfig.significantValueDigits, Scale.Nano)) + HdrRecorder(timeInMailboxConfig.highestTrackableValue, timeInMailboxConfig.significantValueDigits, Scale.Nano), + CounterRecorder()) } } } diff --git a/kamon-core/src/main/scala/kamon/metrics/instruments/CounterRecorder.scala b/kamon-core/src/main/scala/kamon/metrics/instruments/CounterRecorder.scala new file mode 100644 index 00000000..1ab743d2 --- /dev/null +++ b/kamon-core/src/main/scala/kamon/metrics/instruments/CounterRecorder.scala @@ -0,0 +1,36 @@ +package kamon.metrics.instruments +/* + * ========================================================================================= + * Copyright © 2013-2014 the kamon project + * + * 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. + * ========================================================================================= + */ + +import kamon.metrics._ +import kamon.metrics.MetricSnapshot.Measurement + +import jsr166e.LongAdder + +class CounterRecorder extends MetricRecorder { + private val counter = new LongAdder + + def record(value: Long): Unit = counter.add(value) + + def collect(): MetricSnapshotLike = { + val sum = counter.sumThenReset() + MetricSnapshot(InstrumentTypes.Counter, sum, Scale.Unit, Vector(Measurement(1, sum))) + } +} + +object CounterRecorder { + def apply() = new CounterRecorder +} \ No newline at end of file -- cgit v1.2.3