/**
* Copyright 2017 Pivotal Software, Inc.
*
* 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 org.springframework.metrics.instrument;
import com.google.common.cache.Cache;
import org.springframework.metrics.instrument.binder.MeterBinder;
import javax.sql.DataSource;
import java.util.*;
import java.util.function.ToDoubleFunction;
import java.util.stream.Stream;
import static java.util.Collections.emptyList;
import static java.util.stream.Collectors.toList;
import static java.util.stream.StreamSupport.stream;
import static org.springframework.metrics.instrument.Tags.tagList;
/**
* Creates and manages your application's set of meters. Exporters use the meter registry to iterate
* over the set of meters instrumenting your application, and then further iterate over each meter's metrics, generally
* resulting in a time series in the metrics backend for each combination of metrics and dimensions.
*
* @author Jon Schneider
*/
public interface MeterRegistry {
/**
* @return The set of registered meters.
*/
Collection<Meter> getMeters();
default <M extends Meter> Optional<M> findMeter(Class<M> mClass, String name, String...tags) {
return findMeter(mClass, name, Tags.tagList(tags));
}
default <M extends Meter> Optional<M> findMeter(Class<M> mClass, String name, Stream<Tag> tags) {
return findMeter(mClass, name, tags);
}
<M extends Meter> Optional<M> findMeter(Class<M> mClass, String name, Iterable<Tag> tags);
Clock getClock();
/**
* Measures the rate of some activity.
*/
Counter counter(String name, Iterable<Tag> tags);
/**
* Measures the rate of some activity.
*/
default Counter counter(String name, Stream<Tag> tags) {
return counter(name, tags.collect(toList()));
}
/**
* Measures the rate of some activity.
*/
default Counter counter(String name) {
return counter(name, emptyList());
}
/**
* Measures the rate of some activity.
*/
default Counter counter(String name, String... tags) {
return counter(name, tagList(tags));
}
/**
* Measures the sample distribution of events.
*/
DistributionSummary distributionSummary(String name, Iterable<Tag> tags);
/**
* Measures the sample distribution of events.
*/
default DistributionSummary distributionSummary(String name, Stream<Tag> tags) {
return distributionSummary(name, tags.collect(toList()));
}
/**
* Measures the sample distribution of events.
*/
default DistributionSummary distributionSummary(String name) {
return distributionSummary(name, emptyList());
}
/**
* Measures the sample distribution of events.
*/
default DistributionSummary distributionSummary(String name, String... tags) {
return distributionSummary(name, tagList(tags));
}
/**
* Measures the time taken for short tasks.
*/
Timer timer(String name, Iterable<Tag> tags);
/**
* Measures the time taken for short tasks.
*/
default Timer timer(String name, Stream<Tag> tags) {
return timer(name, tags.collect(toList()));
}
/**
* Measures the time taken for short tasks.
*/
default Timer timer(String name) {
return timer(name, emptyList());
}
/**
* Measures the time taken for short tasks.
*/
default Timer timer(String name, String... tags) {
return timer(name, tagList(tags));
}
/**
* Measures the time taken for short tasks.
*/
LongTaskTimer longTaskTimer(String name, Iterable<Tag> tags);
/**
* Measures the time taken for short tasks.
*/
default LongTaskTimer longTaskTimer(String name, Stream<Tag> tags) {
return longTaskTimer(name, tags.collect(toList()));
}
/**
* Measures the time taken for short tasks.
*/
default LongTaskTimer longTaskTimer(String name) {
return longTaskTimer(name, emptyList());
}
/**
* Measures the time taken for short tasks.
*/
default LongTaskTimer longTaskTimer(String name, String... tags) {
return longTaskTimer(name, tagList(tags));
}
/**
* Register a gauge that reports the value of the object after the function
* {@code f} is applied. The registration will keep a weak reference to the object so it will
* not prevent garbage collection. Applying {@code f} on the object should be thread safe.
* <p>
* If multiple gauges are registered with the same id, then the values will be aggregated and
* the sum will be reported. For example, registering multiple gauges for active threads in
* a thread pool with the same id would produce a value that is the overall number
* of active threads. For other behaviors, manage it on the user side and avoid multiple
* registrations.
*
* @param name Name of the metric being registered.
* @param tags Sequence of dimensions for breaking down the getName.
* @param obj Object used to compute a value.
* @param f Function that is applied on the value for the number.
* @return The number that was passed in so the registration can be done as part of an assignment
* statement.
*/
default <T> T gauge(String name, Stream<Tag> tags, T obj, ToDoubleFunction<T> f) {
return gauge(name, tags.collect(toList()), obj, f);
}
/**
* Register a gauge that reports the value of the object after the function
* {@code f} is applied. The registration will keep a weak reference to the object so it will
* not prevent garbage collection. Applying {@code f} on the object should be thread safe.
* <p>
* If multiple gauges are registered with the same id, then the values will be aggregated and
* the sum will be reported. For example, registering multiple gauges for active threads in
* a thread pool with the same id would produce a value that is the overall number
* of active threads. For other behaviors, manage it on the user side and avoid multiple
* registrations.
*
* @param name Name of the metric being registered.
* @param tags Sequence of dimensions for breaking down the getName.
* @param obj Object used to compute a value.
* @param f Function that is applied on the value for the number.
* @return The number that was passed in so the registration can be done as part of an assignment
* statement.
*/
<T> T gauge(String name, Iterable<Tag> tags, T obj, ToDoubleFunction<T> f);
/**
* Register a gauge that reports the value of the {@link java.lang.Number}.
*
* @param name Name of the metric being registered.
* @param tags Sequence of dimensions for breaking down the getName.
* @param number Thread-safe implementation of {@link Number} used to access the value.
* @return The number that was passed in so the registration can be done as part of an assignment
* statement.
*/
default <T extends Number> T gauge(String name, Iterable<Tag> tags, T number) {
return gauge(name, tags, number, Number::doubleValue);
}
/**
* Register a gauge that reports the value of the {@link java.lang.Number}.
*
* @param name Name of the metric being registered.
* @param number Thread-safe implementation of {@link Number} used to access the value.
* @return The number that was passed in so the registration can be done as part of an assignment
* statement.
*/
default <T extends Number> T gauge(String name, T number) {
return gauge(name, emptyList(), number);
}
/**
* Register a gauge that reports the value of the object.
*
* @param name Name of the metric being registered.
* @param obj Object used to compute a value.
* @param f Function that is applied on the value for the number.
* @return The number that was passed in so the registration can be done as part of an assignment
* statement.
*/
default <T> T gauge(String name, T obj, ToDoubleFunction<T> f) {
return gauge(name, emptyList(), obj, f);
}
/**
* Register a gauge that reports the size of the {@link java.util.Collection}. The registration
* will keep a weak reference to the collection so it will not prevent garbage collection.
* The collection implementation used should be thread safe. Note that calling
* {@link java.util.Collection#size()} can be expensive for some collection implementations
* and should be considered before registering.
*
* @param name Name of the metric being registered.
* @param tags Sequence of dimensions for breaking down the getName.
* @param collection Thread-safe implementation of {@link Collection} used to access the value.
* @return The number that was passed in so the registration can be done as part of an assignment
* statement.
*/
default <T extends Collection<?>> T collectionSize(String name, Iterable<Tag> tags, T collection) {
return gauge(name, tags, collection, Collection::size);
}
/**
* Register a gauge that reports the size of the {@link java.util.Collection}. The registration
* will keep a weak reference to the collection so it will not prevent garbage collection.
* The collection implementation used should be thread safe. Note that calling
* {@link java.util.Collection#size()} can be expensive for some collection implementations
* and should be considered before registering.
*
* @param name Name of the metric being registered.
* @param collection Thread-safe implementation of {@link Collection} used to access the value.
* @return The number that was passed in so the registration can be done as part of an assignment
* statement.
*/
default <T extends Collection<?>> T collectionSize(String name, T collection) {
return collectionSize(name, emptyList(), collection);
}
/**
* Register a gauge that reports the size of the {@link java.util.Map}. The registration
* will keep a weak reference to the collection so it will not prevent garbage collection.
* The collection implementation used should be thread safe. Note that calling
* {@link java.util.Map#size()} can be expensive for some collection implementations
* and should be considered before registering.
*
* @param name Name of the metric being registered.
* @param tags Sequence of dimensions for breaking down the getName.
* @param collection Thread-safe implementation of {@link Map} used to access the value.
* @return The number that was passed in so the registration can be done as part of an assignment
* statement.
*/
default <T extends Map<?, ?>> T mapSize(String name, Iterable<Tag> tags, T collection) {
return gauge(name, tags, collection, Map::size);
}
/**
* Register a gauge that reports the size of the {@link java.util.Map}. The registration
* will keep a weak reference to the collection so it will not prevent garbage collection.
* The collection implementation used should be thread safe. Note that calling
* {@link java.util.Map#size()} can be expensive for some collection implementations
* and should be considered before registering.
*
* @param name Name of the metric being registered.
* @param collection Thread-safe implementation of {@link Map} used to access the value.
* @return The number that was passed in so the registration can be done as part of an assignment
* statement.
*/
default <T extends Map<?, ?>> T mapSize(String name, T collection) {
return mapSize(name, emptyList(), collection);
}
/**
* Execute an algorithm to bind one or more metrics to the registry.
*/
default MeterRegistry bind(MeterBinder... binders) {
for (MeterBinder binder : binders) {
binder.bindTo(this);
}
return this;
}
/**
* Record metrics on Guava caches.
*
* @see com.google.common.cache.CacheStats
* @param cache The cache to instrument.
* @return The instrumented cache, unchanged. The original cache is not
* wrapped or proxied in any way.
*/
default Cache monitor(String name, Iterable<Tag> tags, Cache cache) {
return monitor(name, stream(tags.spliterator(), false), cache);
}
/**
* Record metrics on Guava caches.
*
* @see com.google.common.cache.CacheStats
* @param cache The cache to instrument.
* @return The instrumented cache, unchanged. The original cache is not
* wrapped or proxied in any way.
*/
Cache monitor(String name, Stream<Tag> tags, Cache cache);
/**
* Record metrics on Guava caches.
*
* @see com.google.common.cache.CacheStats
* @param cache The cache to instrument.
* @return The instrumented cache, unchanged. The original cache is not
* wrapped or proxied in any way.
*/
default Cache monitor(String name, Cache cache) {
return monitor(name, emptyList(), cache);
}
/**
* Record metrics on active connections and connection pool utilization.
*
* @param dataSource The data source to instrument.
* @return The instrumented data source, unchanged. The original data source
* is not wrapped or proxied in any way.
*/
default DataSource monitor(String name, Iterable<Tag> tags, DataSource dataSource) {
return monitor(name, stream(tags.spliterator(), false), dataSource);
}
/**
* Record metrics on active connections and connection pool utilization.
*
* @param dataSource The data source to instrument.
* @return The instrumented data source, unchanged. The original data source
* is not wrapped or proxied in any way.
*/
DataSource monitor(String name, Stream<Tag> tags, DataSource dataSource);
/**
* Record metrics on active connections and connection pool utilization.
*
* @param dataSource The data source to instrument.
* @return The instrumented data source, unchanged. The original data source
* is not wrapped or proxied in any way.
*/
default DataSource monitor(String name, DataSource dataSource) {
return monitor(name, emptyList(), dataSource);
}
}