Skip to content

Commit e66b02b

Browse files
committed
utility class to keep track of instrument groups
1 parent a005d34 commit e66b02b

File tree

4 files changed

+130
-2
lines changed

4 files changed

+130
-2
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package kamon.metric
2+
3+
import kamon.Kamon
4+
import kamon.tag.TagSet
5+
import kamon.testkit.MetricInspection
6+
import org.scalatest.{Matchers, WordSpec}
7+
8+
class InstrumentGroupSpec extends WordSpec with MetricInspection.Syntax with Matchers {
9+
10+
"an Instrument Group" should {
11+
"register instruments with common tags and remove them when cleaning up" in {
12+
val group = new CommonTagsOnly(TagSet.of("type", "common"))
13+
14+
Counter.tagValues("type") should contain only("common")
15+
Gauge.tagValues("type") should contain only("common")
16+
Histogram.tagValues("type") should contain only("common")
17+
RangeSampler.tagValues("type") should contain only("common")
18+
19+
group.remove()
20+
21+
Counter.tagValues("type") shouldBe empty
22+
Gauge.tagValues("type") shouldBe empty
23+
Histogram.tagValues("type") shouldBe empty
24+
RangeSampler.tagValues("type") shouldBe empty
25+
}
26+
27+
"override common tags with tags supplied to the register method" in {
28+
val group = new MixedTags(TagSet.of("type", "basic"))
29+
30+
Counter.tagValues("type") should contain only("basic")
31+
Gauge.tagValues("type") should contain only("simple")
32+
Histogram.tagValues("type") should contain only("42")
33+
RangeSampler.tagValues("type") should contain only("true")
34+
35+
group.remove()
36+
37+
Counter.tagValues("type") shouldBe empty
38+
Gauge.tagValues("type") shouldBe empty
39+
Histogram.tagValues("type") shouldBe empty
40+
RangeSampler.tagValues("type") shouldBe empty
41+
}
42+
}
43+
44+
45+
val Counter = Kamon.counter("metric.group.counter")
46+
val Gauge = Kamon.gauge("metric.group.gauge")
47+
val Histogram = Kamon.histogram("metric.group.histogram")
48+
val RangeSampler = Kamon.rangeSampler("metric.group.range-sampler")
49+
50+
class CommonTagsOnly(tags: TagSet) extends InstrumentGroup(tags) {
51+
val counter = register(Counter)
52+
val gauge = register(Gauge)
53+
val histogram = register(Histogram)
54+
val rangeSampler = register(RangeSampler)
55+
}
56+
57+
class MixedTags(tags: TagSet) extends InstrumentGroup(tags) {
58+
val counter = register(Counter)
59+
val gauge = register(Gauge, "type", "simple")
60+
val histogram = register(Histogram, "type", 42)
61+
val rangeSampler = register(RangeSampler, "type", true)
62+
}
63+
}

kamon-core/src/main/scala/kamon/metric/Instrument.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import kamon.tag.TagSet
88
/**
99
* Base user-facing API for all metric instruments in Kamon.
1010
*/
11-
trait Instrument[Inst, Sett <: Metric.Settings] extends Tagging[Inst] {
11+
trait Instrument[Inst <: Instrument[Inst, Sett], Sett <: Metric.Settings] extends Tagging[Inst] {
1212

1313
/**
1414
* Returns the metric to which this instrument belongs.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package kamon
2+
package metric
3+
4+
import kamon.tag.TagSet
5+
6+
/**
7+
* Utility class for handling groups of instruments that should be created and removed together. This becomes specially
8+
* handy when using several instruments to track different aspects of the same component. For example, when tracking
9+
* metrics on a thread pool you will want to request several instruments to track different aspects: the pool size, the
10+
* number of submitted tasks, the queue size and so on, and all of those instruments should share common tags that are
11+
* specific to the instrumented thread pool; additionally, once said thread pool is shutdown, all of those instruments
12+
* should be removed together. This class makes it simpler to keep track of all of those related instruments and remove
13+
* them together when necessary.
14+
*/
15+
abstract class InstrumentGroup(val commonTags: TagSet) {
16+
private var _groupInstruments = List.empty[Instrument[_, _]]
17+
18+
/**
19+
* Registers and returns an instrument of the provided metric with the common tags.
20+
*/
21+
def register[Inst <: Instrument[Inst, Sett], Sett <: Metric.Settings](metric: Metric[Inst, Sett]): Inst =
22+
registerInstrument(metric, commonTags)
23+
24+
/**
25+
* Registers and returns an instrument of the provided metric with the common tags and the additionally provided
26+
* key/value pair.
27+
*/
28+
def register[Inst <: Instrument[Inst, Sett], Sett <: Metric.Settings](metric: Metric[Inst, Sett], key: String, value: String): Inst =
29+
registerInstrument(metric, commonTags.withTag(key, value))
30+
31+
/**
32+
* Registers and returns an instrument of the provided metric with the common tags and the additionally provided
33+
* key/value pair.
34+
*/
35+
def register[Inst <: Instrument[Inst, Sett], Sett <: Metric.Settings](metric: Metric[Inst, Sett], key: String, value: Long): Inst =
36+
registerInstrument(metric, commonTags.withTag(key, value))
37+
38+
/**
39+
* Registers and returns an instrument of the provided metric with the common tags and the additionally provided
40+
* key/value pair.
41+
*/
42+
def register[Inst <: Instrument[Inst, Sett], Sett <: Metric.Settings](metric: Metric[Inst, Sett], key: String, value: Boolean): Inst =
43+
registerInstrument(metric, commonTags.withTag(key, value))
44+
45+
/**
46+
* Registers and returns an instrument of the provided metric with the common tags and the additionally provided tags.
47+
*/
48+
def register[Inst <: Instrument[Inst, Sett], Sett <: Metric.Settings](metric: Metric[Inst, Sett], extraTags: TagSet): Inst =
49+
registerInstrument(metric, commonTags.withTags(extraTags))
50+
51+
52+
private def registerInstrument[Inst <: Instrument[Inst, Sett], Sett <: Metric.Settings](metric: Metric[Inst, Sett],
53+
tags: TagSet): Inst = synchronized {
54+
val instrument = metric.withTags(tags)
55+
_groupInstruments = instrument :: _groupInstruments
56+
instrument
57+
}
58+
59+
/**
60+
* Removes all instruments that were registered by this group.
61+
*/
62+
def remove(): Unit = synchronized {
63+
_groupInstruments foreach(_.remove())
64+
}
65+
}

kamon-core/src/main/scala/kamon/metric/Metric.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import scala.collection.mutable
2222
* combination of tags used to create them.
2323
*
2424
*/
25-
trait Metric[Inst, Sett <: Metric.Settings] extends Tagging[Inst] {
25+
trait Metric[Inst <: Instrument[Inst, Sett], Sett <: Metric.Settings] extends Tagging[Inst] {
2626

2727
/**
2828
* A unique identifier for this metric. Metric names typically will be namespaced, meaning that their name has a

0 commit comments

Comments
 (0)