com.netflix.servo.monitor.BucketConfig Maven / Gradle / Ivy
/*
* Copyright 2014 Netflix, 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 com.netflix.servo.monitor;
import com.netflix.servo.util.Preconditions;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
/**
* Configuration options for buckets for a {@link BucketTimer}
*
* For example:
*
*
* BucketConfig cfg = new BucketConfig.Builder().withBuckets(new long[]{10L, 20L}).build());
*
*
* will create a configuration that will report buckets for <= 10ms, (10ms, 20ms], and higher
* than 20ms. The default timeUnit is milliseconds but can be changed using the
* {@link BucketConfig.Builder#withTimeUnit(TimeUnit)} method.
*
*
* The user must specify buckets otherwise a {@link NullPointerException} will be generated.
*
*
* See {@link BucketTimer} for more details.
*/
public final class BucketConfig {
/**
* Helper class for constructing BucketConfigs.
*/
public static class Builder {
private TimeUnit timeUnit = TimeUnit.MILLISECONDS;
private long[] buckets = null;
/**
* Sets the timeUnit for the buckets.
*/
public Builder withTimeUnit(TimeUnit timeUnit) {
this.timeUnit = Preconditions.checkNotNull(timeUnit, "timeUnit");
return this;
}
/**
* Sets the buckets to be used.
*
*
* - Each bucket must be unique.
*
- Buckets must be in ascending order (smallest-to-largest).
*
- All bucket counts will be namespaced under the "servo.bucket" tag.
*
- Buckets are incremented in the following way: Given a set of n
* ordered buckets, let n1 = the first bucket. If a given duration is
* less than or equal to n1, the counter for n1 is incremented; else
* perform the same check on n2, n3, etc. If the duration is greater
* the largest bucket, it is added to the 'overflow' bucket. The overflow
* bucket is automatically created.
*
*/
public Builder withBuckets(long[] buckets) {
Preconditions.checkNotNull(buckets, "buckets");
this.buckets = Arrays.copyOf(buckets, buckets.length);
Preconditions.checkArgument(this.buckets.length > 0, "buckets cannot be empty");
Preconditions.checkArgument(isAscending(this.buckets),
"buckets must be in ascending order");
return this;
}
private boolean isAscending(long[] values) {
long last = values[0];
for (int i = 1; i < values.length; i++) {
if (values[i] <= last) {
return false;
}
last = values[i];
}
return true;
}
/**
* Builds a new {@link com.netflix.servo.monitor.BucketConfig}.
*/
public BucketConfig build() {
return new BucketConfig(this);
}
}
private final TimeUnit timeUnit;
private final long[] buckets;
BucketConfig(Builder builder) {
this.timeUnit = builder.timeUnit;
this.buckets = Arrays.copyOf(builder.buckets, builder.buckets.length);
}
/**
* Get the TimeUnit of the buckets.
*/
public TimeUnit getTimeUnit() {
return timeUnit;
}
/**
* Returns an abbreviation for the Bucket's TimeUnit.
*/
public String getTimeUnitAbbreviation() {
switch (timeUnit) {
case DAYS:
return "day";
case HOURS:
return "hr";
case MICROSECONDS:
return "\u00B5s";
case MILLISECONDS:
return "ms";
case MINUTES:
return "min";
case NANOSECONDS:
return "ns";
case SECONDS:
return "s";
default:
return "unkwn";
}
}
/**
* Get a copy of the array that holds the bucket values.
*/
public long[] getBuckets() {
return Arrays.copyOf(buckets, buckets.length);
}
/**
* {@inheritDoc}
*/
@Override
public String toString() {
return "BucketConfig{timeUnit=" + timeUnit
+ ", buckets=" + Arrays.toString(buckets) + '}';
}
/**
* {@inheritDoc}
*/
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (!(o instanceof BucketConfig)) {
return false;
}
final BucketConfig that = (BucketConfig) o;
return timeUnit == that.timeUnit && Arrays.equals(buckets, that.buckets);
}
/**
* {@inheritDoc}
*/
@Override
public int hashCode() {
int result = timeUnit.hashCode();
result = 31 * result + Arrays.hashCode(buckets);
return result;
}
}