@@ -22,7 +22,7 @@ import java.util.concurrent.TimeUnit
22
22
23
23
import scala .collection .mutable
24
24
25
- import com .codahale .metrics .{ Metric , MetricFilter , MetricRegistry }
25
+ import com .codahale .metrics ._
26
26
import org .eclipse .jetty .servlet .ServletContextHandler
27
27
28
28
import org .apache .spark .{SecurityManager , SparkConf }
@@ -70,14 +70,15 @@ import org.apache.spark.util.Utils
70
70
private [spark] class MetricsSystem private (
71
71
val instance : String ,
72
72
conf : SparkConf ,
73
- securityMgr : SecurityManager )
73
+ securityMgr : SecurityManager ,
74
+ registry : MetricRegistry )
74
75
extends Logging {
75
76
76
77
private [this ] val metricsConfig = new MetricsConfig (conf)
77
78
78
79
private val sinks = new mutable.ArrayBuffer [Sink ]
79
- private val sources = new mutable.ArrayBuffer [Source ]
80
- private val registry = new MetricRegistry ( )
80
+ private val sourceToListeners = new mutable.HashMap [Source , MetricRegistryListener ]
81
+ private val defaultListener = new MetricsSystemListener ( " " )
81
82
82
83
private var running : Boolean = false
83
84
@@ -99,13 +100,17 @@ private[spark] class MetricsSystem private (
99
100
running = true
100
101
StaticSources .allSources.foreach(registerSource)
101
102
registerSources()
103
+ SharedMetricRegistries .getDefault.addListener(defaultListener)
102
104
registerSinks()
103
- sinks.foreach(_.start)
105
+ sinks.foreach(_.start() )
104
106
}
105
107
106
108
def stop () {
107
109
if (running) {
108
- sinks.foreach(_.stop)
110
+ sinks.foreach(_.stop())
111
+ sourceToListeners.keySet.foreach(deregisterSource)
112
+ sourceToListeners.clear()
113
+ SharedMetricRegistries .getDefault.removeListener(defaultListener)
109
114
} else {
110
115
logWarning(" Stopping a MetricsSystem that is not running" )
111
116
}
@@ -151,26 +156,36 @@ private[spark] class MetricsSystem private (
151
156
}
152
157
153
158
def getSourcesByName (sourceName : String ): Seq [Source ] =
154
- sources. filter(_.sourceName == sourceName)
159
+ sourceToListeners.keySet. filter(_.sourceName == sourceName).toSeq
155
160
156
161
def registerSource (source : Source ) {
157
- sources += source
158
162
try {
159
- val regName = buildRegistryName(source)
160
- registry.register(regName, source.metricRegistry)
163
+ val listener = new MetricsSystemListener (buildRegistryName(source))
164
+ source.metricRegistry.addListener(listener)
165
+ sourceToListeners += source -> listener
161
166
} catch {
162
167
case e : IllegalArgumentException => logInfo(" Metrics already registered" , e)
163
168
}
164
169
}
165
170
166
- def removeSource (source : Source ) {
167
- sources -= source
171
+ def deregisterSource (source : Source ) {
168
172
val regName = buildRegistryName(source)
169
173
registry.removeMatching(new MetricFilter {
170
174
def matches (name : String , metric : Metric ): Boolean = name.startsWith(regName)
171
175
})
176
+ sourceToListeners.get(source).foreach(source.metricRegistry.removeListener)
172
177
}
173
178
179
+ def removeSource (source : Source ): Unit = {
180
+ deregisterSource(source)
181
+ sourceToListeners.remove(source)
182
+ }
183
+
184
+ def getSources : Seq [Source ] =
185
+ sourceToListeners.keySet.to[collection.immutable.Seq ]
186
+
187
+ def getSinks : Seq [Sink ] = sinks.to[collection.immutable.Seq ]
188
+
174
189
private def registerSources () {
175
190
val instConfig = metricsConfig.getInstance(instance)
176
191
val sourceConfigs = metricsConfig.subProperties(instConfig, MetricsSystem .SOURCE_REGEX )
@@ -211,6 +226,41 @@ private[spark] class MetricsSystem private (
211
226
}
212
227
}
213
228
}
229
+
230
+ private [spark] class MetricsSystemListener (prefix : String )
231
+ extends MetricRegistryListener {
232
+ def metricName (name : String ): String = MetricRegistry .name(prefix, name)
233
+
234
+ override def onHistogramAdded (name : String , histogram : Histogram ): Unit =
235
+ registry.register(metricName(name), histogram)
236
+
237
+ override def onCounterAdded (name : String , counter : Counter ): Unit =
238
+ registry.register(metricName(name), counter)
239
+
240
+ override def onHistogramRemoved (name : String ): Unit =
241
+ registry.remove(metricName(name))
242
+
243
+ override def onGaugeRemoved (name : String ): Unit =
244
+ registry.remove(metricName(name))
245
+
246
+ override def onMeterRemoved (name : String ): Unit =
247
+ registry.remove(metricName(name))
248
+
249
+ override def onTimerAdded (name : String , timer : Timer ): Unit =
250
+ registry.register(metricName(name), timer)
251
+
252
+ override def onCounterRemoved (name : String ): Unit =
253
+ registry.remove(metricName(name))
254
+
255
+ override def onGaugeAdded (name : String , gauge : Gauge [_]): Unit =
256
+ registry.register(metricName(name), gauge)
257
+
258
+ override def onTimerRemoved (name : String ): Unit =
259
+ registry.remove(metricName(name))
260
+
261
+ override def onMeterAdded (name : String , meter : Meter ): Unit =
262
+ registry.register(metricName(name), meter)
263
+ }
214
264
}
215
265
216
266
private [spark] object MetricsSystem {
@@ -220,6 +270,10 @@ private[spark] object MetricsSystem {
220
270
private [this ] val MINIMAL_POLL_UNIT = TimeUnit .SECONDS
221
271
private [this ] val MINIMAL_POLL_PERIOD = 1
222
272
273
+ scala.util.control.Exception .ignoring(classOf [IllegalStateException ]) {
274
+ SharedMetricRegistries .setDefault(" spark" , new MetricRegistry ())
275
+ }
276
+
223
277
def checkMinimalPollingPeriod (pollUnit : TimeUnit , pollPeriod : Int ) {
224
278
val period = MINIMAL_POLL_UNIT .convert(pollPeriod, pollUnit)
225
279
if (period < MINIMAL_POLL_PERIOD ) {
@@ -230,6 +284,14 @@ private[spark] object MetricsSystem {
230
284
231
285
def createMetricsSystem (
232
286
instance : String , conf : SparkConf , securityMgr : SecurityManager ): MetricsSystem = {
233
- new MetricsSystem (instance, conf, securityMgr)
287
+ new MetricsSystem (instance, conf, securityMgr, new MetricRegistry ())
288
+ }
289
+
290
+ def createMetricsSystem (
291
+ instance : String ,
292
+ conf : SparkConf ,
293
+ securityMgr : SecurityManager ,
294
+ registry : MetricRegistry ): MetricsSystem = {
295
+ new MetricsSystem (instance, conf, securityMgr, registry)
234
296
}
235
297
}
0 commit comments