diff options
author | Diego Parra <diegolparra@gmail.com> | 2018-11-30 02:25:37 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-11-30 02:25:37 -0300 |
commit | 55e052f0da580296c9b273612c50c57f8ad4206d (patch) | |
tree | 8d89a849cee4dc039073db2223efdff8fce855aa | |
parent | fe367087830db4dd147e5d92fb6bf689114871dc (diff) | |
parent | b068f55387e0cfe92b3ec403132d5c851d51eb00 (diff) | |
download | Kamon-55e052f0da580296c9b273612c50c57f8ad4206d.tar.gz Kamon-55e052f0da580296c9b273612c50c57f8ad4206d.tar.bz2 Kamon-55e052f0da580296c9b273612c50c57f8ad4206d.zip |
Merge pull request #561 from ivantopo/metric-group
add a simple metric group utility for instrumentations
-rw-r--r-- | kamon-core-tests/src/test/scala/kamon/instrumentation/MetricGroupSpec.scala | 62 | ||||
-rw-r--r-- | kamon-core/src/main/scala/kamon/instrumentation/MetricGroup.scala | 64 |
2 files changed, 126 insertions, 0 deletions
diff --git a/kamon-core-tests/src/test/scala/kamon/instrumentation/MetricGroupSpec.scala b/kamon-core-tests/src/test/scala/kamon/instrumentation/MetricGroupSpec.scala new file mode 100644 index 00000000..0b823bc4 --- /dev/null +++ b/kamon-core-tests/src/test/scala/kamon/instrumentation/MetricGroupSpec.scala @@ -0,0 +1,62 @@ +package kamon.instrumentation + +import kamon.Kamon +import kamon.testkit.MetricInspection +import org.scalatest.{Matchers, WordSpec} + +class MetricGroupSpec extends WordSpec with MetricInspection with Matchers { + + "a Metric Group" should { + "register metrics with common tags and remove them when cleaning up" in { + val group = new CommonTagsOnly(Map("type" -> "common")) + + Counter.valuesForTag("type") should contain only("common") + Gauge.valuesForTag("type") should contain only("common") + Histogram.valuesForTag("type") should contain only("common") + RangeSampler.valuesForTag("type") should contain only("common") + + group.cleanup() + + Counter.valuesForTag("type") shouldBe empty + Gauge.valuesForTag("type") shouldBe empty + Histogram.valuesForTag("type") shouldBe empty + RangeSampler.valuesForTag("type") shouldBe empty + } + + "override common tags with tags supplied to the tag method" in { + val group = new MixedTags(Map("type" -> "basic")) + + Counter.valuesForTag("type") should contain only("basic") + Gauge.valuesForTag("type") should contain only("simple") + Histogram.valuesForTag("type") should contain only("tuple") + RangeSampler.valuesForTag("type") should contain only("map") + + group.cleanup() + + Counter.valuesForTag("type") shouldBe empty + Gauge.valuesForTag("type") shouldBe empty + Histogram.valuesForTag("type") shouldBe empty + RangeSampler.valuesForTag("type") shouldBe empty + } + } + + + val Counter = Kamon.counter("metric.group.counter") + val Gauge = Kamon.gauge("metric.group.gauge") + val Histogram = Kamon.histogram("metric.group.histogram") + val RangeSampler = Kamon.rangeSampler("metric.group.range-sampler") + + class CommonTagsOnly(tags: Map[String, String]) extends MetricGroup(tags) { + val counter = tag(Counter) + val gauge = tag(Gauge) + val histogram = tag(Histogram) + val rangeSampler = tag(RangeSampler) + } + + class MixedTags(tags: Map[String, String]) extends MetricGroup(tags) { + val counter = tag(Counter) + val gauge = tag(Gauge, "type", "simple") + val histogram = tag(Histogram, "type" -> "tuple") + val rangeSampler = tag(RangeSampler, Map("type" -> "map")) + } +} diff --git a/kamon-core/src/main/scala/kamon/instrumentation/MetricGroup.scala b/kamon-core/src/main/scala/kamon/instrumentation/MetricGroup.scala new file mode 100644 index 00000000..b27c6f54 --- /dev/null +++ b/kamon-core/src/main/scala/kamon/instrumentation/MetricGroup.scala @@ -0,0 +1,64 @@ +package kamon +package instrumentation + +import kamon.metric.Metric +import scala.collection.JavaConverters._ + +/** + * Utility class that helps to apply the same tags to several metrics and keep track of all the tagged instruments so + * that they can later be cleaned up. This becomes specially handy when tracking several metrics that are related to + * each other and should be created and removed together, for example, when tracking metrics on a thread pool you will + * want to register several metrics related to one particular thread pool with a number of common tags and then remove + * all of those metrics once the thread pool is shut down. + * + * @param commonTags Tags to be applied to all metrics returned by calls to the tag method. + */ +abstract class MetricGroup(commonTags: Map[String, String]) { + private var _groupInstruments = List.empty[(Metric[_], Map[String, String])] + + /** + * Tag a metric using the common tags. + */ + def tag[T](metric: Metric[T]): T = + register(metric, commonTags) + + /** + * Tag a metric using the supplied key/value pair and the common tags. + */ + def tag[T](metric: Metric[T], key: String, value: String): T = + register(metric, commonTags ++ Map(key -> value)) + + /** + * Tag a metric using the supplied tuple and the common tags. + */ + def tag[T](metric: Metric[T], tag: (String, String)): T = + register(metric, commonTags + tag) + + /** + * Tag a metric using the supplied tags map and the common tags. + */ + def tag[T](metric: Metric[T], tags: Map[String, String]): T = + register(metric, commonTags ++ tags) + + /** + * Tag a metric using the supplied tags map and the common tags. + */ + def tag[T](metric: Metric[T], tags: java.util.Map[String, String]): T = + register(metric, commonTags ++ tags.asScala.toMap) + + + private def register[T](metric: Metric[T], tags: Map[String, String]): T = synchronized { + _groupInstruments = (metric -> tags) :: _groupInstruments + metric.refine(tags) + } + + + /** + * Removes all metrics that were tagged by this group. + */ + def cleanup(): Unit = synchronized { + _groupInstruments foreach { + case (metric, tags) => metric.remove(tags) + } + } +}
\ No newline at end of file |