forked from ReactiveX/RxJava
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Issue ReactiveX#531: Time limiter micrometer (ReactiveX#599)
- Loading branch information
Showing
5 changed files
with
394 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
213 changes: 213 additions & 0 deletions
213
...eter/src/main/java/io/github/resilience4j/micrometer/tagged/TaggedTimeLimiterMetrics.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
/* | ||
* Copyright 2019 authors | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
package io.github.resilience4j.micrometer.tagged; | ||
|
||
import io.github.resilience4j.timelimiter.TimeLimiter; | ||
import io.github.resilience4j.timelimiter.TimeLimiterRegistry; | ||
import io.micrometer.core.instrument.Counter; | ||
import io.micrometer.core.instrument.Meter; | ||
import io.micrometer.core.instrument.MeterRegistry; | ||
import io.micrometer.core.instrument.binder.MeterBinder; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Objects; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
/** | ||
* A micrometer binder that is used to register TimeLimiter exposed events. | ||
*/ | ||
public class TaggedTimeLimiterMetrics extends AbstractMetrics implements MeterBinder { | ||
|
||
/** | ||
* Creates a new binder that uses given {@code registry} as source of time limiters. | ||
* | ||
* @param timeLimiterRegistry the source of time limiters | ||
* @return The {@link TaggedTimeLimiterMetrics} instance. | ||
*/ | ||
public static TaggedTimeLimiterMetrics ofTimeLimiterRegistry(TimeLimiterRegistry timeLimiterRegistry) { | ||
return new TaggedTimeLimiterMetrics(MetricNames.ofDefaults(), timeLimiterRegistry); | ||
} | ||
|
||
/** | ||
* Creates a new binder that uses given {@code registry} as source of time limiters. | ||
* | ||
* @param names custom metric names | ||
* @param timeLimiterRegistry the source of time limiters | ||
* @return The {@link TaggedTimeLimiterMetrics} instance. | ||
*/ | ||
public static TaggedTimeLimiterMetrics ofTimeLimiterRegistry(MetricNames names, TimeLimiterRegistry timeLimiterRegistry) { | ||
return new TaggedTimeLimiterMetrics(names, timeLimiterRegistry); | ||
} | ||
|
||
private final MetricNames names; | ||
private final TimeLimiterRegistry timeLimiterRegistry; | ||
|
||
private TaggedTimeLimiterMetrics(MetricNames names, TimeLimiterRegistry timeLimiterRegistry) { | ||
super(); | ||
this.names = Objects.requireNonNull(names); | ||
this.timeLimiterRegistry = Objects.requireNonNull(timeLimiterRegistry); | ||
} | ||
|
||
@Override | ||
public void bindTo(MeterRegistry registry) { | ||
for (TimeLimiter timeLimiter : timeLimiterRegistry.getAllTimeLimiters()) { | ||
addMetrics(registry, timeLimiter); | ||
} | ||
timeLimiterRegistry.getEventPublisher().onEntryAdded(event -> addMetrics(registry, event.getAddedEntry())); | ||
timeLimiterRegistry.getEventPublisher().onEntryRemoved(event -> removeMetrics(registry, event.getRemovedEntry().getName())); | ||
timeLimiterRegistry.getEventPublisher().onEntryReplaced(event -> { | ||
removeMetrics(registry, event.getOldEntry().getName()); | ||
addMetrics(registry, event.getNewEntry()); | ||
}); | ||
} | ||
|
||
private void addMetrics(MeterRegistry registry, TimeLimiter timeLimiter) { | ||
Counter successes = Counter.builder(names.getSuccessfulMetricName()) | ||
.description("The number of successful calls") | ||
.tag(TagNames.NAME, timeLimiter.getName()) | ||
.register(registry); | ||
Counter failures = Counter.builder(names.getFailedMetricName()) | ||
.description("The number of failed calls") | ||
.tag(TagNames.NAME, timeLimiter.getName()) | ||
.register(registry); | ||
Counter timeouts = Counter.builder(names.getTimeoutMetricName()) | ||
.description("The number of timed out calls") | ||
.tag(TagNames.NAME, timeLimiter.getName()) | ||
.register(registry); | ||
|
||
timeLimiter.getEventPublisher() | ||
.onSuccess(event -> successes.increment()) | ||
.onError(event -> failures.increment()) | ||
.onTimeout(event -> timeouts.increment()); | ||
|
||
List<Meter.Id> ids = Arrays.asList(successes.getId(), failures.getId(), timeouts.getId()); | ||
meterIdMap.put(timeLimiter.getName(), new HashSet<>(ids)); | ||
} | ||
|
||
/** | ||
* Defines possible configuration for metric names. | ||
*/ | ||
public static class MetricNames { | ||
|
||
private static final String DEFAULT_PREFIX = "resilience4j.timelimiter"; | ||
public static final String SUCCESSFUL_METRIC_NAME = DEFAULT_PREFIX + ".successful"; | ||
public static final String FAILED_METRIC_NAME = DEFAULT_PREFIX + ".failed"; | ||
public static final String TIMEOUT_METRIC_NAME = DEFAULT_PREFIX + ".timeout"; | ||
|
||
/** | ||
* Returns a builder for creating custom metric names. | ||
* Note that names have default values, so only desired metrics can be renamed. | ||
* | ||
* @return The builder. | ||
*/ | ||
public static Builder custom() { | ||
return new Builder(); | ||
} | ||
|
||
/** | ||
* Returns default metric names. | ||
* | ||
* @return The default {@link MetricNames} instance. | ||
*/ | ||
public static MetricNames ofDefaults() { | ||
return new MetricNames(); | ||
} | ||
|
||
private String successfulMetricName = SUCCESSFUL_METRIC_NAME; | ||
private String failedMetricName = FAILED_METRIC_NAME; | ||
private String timeoutMetricName = TIMEOUT_METRIC_NAME; | ||
|
||
/** | ||
* Returns the metric name for successful calls, defaults to {@value SUCCESSFUL_METRIC_NAME}. | ||
* | ||
* @return The successful calls metric name. | ||
*/ | ||
public String getSuccessfulMetricName() { | ||
return successfulMetricName; | ||
} | ||
|
||
/** | ||
* Returns the metric name for failed calls, defaults to {@value FAILED_METRIC_NAME}. | ||
* | ||
* @return The failed calls metric name. | ||
*/ | ||
public String getFailedMetricName() { | ||
return failedMetricName; | ||
} | ||
|
||
/** | ||
* Returns the metric name for timed out calls, defaults to {@value TIMEOUT_METRIC_NAME}. | ||
* | ||
* @return The timed out calls metric name. | ||
*/ | ||
public String getTimeoutMetricName() { | ||
return timeoutMetricName; | ||
} | ||
|
||
/** | ||
* Helps building custom instance of {@link MetricNames}. | ||
*/ | ||
public static class Builder { | ||
|
||
private final MetricNames metricNames = new MetricNames(); | ||
|
||
/** | ||
* Overrides the default metric name {@value MetricNames#SUCCESSFUL_METRIC_NAME} with a given one. | ||
* | ||
* @param successfulMetricName The successful calls metric name. | ||
* @return The builder. | ||
*/ | ||
public Builder successfulMetricName(String successfulMetricName) { | ||
metricNames.successfulMetricName = requireNonNull(successfulMetricName); | ||
return this; | ||
} | ||
|
||
/** | ||
* Overrides the default metric name {@value MetricNames#FAILED_METRIC_NAME} with a given one. | ||
* | ||
* @param failedMetricName The failed calls metric name. | ||
* @return The builder. | ||
*/ | ||
public Builder failedMetricName(String failedMetricName) { | ||
metricNames.failedMetricName = requireNonNull(failedMetricName); | ||
return this; | ||
} | ||
|
||
/** | ||
* Overrides the default metric name {@value MetricNames#TIMEOUT_METRIC_NAME} with a given one. | ||
* | ||
* @param timeoutMetricName The timed out calls metric name. | ||
* @return The builder. | ||
*/ | ||
public Builder timeoutMetricName(String timeoutMetricName) { | ||
metricNames.timeoutMetricName = requireNonNull(timeoutMetricName); | ||
return this; | ||
} | ||
|
||
/** | ||
* Builds {@link MetricNames} instance. | ||
* | ||
* @return The built {@link MetricNames} instance. | ||
*/ | ||
public MetricNames build() { | ||
return metricNames; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.