@@ -96,14 +96,13 @@ public static MicrometerMetricsBuilder newMicrometerMetricsBuilder(MeterRegistry
96
96
97
97
/**
98
98
* Creates a micrometer-based Metrics implementation that cleans up {@link Meter}s associated with
99
- * deleted resources as specified by the (possibly {@code null}) provided {@link Cleaner}
100
- * instance.
99
+ * deleted resources as specified by the provided {@link Cleaner} instance.
101
100
*
102
101
* @param registry the {@link MeterRegistry} instance to use for metrics recording
103
102
* @param cleaner the {@link Cleaner} to use
104
103
* @param collectingPerResourceMetrics whether to collect per resource metrics
105
104
*/
106
- private MicrometerMetrics (
105
+ protected MicrometerMetrics (
107
106
MeterRegistry registry , Cleaner cleaner , boolean collectingPerResourceMetrics ) {
108
107
this .registry = registry ;
109
108
this .cleaner = cleaner ;
@@ -315,11 +314,10 @@ protected Set<Meter.Id> recordedMeterIdsFor(ResourceID resourceID) {
315
314
public static class PerResourceCollectingMicrometerMetricsBuilder
316
315
extends MicrometerMetricsBuilder {
317
316
318
- private int cleaningThreadsNumber ;
319
- private int cleanUpDelayInSeconds ;
320
-
321
317
private PerResourceCollectingMicrometerMetricsBuilder (MeterRegistry registry ) {
322
318
super (registry );
319
+ cleanerBuilder .withCleanerType (CleanerType .DELAYED );
320
+ collectingPerResourceMetrics = true ;
323
321
}
324
322
325
323
/**
@@ -329,7 +327,7 @@ private PerResourceCollectingMicrometerMetricsBuilder(MeterRegistry registry) {
329
327
*/
330
328
public PerResourceCollectingMicrometerMetricsBuilder withCleaningThreadNumber (
331
329
int cleaningThreadsNumber ) {
332
- this . cleaningThreadsNumber = cleaningThreadsNumber <= 0 ? 1 : cleaningThreadsNumber ;
330
+ cleanerBuilder . withCleaningThreadNumber ( cleaningThreadsNumber ) ;
333
331
return this ;
334
332
}
335
333
@@ -343,30 +341,24 @@ public PerResourceCollectingMicrometerMetricsBuilder withCleaningThreadNumber(
343
341
*/
344
342
public PerResourceCollectingMicrometerMetricsBuilder withCleanUpDelayInSeconds (
345
343
int cleanUpDelayInSeconds ) {
346
- this . cleanUpDelayInSeconds = Math . max (cleanUpDelayInSeconds , 1 );
344
+ cleanerBuilder . withCleanUpDelayInSeconds (cleanUpDelayInSeconds );
347
345
return this ;
348
346
}
349
-
350
- @ Override
351
- public MicrometerMetrics build () {
352
- final var cleaner =
353
- new DelayedCleaner (registry , cleanUpDelayInSeconds , cleaningThreadsNumber );
354
- return new MicrometerMetrics (registry , cleaner , true );
355
- }
356
347
}
357
348
358
349
public static class MicrometerMetricsBuilder {
359
350
protected final MeterRegistry registry ;
360
- private boolean collectingPerResourceMetrics = true ;
351
+ protected final CleanerBuilder cleanerBuilder ;
352
+ protected boolean collectingPerResourceMetrics = true ;
361
353
362
354
private MicrometerMetricsBuilder (MeterRegistry registry ) {
363
355
this .registry = registry ;
356
+ this .cleanerBuilder = new CleanerBuilder (registry );
364
357
}
365
358
366
359
/** Configures the instance to collect metrics on a per-resource basis. */
367
360
@ SuppressWarnings ("unused" )
368
361
public PerResourceCollectingMicrometerMetricsBuilder collectingMetricsPerResource () {
369
- collectingPerResourceMetrics = true ;
370
362
return new PerResourceCollectingMicrometerMetricsBuilder (registry );
371
363
}
372
364
@@ -381,11 +373,79 @@ public MicrometerMetricsBuilder notCollectingMetricsPerResource() {
381
373
}
382
374
383
375
public MicrometerMetrics build () {
384
- return new MicrometerMetrics (registry , Cleaner .NOOP , collectingPerResourceMetrics );
376
+ return new MicrometerMetrics (registry , cleanerBuilder .build (), collectingPerResourceMetrics );
377
+ }
378
+ }
379
+
380
+ public static class CleanerBuilder {
381
+
382
+ private final MeterRegistry registry ;
383
+ private CleanerType cleanerType = CleanerType .NOOP ;
384
+ private int cleaningThreadsNumber = 0 ;
385
+ private int cleanUpDelayInSeconds = 0 ;
386
+
387
+ public CleanerBuilder (MeterRegistry registry ) {
388
+ this .registry = registry ;
389
+ }
390
+
391
+ /**
392
+ * @param cleanerType the type of cleaner to use, defaults to {@link CleanerType#NOOP} if not
393
+ * specified
394
+ */
395
+ public CleanerBuilder withCleanerType (CleanerType cleanerType ) {
396
+ this .cleanerType = cleanerType ;
397
+ return this ;
398
+ }
399
+
400
+ /**
401
+ * @param cleaningThreadsNumber the maximal number of threads that can be assigned to the
402
+ * removal of {@link Meter}s associated with deleted resources, defaults to 1 if not
403
+ * specified or if the provided number is lesser or equal to 0
404
+ * @throws IllegalStateException if the cleaner type is not {@link CleanerType#DELAYED}
405
+ */
406
+ public CleanerBuilder withCleaningThreadNumber (int cleaningThreadsNumber ) {
407
+ if (cleanerType != CleanerType .DELAYED ) {
408
+ throw new IllegalStateException (
409
+ "Cleaning threads can only be configured when using the DELAYED cleaner type" );
410
+ }
411
+ this .cleaningThreadsNumber = cleaningThreadsNumber <= 0 ? 1 : cleaningThreadsNumber ;
412
+ return this ;
385
413
}
414
+
415
+ /**
416
+ * @param cleanUpDelayInSeconds the number of seconds to wait before {@link Meter}s are removed
417
+ * for deleted resources, defaults to 1 (meaning meters will be removed one second after the
418
+ * associated resource is deleted) if not specified or if the provided number is lesser than
419
+ * 0. Threading and the general interaction model of interacting with the API server means
420
+ * that it's not possible to ensure that meters are immediately deleted in all cases so a
421
+ * minimal delay of one second is always enforced
422
+ * @throws IllegalStateException if the cleaner type is not {@link CleanerType#DELAYED}
423
+ */
424
+ public CleanerBuilder withCleanUpDelayInSeconds (int cleanUpDelayInSeconds ) {
425
+ if (cleanerType != CleanerType .DELAYED ) {
426
+ throw new IllegalStateException (
427
+ "Clean up delay can only be configured when using the DELAYED cleaner type" );
428
+ }
429
+ this .cleanUpDelayInSeconds = Math .max (cleanUpDelayInSeconds , 1 );
430
+ return this ;
431
+ }
432
+
433
+ public Cleaner build () {
434
+ return switch (cleanerType ) {
435
+ case NOOP -> Cleaner .NOOP ;
436
+ case DEFAULT -> new DefaultCleaner (registry );
437
+ case DELAYED -> new DelayedCleaner (registry , cleanUpDelayInSeconds , cleaningThreadsNumber );
438
+ };
439
+ }
440
+ }
441
+
442
+ public enum CleanerType {
443
+ NOOP ,
444
+ DEFAULT ,
445
+ DELAYED
386
446
}
387
447
388
- interface Cleaner {
448
+ public interface Cleaner {
389
449
Cleaner NOOP = new Cleaner () {};
390
450
391
451
default void removeMetersFor (ResourceID resourceID ) {}
@@ -444,5 +504,10 @@ public void removeMetersFor(ResourceID resourceID) {
444
504
metersCleaner .schedule (
445
505
() -> super .removeMetersFor (resourceID ), cleanUpDelayInSeconds , TimeUnit .SECONDS );
446
506
}
507
+
508
+ // for testing purposes only
509
+ int getCleanUpDelayInSeconds () {
510
+ return cleanUpDelayInSeconds ;
511
+ }
447
512
}
448
513
}
0 commit comments