aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Parra <diegolparra@gmail.com>2018-11-30 02:25:37 -0300
committerGitHub <noreply@github.com>2018-11-30 02:25:37 -0300
commit55e052f0da580296c9b273612c50c57f8ad4206d (patch)
tree8d89a849cee4dc039073db2223efdff8fce855aa
parentfe367087830db4dd147e5d92fb6bf689114871dc (diff)
parentb068f55387e0cfe92b3ec403132d5c851d51eb00 (diff)
downloadKamon-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.scala62
-rw-r--r--kamon-core/src/main/scala/kamon/instrumentation/MetricGroup.scala64
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