sonarqube fixes
This commit is contained in:
parent
ec58c764d2
commit
1db95358c5
16 changed files with 193 additions and 152 deletions
|
@ -1,7 +1,7 @@
|
||||||
ext {
|
ext {
|
||||||
user = 'xbib'
|
user = 'xbib'
|
||||||
name = 'metrics'
|
name = 'metrics'
|
||||||
description = 'A stripped-down version of Coda Hale Metrics'
|
description = 'A stripped-down and modified version of Coda Hale Metrics'
|
||||||
scmUrl = 'https://github.com/' + user + '/' + name
|
scmUrl = 'https://github.com/' + user + '/' + name
|
||||||
scmConnection = 'scm:git:git://github.com/' + user + '/' + name + '.git'
|
scmConnection = 'scm:git:git://github.com/' + user + '/' + name + '.git'
|
||||||
scmDeveloperConnection = 'scm:git:git://github.com/' + user + '/' + name + '.git'
|
scmDeveloperConnection = 'scm:git:git://github.com/' + user + '/' + name + '.git'
|
||||||
|
|
|
@ -1,20 +1,17 @@
|
||||||
package org.xbib.metrics;
|
package org.xbib.metrics;
|
||||||
|
|
||||||
import java.lang.management.ManagementFactory;
|
|
||||||
import java.lang.management.ThreadMXBean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An abstraction for how time passes. It is passed to {@link Sampler} to track timing.
|
* An interface for how time passes. It is passed to {@link Sampler} to track timing.
|
||||||
*/
|
*/
|
||||||
public abstract class Clock {
|
public interface Clock {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default clock to use.
|
* The default clock to use.
|
||||||
*
|
*
|
||||||
* @return the default {@link Clock} instance
|
* @return the default {@link Clock} instance
|
||||||
* @see Clock.UserTimeClock
|
* @see UserTimeClock
|
||||||
*/
|
*/
|
||||||
public static Clock defaultClock() {
|
static Clock defaultClock() {
|
||||||
return UserTimeClock.DEFAULT;
|
return UserTimeClock.DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,40 +20,13 @@ public abstract class Clock {
|
||||||
*
|
*
|
||||||
* @return time tick in nanoseconds
|
* @return time tick in nanoseconds
|
||||||
*/
|
*/
|
||||||
public abstract long getTick();
|
long getTick();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the current time in milliseconds.
|
* Returns the current time in milliseconds.
|
||||||
*
|
*
|
||||||
* @return time in milliseconds
|
* @return time in milliseconds
|
||||||
*/
|
*/
|
||||||
public long getTime() {
|
long getTime();
|
||||||
return System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A clock implementation which returns the current time in epoch nanoseconds.
|
|
||||||
*/
|
|
||||||
public static class UserTimeClock extends Clock {
|
|
||||||
@Override
|
|
||||||
public long getTick() {
|
|
||||||
return System.nanoTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
static final Clock DEFAULT = new UserTimeClock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A clock implementation which returns the current thread's CPU time.
|
|
||||||
*/
|
|
||||||
public static class CpuTimeClock extends Clock {
|
|
||||||
private static final ThreadMXBean THREAD_MX_BEAN = ManagementFactory.getThreadMXBean();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long getTick() {
|
|
||||||
return THREAD_MX_BEAN.getCurrentThreadCpuTime();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
21
src/main/java/org/xbib/metrics/CpuTimeClock.java
Normal file
21
src/main/java/org/xbib/metrics/CpuTimeClock.java
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package org.xbib.metrics;
|
||||||
|
|
||||||
|
import java.lang.management.ManagementFactory;
|
||||||
|
import java.lang.management.ThreadMXBean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A clock implementation which returns the current thread's CPU time.
|
||||||
|
*/
|
||||||
|
class CpuTimeClock implements Clock {
|
||||||
|
private static final ThreadMXBean THREAD_MX_BEAN = ManagementFactory.getThreadMXBean();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTick() {
|
||||||
|
return THREAD_MX_BEAN.getCurrentThreadCpuTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTime() {
|
||||||
|
return System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
}
|
|
@ -15,7 +15,8 @@ public class ExpWeightedMovingAverage {
|
||||||
private static final double M5_ALPHA = 1 - Math.exp(-5 / 60.0 / 5);
|
private static final double M5_ALPHA = 1 - Math.exp(-5 / 60.0 / 5);
|
||||||
private static final double M15_ALPHA = 1 - Math.exp(-5 / 60.0 / 15);
|
private static final double M15_ALPHA = 1 - Math.exp(-5 / 60.0 / 15);
|
||||||
private final LongAdder uncounted = new LongAdder();
|
private final LongAdder uncounted = new LongAdder();
|
||||||
private final double alpha, interval;
|
private final double alpha;
|
||||||
|
private final double interval;
|
||||||
private volatile boolean initialized = false;
|
private volatile boolean initialized = false;
|
||||||
private volatile double rate = 0.0;
|
private volatile double rate = 0.0;
|
||||||
|
|
||||||
|
|
|
@ -72,10 +72,12 @@ public class ExponentiallyDecayingReservoir implements Reservoir {
|
||||||
this.nextScaleTime = new AtomicLong(clock.getTick() + RESCALE_THRESHOLD);
|
this.nextScaleTime = new AtomicLong(clock.getTick() + RESCALE_THRESHOLD);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public int size() {
|
public int size() {
|
||||||
return (int) min(size, count.get());
|
return (int) min(size, count.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void update(long value) {
|
public void update(long value) {
|
||||||
update(value, currentTimeInSeconds());
|
update(value, currentTimeInSeconds());
|
||||||
}
|
}
|
||||||
|
@ -119,6 +121,7 @@ public class ExponentiallyDecayingReservoir implements Reservoir {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public Snapshot getSnapshot() {
|
public Snapshot getSnapshot() {
|
||||||
lockForRegularUsage();
|
lockForRegularUsage();
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -14,6 +14,7 @@ package org.xbib.metrics;
|
||||||
*
|
*
|
||||||
* @param <T> the type of the metric's value
|
* @param <T> the type of the metric's value
|
||||||
*/
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
public interface Gauge<T> extends Metric {
|
public interface Gauge<T> extends Metric {
|
||||||
/**
|
/**
|
||||||
* Returns the metric's current value.
|
* Returns the metric's current value.
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class Histogram implements Metric, Sampling, Count {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inc(String index, String type, String id) {
|
public void inc(String index, String type, String id) {
|
||||||
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -55,7 +55,7 @@ public class Histogram implements Metric, Sampling, Count {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dec(String index, String type, String id) {
|
public void dec(String index, String type, String id) {
|
||||||
|
// not used
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -46,12 +46,7 @@ public class Meter implements Metered {
|
||||||
|
|
||||||
public void spawn(long intervalSeconds) {
|
public void spawn(long intervalSeconds) {
|
||||||
this.future = Executors.newScheduledThreadPool(1)
|
this.future = Executors.newScheduledThreadPool(1)
|
||||||
.scheduleAtFixedRate(new Runnable() {
|
.scheduleAtFixedRate(this::tickIfNecessary, intervalSeconds, intervalSeconds, TimeUnit.SECONDS);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
tickIfNecessary();
|
|
||||||
}
|
|
||||||
}, intervalSeconds, intervalSeconds, TimeUnit.SECONDS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
|
|
|
@ -3,16 +3,12 @@ package org.xbib.metrics;
|
||||||
/**
|
/**
|
||||||
* A filter used to determine whether or not a metric should be reported, among other things.
|
* A filter used to determine whether or not a metric should be reported, among other things.
|
||||||
*/
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
public interface MetricFilter {
|
public interface MetricFilter {
|
||||||
/**
|
/**
|
||||||
* Matches all metrics, regardless of type or name.
|
* Matches all metrics, regardless of type or name.
|
||||||
*/
|
*/
|
||||||
MetricFilter ALL = new MetricFilter() {
|
MetricFilter ALL = (name, metric) -> true;
|
||||||
@Override
|
|
||||||
public boolean matches(MetricName name, Metric metric) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if the metric matches the filter; {@code false} otherwise.
|
* Returns {@code true} if the metric matches the filter; {@code false} otherwise.
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
**/
|
**/
|
||||||
public static MetricName join(MetricName... parts) {
|
public static MetricName join(MetricName... parts) {
|
||||||
final StringBuilder nameBuilder = new StringBuilder();
|
final StringBuilder nameBuilder = new StringBuilder();
|
||||||
final Map<String, String> tags = new HashMap<String, String>();
|
final Map<String, String> tags = new HashMap<>();
|
||||||
|
|
||||||
boolean first = true;
|
boolean first = true;
|
||||||
|
|
||||||
|
@ -92,16 +92,13 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
if (name == null || name.isEmpty()) {
|
if (name == null || name.isEmpty()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first) {
|
if (first) {
|
||||||
first = false;
|
first = false;
|
||||||
} else {
|
} else {
|
||||||
builder.append(SEPARATOR);
|
builder.append(SEPARATOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.append(name);
|
builder.append(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +106,6 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
if (tags == null || tags.isEmpty()) {
|
if (tags == null || tags.isEmpty()) {
|
||||||
return EMPTY_TAGS;
|
return EMPTY_TAGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Collections.unmodifiableMap(tags);
|
return Collections.unmodifiableMap(tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +128,6 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
*/
|
*/
|
||||||
public MetricName resolve(String p) {
|
public MetricName resolve(String p) {
|
||||||
final String next;
|
final String next;
|
||||||
|
|
||||||
if (p != null && !p.isEmpty()) {
|
if (p != null && !p.isEmpty()) {
|
||||||
if (key != null && !key.isEmpty()) {
|
if (key != null && !key.isEmpty()) {
|
||||||
next = key + SEPARATOR + p;
|
next = key + SEPARATOR + p;
|
||||||
|
@ -142,7 +137,6 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
} else {
|
} else {
|
||||||
next = this.key;
|
next = this.key;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MetricName(next, tags);
|
return new MetricName(next, tags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,9 +147,9 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
* @return A newly created metric name with the specified tags associated with it.
|
* @return A newly created metric name with the specified tags associated with it.
|
||||||
*/
|
*/
|
||||||
public MetricName tagged(Map<String, String> add) {
|
public MetricName tagged(Map<String, String> add) {
|
||||||
final Map<String, String> tags = new HashMap<String, String>(add);
|
final Map<String, String> map = new HashMap<>(add);
|
||||||
tags.putAll(this.tags);
|
map.putAll(this.tags);
|
||||||
return new MetricName(key, tags);
|
return new MetricName(key, map);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -171,17 +165,13 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
if (pairs == null) {
|
if (pairs == null) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pairs.length % 2 != 0) {
|
if (pairs.length % 2 != 0) {
|
||||||
throw new IllegalArgumentException("Argument count must be even");
|
throw new IllegalArgumentException("Argument count must be even");
|
||||||
}
|
}
|
||||||
|
final Map<String, String> add = new HashMap<>();
|
||||||
final Map<String, String> add = new HashMap<String, String>();
|
|
||||||
|
|
||||||
for (int i = 0; i < pairs.length; i += 2) {
|
for (int i = 0; i < pairs.length; i += 2) {
|
||||||
add.put(pairs[i], pairs[i + 1]);
|
add.put(pairs[i], pairs[i + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return tagged(add);
|
return tagged(add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -189,9 +179,7 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
public String toString() {
|
public String toString() {
|
||||||
if (tags.isEmpty()) {
|
if (tags.isEmpty()) {
|
||||||
return key;
|
return key;
|
||||||
//return key + "{}";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return key + tags;
|
return key + tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,17 +197,13 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
if (this == obj) {
|
if (this == obj) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj == null) {
|
if (obj == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getClass() != obj.getClass()) {
|
if (getClass() != obj.getClass()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
MetricName other = (MetricName) obj;
|
MetricName other = (MetricName) obj;
|
||||||
|
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
if (other.key != null) {
|
if (other.key != null) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -227,23 +211,15 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
} else if (!key.equals(other.key)) {
|
} else if (!key.equals(other.key)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return tags.equals(other.tags);
|
return tags.equals(other.tags);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compareTo(MetricName o) {
|
public int compareTo(MetricName o) {
|
||||||
if (o == null) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int c = compareName(key, o.getKey());
|
int c = compareName(key, o.getKey());
|
||||||
|
|
||||||
if (c != 0) {
|
if (c != 0) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compareTags(tags, o.getTags());
|
return compareTags(tags, o.getTags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -251,15 +227,12 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
if (left == null && right == null) {
|
if (left == null && right == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left == null) {
|
if (left == null) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right == null) {
|
if (right == null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return left.compareTo(right);
|
return left.compareTo(right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -267,45 +240,35 @@ public class MetricName implements Comparable<MetricName> {
|
||||||
if (left == null && right == null) {
|
if (left == null && right == null) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (left == null) {
|
if (left == null) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (right == null) {
|
if (right == null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Iterable<String> keys = uniqueSortedKeys(left, right);
|
final Iterable<String> keys = uniqueSortedKeys(left, right);
|
||||||
|
for (final String s : keys) {
|
||||||
for (final String key : keys) {
|
final String a = left.get(s);
|
||||||
final String a = left.get(key);
|
final String b = right.get(s);
|
||||||
final String b = right.get(key);
|
|
||||||
|
|
||||||
if (a == null && b == null) {
|
if (a == null && b == null) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (a == null) {
|
if (a == null) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (b == null) {
|
if (b == null) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int c = a.compareTo(b);
|
int c = a.compareTo(b);
|
||||||
|
|
||||||
if (c != 0) {
|
if (c != 0) {
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Iterable<String> uniqueSortedKeys(Map<String, String> left, Map<String, String> right) {
|
private Iterable<String> uniqueSortedKeys(Map<String, String> left, Map<String, String> right) {
|
||||||
final Set<String> set = new TreeSet<String>(left.keySet());
|
final Set<String> set = new TreeSet<>(left.keySet());
|
||||||
set.addAll(right.keySet());
|
set.addAll(right.keySet());
|
||||||
return set;
|
return set;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,15 @@ import java.util.TreeSet;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A registry of metric instances.
|
* A registry of metric instances.
|
||||||
*/
|
*/
|
||||||
public class MetricRegistry implements MetricSet {
|
public class MetricRegistry implements MetricSet {
|
||||||
|
|
||||||
|
private static final Logger logger = Logger.getLogger(MetricRegistry.class.getName());
|
||||||
private final ConcurrentMap<MetricName, Metric> metrics;
|
private final ConcurrentMap<MetricName, Metric> metrics;
|
||||||
private final List<MetricRegistryListener> listeners;
|
private final List<MetricRegistryListener> listeners;
|
||||||
|
|
||||||
|
@ -23,7 +26,7 @@ public class MetricRegistry implements MetricSet {
|
||||||
* Creates a new {@link MetricRegistry}.
|
* Creates a new {@link MetricRegistry}.
|
||||||
*/
|
*/
|
||||||
public MetricRegistry() {
|
public MetricRegistry() {
|
||||||
this(new ConcurrentHashMap<MetricName, Metric>());
|
this(new ConcurrentHashMap<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,7 +38,7 @@ public class MetricRegistry implements MetricSet {
|
||||||
*/
|
*/
|
||||||
protected MetricRegistry(ConcurrentMap<MetricName, Metric> metricsMap) {
|
protected MetricRegistry(ConcurrentMap<MetricName, Metric> metricsMap) {
|
||||||
this.metrics = metricsMap;
|
this.metrics = metricsMap;
|
||||||
this.listeners = new CopyOnWriteArrayList<MetricRegistryListener>();
|
this.listeners = new CopyOnWriteArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,7 +71,9 @@ public class MetricRegistry implements MetricSet {
|
||||||
}
|
}
|
||||||
final String[] parts = new String[length + 1];
|
final String[] parts = new String[length + 1];
|
||||||
parts[0] = name;
|
parts[0] = name;
|
||||||
|
if (names != null) {
|
||||||
System.arraycopy(names, 0, parts, 1, length);
|
System.arraycopy(names, 0, parts, 1, length);
|
||||||
|
}
|
||||||
return MetricName.build(parts);
|
return MetricName.build(parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +85,7 @@ public class MetricRegistry implements MetricSet {
|
||||||
* @see #register(MetricName, Metric)
|
* @see #register(MetricName, Metric)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Metric> T register(String name, T metric) throws IllegalArgumentException {
|
public <T extends Metric> T register(String name, T metric) {
|
||||||
return register(MetricName.build(name), metric);
|
return register(MetricName.build(name), metric);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,7 +99,7 @@ public class MetricRegistry implements MetricSet {
|
||||||
* @throws IllegalArgumentException if the name is already registered
|
* @throws IllegalArgumentException if the name is already registered
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Metric> T register(MetricName name, T metric) throws IllegalArgumentException {
|
public <T extends Metric> T register(MetricName name, T metric) {
|
||||||
if (metric instanceof MetricSet) {
|
if (metric instanceof MetricSet) {
|
||||||
registerAll(name, (MetricSet) metric);
|
registerAll(name, (MetricSet) metric);
|
||||||
} else {
|
} else {
|
||||||
|
@ -115,7 +120,7 @@ public class MetricRegistry implements MetricSet {
|
||||||
* @param metrics a set of metrics
|
* @param metrics a set of metrics
|
||||||
* @throws IllegalArgumentException if any of the names are already registered
|
* @throws IllegalArgumentException if any of the names are already registered
|
||||||
*/
|
*/
|
||||||
public void registerAll(MetricSet metrics) throws IllegalArgumentException {
|
public void registerAll(MetricSet metrics) {
|
||||||
registerAll(null, metrics);
|
registerAll(null, metrics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,6 +373,7 @@ public class MetricRegistry implements MetricSet {
|
||||||
try {
|
try {
|
||||||
return register(name, builder.newMetric());
|
return register(name, builder.newMetric());
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.log(Level.WARNING, e.getMessage(), e);
|
||||||
final Metric added = metrics.get(name);
|
final Metric added = metrics.get(name);
|
||||||
if (builder.isInstance(added)) {
|
if (builder.isInstance(added)) {
|
||||||
return (T) added;
|
return (T) added;
|
||||||
|
@ -379,7 +385,7 @@ public class MetricRegistry implements MetricSet {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private <T extends Metric> SortedMap<MetricName, T> getMetrics(Class<T> klass, MetricFilter filter) {
|
private <T extends Metric> SortedMap<MetricName, T> getMetrics(Class<T> klass, MetricFilter filter) {
|
||||||
final TreeMap<MetricName, T> timers = new TreeMap<MetricName, T>();
|
final TreeMap<MetricName, T> timers = new TreeMap<>();
|
||||||
for (Map.Entry<MetricName, Metric> entry : metrics.entrySet()) {
|
for (Map.Entry<MetricName, Metric> entry : metrics.entrySet()) {
|
||||||
if (klass.isInstance(entry.getValue()) && filter.matches(entry.getKey(),
|
if (klass.isInstance(entry.getValue()) && filter.matches(entry.getKey(),
|
||||||
entry.getValue())) {
|
entry.getValue())) {
|
||||||
|
@ -433,11 +439,8 @@ public class MetricRegistry implements MetricSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerAll(MetricName prefix, MetricSet metrics) throws IllegalArgumentException {
|
private void registerAll(MetricName prefixName, MetricSet metrics) {
|
||||||
if (prefix == null) {
|
MetricName prefix = prefixName == null ? MetricName.EMPTY : prefixName;
|
||||||
prefix = MetricName.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Map.Entry<MetricName, Metric> entry : metrics.getMetrics().entrySet()) {
|
for (Map.Entry<MetricName, Metric> entry : metrics.getMetrics().entrySet()) {
|
||||||
if (entry.getValue() instanceof MetricSet) {
|
if (entry.getValue() instanceof MetricSet) {
|
||||||
registerAll(MetricName.join(prefix, entry.getKey()), (MetricSet) entry.getValue());
|
registerAll(MetricName.join(prefix, entry.getKey()), (MetricSet) entry.getValue());
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Map;
|
||||||
*
|
*
|
||||||
* @see MetricRegistry#registerAll(MetricSet)
|
* @see MetricRegistry#registerAll(MetricSet)
|
||||||
*/
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
public interface MetricSet extends Metric {
|
public interface MetricSet extends Metric {
|
||||||
/**
|
/**
|
||||||
* A map of metric names to metrics.
|
* A map of metric names to metrics.
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.xbib.metrics;
|
||||||
/**
|
/**
|
||||||
* An object which samples values.
|
* An object which samples values.
|
||||||
*/
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
public interface Sampling {
|
public interface Sampling {
|
||||||
/**
|
/**
|
||||||
* Returns a snapshot of the values.
|
* Returns a snapshot of the values.
|
||||||
|
|
|
@ -3,9 +3,9 @@ package org.xbib.metrics;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A statistical snapshot of a {@link Snapshot}.
|
* A {@link Snapshot}.
|
||||||
*/
|
*/
|
||||||
public abstract class Snapshot {
|
public interface Snapshot {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value at the given quantile.
|
* Returns the value at the given quantile.
|
||||||
|
@ -13,109 +13,97 @@ public abstract class Snapshot {
|
||||||
* @param quantile a given quantile, in {@code [0..1]}
|
* @param quantile a given quantile, in {@code [0..1]}
|
||||||
* @return the value in the distribution at {@code quantile}
|
* @return the value in the distribution at {@code quantile}
|
||||||
*/
|
*/
|
||||||
public abstract double getValue(double quantile);
|
double getValue(double quantile);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the entire set of values in the snapshot.
|
* Returns the entire set of values in the snapshot.
|
||||||
*
|
*
|
||||||
* @return the entire set of values
|
* @return the entire set of values
|
||||||
*/
|
*/
|
||||||
public abstract long[] getValues();
|
long[] getValues();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of values in the snapshot.
|
* Returns the number of values in the snapshot.
|
||||||
*
|
*
|
||||||
* @return the number of values
|
* @return the number of values
|
||||||
*/
|
*/
|
||||||
public abstract int size();
|
int size();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the median value in the distribution.
|
* Returns the median value in the distribution.
|
||||||
*
|
*
|
||||||
* @return the median value
|
* @return the median value
|
||||||
*/
|
*/
|
||||||
public double getMedian() {
|
double getMedian();
|
||||||
return getValue(0.5);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value at the 75th percentile in the distribution.
|
* Returns the value at the 75th percentile in the distribution.
|
||||||
*
|
*
|
||||||
* @return the value at the 75th percentile
|
* @return the value at the 75th percentile
|
||||||
*/
|
*/
|
||||||
public double get75thPercentile() {
|
double get75thPercentile();
|
||||||
return getValue(0.75);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value at the 95th percentile in the distribution.
|
* Returns the value at the 95th percentile in the distribution.
|
||||||
*
|
*
|
||||||
* @return the value at the 95th percentile
|
* @return the value at the 95th percentile
|
||||||
*/
|
*/
|
||||||
public double get95thPercentile() {
|
double get95thPercentile();
|
||||||
return getValue(0.95);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value at the 98th percentile in the distribution.
|
* Returns the value at the 98th percentile in the distribution.
|
||||||
*
|
*
|
||||||
* @return the value at the 98th percentile
|
* @return the value at the 98th percentile
|
||||||
*/
|
*/
|
||||||
public double get98thPercentile() {
|
double get98thPercentile();
|
||||||
return getValue(0.98);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value at the 99th percentile in the distribution.
|
* Returns the value at the 99th percentile in the distribution.
|
||||||
*
|
*
|
||||||
* @return the value at the 99th percentile
|
* @return the value at the 99th percentile
|
||||||
*/
|
*/
|
||||||
public double get99thPercentile() {
|
double get99thPercentile();
|
||||||
return getValue(0.99);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value at the 99.9th percentile in the distribution.
|
* Returns the value at the 99.9th percentile in the distribution.
|
||||||
*
|
*
|
||||||
* @return the value at the 99.9th percentile
|
* @return the value at the 99.9th percentile
|
||||||
*/
|
*/
|
||||||
public double get999thPercentile() {
|
double get999thPercentile();
|
||||||
return getValue(0.999);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the highest value in the snapshot.
|
* Returns the highest value in the snapshot.
|
||||||
*
|
*
|
||||||
* @return the highest value
|
* @return the highest value
|
||||||
*/
|
*/
|
||||||
public abstract long getMax();
|
long getMax();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the arithmetic mean of the values in the snapshot.
|
* Returns the arithmetic mean of the values in the snapshot.
|
||||||
*
|
*
|
||||||
* @return the arithmetic mean
|
* @return the arithmetic mean
|
||||||
*/
|
*/
|
||||||
public abstract double getMean();
|
double getMean();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the lowest value in the snapshot.
|
* Returns the lowest value in the snapshot.
|
||||||
*
|
*
|
||||||
* @return the lowest value
|
* @return the lowest value
|
||||||
*/
|
*/
|
||||||
public abstract long getMin();
|
long getMin();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the standard deviation of the values in the snapshot.
|
* Returns the standard deviation of the values in the snapshot.
|
||||||
*
|
*
|
||||||
* @return the standard value
|
* @return the standard value
|
||||||
*/
|
*/
|
||||||
public abstract double getStdDev();
|
double getStdDev();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the values of the snapshot to the given stream.
|
* Writes the values of the snapshot to the given stream.
|
||||||
*
|
*
|
||||||
* @param output an output stream
|
* @param output an output stream
|
||||||
*/
|
*/
|
||||||
public abstract void dump(OutputStream output);
|
void dump(OutputStream output);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
20
src/main/java/org/xbib/metrics/UserTimeClock.java
Normal file
20
src/main/java/org/xbib/metrics/UserTimeClock.java
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
package org.xbib.metrics;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A clock implementation which returns the current time in epoch nanoseconds.
|
||||||
|
*/
|
||||||
|
class UserTimeClock implements Clock {
|
||||||
|
|
||||||
|
static final Clock DEFAULT = new UserTimeClock();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTick() {
|
||||||
|
return System.nanoTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getTime() {
|
||||||
|
return System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,12 +6,11 @@ import java.io.PrintWriter;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Comparator;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A statistical snapshot of a {@link WeightedSnapshot}.
|
* A statistical snapshot of a {@link WeightedSnapshot}.
|
||||||
*/
|
*/
|
||||||
public class WeightedSnapshot extends Snapshot {
|
public class WeightedSnapshot implements Snapshot {
|
||||||
|
|
||||||
private final long[] values;
|
private final long[] values;
|
||||||
private final double[] normWeights;
|
private final double[] normWeights;
|
||||||
|
@ -25,9 +24,7 @@ public class WeightedSnapshot extends Snapshot {
|
||||||
public WeightedSnapshot(Collection<WeightedSample> values) {
|
public WeightedSnapshot(Collection<WeightedSample> values) {
|
||||||
final WeightedSample[] copy = values.toArray(new WeightedSample[]{});
|
final WeightedSample[] copy = values.toArray(new WeightedSample[]{});
|
||||||
|
|
||||||
Arrays.sort(copy, new Comparator<WeightedSample>() {
|
Arrays.sort(copy, (o1, o2) -> {
|
||||||
@Override
|
|
||||||
public int compare(WeightedSample o1, WeightedSample o2) {
|
|
||||||
if (o1.value > o2.value) {
|
if (o1.value > o2.value) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -35,21 +32,20 @@ public class WeightedSnapshot extends Snapshot {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.values = new long[copy.length];
|
this.values = new long[copy.length];
|
||||||
this.normWeights = new double[copy.length];
|
this.normWeights = new double[copy.length];
|
||||||
this.quantiles = new double[copy.length];
|
this.quantiles = new double[copy.length];
|
||||||
|
|
||||||
double sumWeight = 0;
|
double sumWeight = 0.0f;
|
||||||
for (WeightedSample sample : copy) {
|
for (WeightedSample sample : copy) {
|
||||||
sumWeight += sample.weight;
|
sumWeight += sample.weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < copy.length; i++) {
|
for (int i = 0; i < copy.length; i++) {
|
||||||
this.values[i] = copy[i].value;
|
this.values[i] = copy[i].value;
|
||||||
this.normWeights[i] = copy[i].weight / sumWeight;
|
this.normWeights[i] = safeDivide(copy[i].weight, sumWeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 1; i < copy.length; i++) {
|
for (int i = 1; i < copy.length; i++) {
|
||||||
|
@ -57,6 +53,88 @@ public class WeightedSnapshot extends Snapshot {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static double safeDivide(double dividend, double divisor) {
|
||||||
|
if (Double.compare(divisor, Double.NaN) == 0) {
|
||||||
|
return Double.NaN;
|
||||||
|
}
|
||||||
|
if (Double.compare(dividend, Double.NaN) == 0) {
|
||||||
|
return Double.NaN;
|
||||||
|
}
|
||||||
|
if (Double.compare(divisor, 0.0) == 0) {
|
||||||
|
if (Double.compare(dividend, 0.0) == -1) {
|
||||||
|
return Double.NEGATIVE_INFINITY;
|
||||||
|
}
|
||||||
|
return Double.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
|
if (Double.compare(divisor, -0.0) == 0) {
|
||||||
|
if (Double.compare(dividend, -0.0) == 1) {
|
||||||
|
return Double.NEGATIVE_INFINITY;
|
||||||
|
}
|
||||||
|
return Double.POSITIVE_INFINITY;
|
||||||
|
}
|
||||||
|
return dividend / divisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the median value in the distribution.
|
||||||
|
*
|
||||||
|
* @return the median value
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double getMedian() {
|
||||||
|
return getValue(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value at the 75th percentile in the distribution.
|
||||||
|
*
|
||||||
|
* @return the value at the 75th percentile
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double get75thPercentile() {
|
||||||
|
return getValue(0.75);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value at the 95th percentile in the distribution.
|
||||||
|
*
|
||||||
|
* @return the value at the 95th percentile
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double get95thPercentile() {
|
||||||
|
return getValue(0.95);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value at the 98th percentile in the distribution.
|
||||||
|
*
|
||||||
|
* @return the value at the 98th percentile
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double get98thPercentile() {
|
||||||
|
return getValue(0.98);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value at the 99th percentile in the distribution.
|
||||||
|
*
|
||||||
|
* @return the value at the 99th percentile
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double get99thPercentile() {
|
||||||
|
return getValue(0.99);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the value at the 99.9th percentile in the distribution.
|
||||||
|
*
|
||||||
|
* @return the value at the 99.9th percentile
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public double get999thPercentile() {
|
||||||
|
return getValue(0.999);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the value at the given quantile.
|
* Returns the value at the given quantile.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue