1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
package kamon.metric
import akka.actor.ExtendedActorSystem
import com.typesafe.config.Config
import kamon.metric.instrument.{ RefreshScheduler, InstrumentFactory, DefaultInstrumentSettings, InstrumentCustomSettings }
import kamon.util.GlobPathFilter
import scala.concurrent.duration.FiniteDuration
/**
* Configuration settings for the Metrics extension, as read from the `kamon.metric` configuration key.
*/
case class MetricsExtensionSettings(
tickInterval: FiniteDuration,
defaultCollectionContextBufferSize: Int,
trackUnmatchedEntities: Boolean,
entityFilters: Map[String, EntityFilter],
instrumentFactories: Map[String, InstrumentFactory],
defaultInstrumentFactory: InstrumentFactory,
metricCollectionDispatcher: String,
refreshSchedulerDispatcher: String,
refreshScheduler: RefreshScheduler)
/**
*
*/
case class EntityFilter(includes: List[GlobPathFilter], excludes: List[GlobPathFilter]) {
def accept(name: String): Boolean =
includes.exists(_.accept(name)) && !excludes.exists(_.accept(name))
}
object MetricsExtensionSettings {
import kamon.util.ConfigTools.Syntax
import scala.concurrent.duration._
def apply(system: ExtendedActorSystem): MetricsExtensionSettings = {
val metricConfig = system.settings.config.getConfig("kamon.metric")
val tickInterval = metricConfig.getFiniteDuration("tick-interval")
val collectBufferSize = metricConfig.getInt("default-collection-context-buffer-size")
val trackUnmatchedEntities = metricConfig.getBoolean("track-unmatched-entities")
val entityFilters = loadFilters(metricConfig.getConfig("filters"))
val defaultInstrumentSettings = DefaultInstrumentSettings.fromConfig(metricConfig.getConfig("default-instrument-settings"))
val metricCollectionDispatcher = metricConfig.getString("dispatchers.metric-collection")
val refreshSchedulerDispatcher = metricConfig.getString("dispatchers.refresh-scheduler")
val refreshScheduler = RefreshScheduler(system.scheduler, system.dispatchers.lookup(refreshSchedulerDispatcher))
val instrumentFactories = loadInstrumentFactories(metricConfig.getConfig("instrument-settings"), defaultInstrumentSettings, refreshScheduler)
val defaultInstrumentFactory = new InstrumentFactory(Map.empty, defaultInstrumentSettings, refreshScheduler)
MetricsExtensionSettings(tickInterval, collectBufferSize, trackUnmatchedEntities, entityFilters, instrumentFactories,
defaultInstrumentFactory, metricCollectionDispatcher, refreshSchedulerDispatcher, refreshScheduler)
}
/**
* Load all the default filters configured under the `kamon.metric.filters` configuration key. All filters are
* defined with the entity category as a sub-key of the `kamon.metric.filters` key and two sub-keys to it: includes
* and excludes with lists of string glob patterns as values. Example:
*
* {{{
*
* kamon.metrics.filters {
* actor {
* includes = ["user/test-actor", "user/service/worker-*"]
* excludes = ["user/IO-*"]
* }
* }
*
* }}}
*
* @return a Map from category name to corresponding entity filter.
*/
def loadFilters(filtersConfig: Config): Map[String, EntityFilter] = {
import scala.collection.JavaConverters._
filtersConfig.firstLevelKeys map { category: String ⇒
val includes = filtersConfig.getStringList(s"$category.includes").asScala.map(inc ⇒ new GlobPathFilter(inc)).toList
val excludes = filtersConfig.getStringList(s"$category.excludes").asScala.map(exc ⇒ new GlobPathFilter(exc)).toList
(category, EntityFilter(includes, excludes))
} toMap
}
/**
* Load any custom configuration settings defined under the `kamon.metric.instrument-settings` configuration key and
* create InstrumentFactories for them.
*
* @return a Map from category name to InstrumentFactory.
*/
def loadInstrumentFactories(instrumentSettings: Config, defaults: DefaultInstrumentSettings, refreshScheduler: RefreshScheduler): Map[String, InstrumentFactory] = {
instrumentSettings.firstLevelKeys.map { category ⇒
val categoryConfig = instrumentSettings.getConfig(category)
val customSettings = categoryConfig.firstLevelKeys.map { instrumentName ⇒
(instrumentName, InstrumentCustomSettings.fromConfig(categoryConfig.getConfig(instrumentName)))
} toMap
(category, new InstrumentFactory(customSettings, defaults, refreshScheduler))
} toMap
}
}
|