-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add distribution metric to semantic-core and ffwd-reporter (#79)
* Add distribution metric to semantic-core and ffwd-reporter * Update javadoc * Fix build failure * Switch to ffw-java-client version 0.22 * Address PR comments: 1. Remove SemanticMetricRegistryListenerV2 2. Added Default methods to SemanticMetricRegistryListener 3. We understand that there is a chance for SemanticMetricRegistry to call a no op methods. This can lead to confusion hopefully users of this lib will look at the source code or documentation. * Change the name of Distribution Implementation and add Threadsafety * Add javadoc to Distribution * Revert SemanticMetricRegistryAdapter changes and remove MetricRegistryListener * Addresse PR's comments: remove code re-ordering and rename SemanticMetricRegistry.getDistribution * Revert re-ordering in FastForwardReporter * Additional info regarding Distribution output * Update copyright licence agremment header
- Loading branch information
Showing
15 changed files
with
379 additions
and
29 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
66 changes: 66 additions & 0 deletions
66
core/src/main/java/com/spotify/metrics/core/Distribution.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,66 @@ | ||
/* | ||
* Copyright (C) 2016 - 2020 Spotify AB. | ||
* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you 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.spotify.metrics.core; | ||
|
||
import com.codahale.metrics.Counting; | ||
import com.codahale.metrics.Metric; | ||
|
||
import java.nio.ByteBuffer; | ||
|
||
/** | ||
* {@link Distribution} is a simple interface that allows users to record measurements | ||
* to compute rank statistics on data distribution not just local source. | ||
* | ||
* <p>Every implementation should produce a serialized data sketch in a byteBuffer | ||
* as this metric point value. For more information on how this is handled upstream, | ||
* Please refer to | ||
* <a href="https://github.com/spotify/ffwd-client-java/blob/master/ffwd- | ||
* client/src/main/java/com/spotify/ffwd/FastForward.java#L110"/> FastForward Java client</a> | ||
* | ||
* <p>Unlike traditional histogram, {@link Distribution} doesn't require | ||
* predefined percentile value. Data recorded | ||
* can be used upstream to compute any percentile. | ||
* | ||
* <p>This Distribution doesn't require any binning configuration. | ||
* Just get an instance through SemanticMetricBuilder and record data. | ||
* | ||
* <p> {@link Distribution} is a good choice if you care about percentile accuracy in | ||
* a distributed environment and you want to rely on P99 to set SLO. | ||
*/ | ||
public interface Distribution extends Metric, Counting { | ||
|
||
/** | ||
* Record value from Min.Double to Max.Double. | ||
* @param val | ||
*/ | ||
void record(double val); | ||
|
||
/** | ||
* Return distribution point value and flush. | ||
* When this method is called every internal state | ||
* is reset and a new recording starts. | ||
* | ||
* @return | ||
*/ | ||
ByteBuffer getValueAndFlush(); | ||
|
||
} |
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
88 changes: 88 additions & 0 deletions
88
core/src/main/java/com/spotify/metrics/core/SemanticMetricDistribution.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,88 @@ | ||
/* | ||
* Copyright (C) 2016 - 2020 Spotify AB. | ||
* | ||
* Licensed to the Apache Software Foundation (ASF) under one | ||
* or more contributor license agreements. See the NOTICE file | ||
* distributed with this work for additional information | ||
* regarding copyright ownership. The ASF licenses this file | ||
* to you 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.spotify.metrics.core; | ||
|
||
|
||
import com.google.common.annotations.VisibleForTesting; | ||
import com.tdunning.math.stats.TDigest; | ||
|
||
import java.nio.ByteBuffer; | ||
import java.util.concurrent.atomic.AtomicReference; | ||
|
||
/** | ||
* Semantic Metric implementation of {@link Distribution}. | ||
* This implementation ensures threadsafety for recording data | ||
* and retrieving distribution point value. | ||
* | ||
* {@link SemanticMetricDistribution} is backed by Ted Dunning T-digest implementation. | ||
* | ||
* <p>{@link TDigest} "sketch" are generated by clustering real-valued samples and | ||
* retaining the mean and number of samples for each cluster. | ||
* The generated data structure is mergeable and produces fairly | ||
* accurate percentile even for long-tail distribution. | ||
* | ||
* <p> We are using T-digest compression level of 100. | ||
* With that level of compression, our own benchmark using Pareto distribution | ||
* dataset, shows P99 error rate is less than 2% . | ||
* From P99.9 to P99.999 the error rate is slightly higher than 2%. | ||
* | ||
*/ | ||
public final class SemanticMetricDistribution implements Distribution { | ||
|
||
private static final int COMPRESSION_DEFAULT_LEVEL = 100; | ||
private final AtomicReference<TDigest> distRef; | ||
|
||
SemanticMetricDistribution() { | ||
this.distRef = new AtomicReference<>(create()); | ||
} | ||
|
||
@Override | ||
public synchronized void record(double val) { | ||
distRef.get().add(val); | ||
} | ||
|
||
@Override | ||
public java.nio.ByteBuffer getValueAndFlush() { | ||
TDigest curVal; | ||
synchronized (this) { | ||
curVal = distRef.getAndSet(create()); // reset tdigest | ||
} | ||
ByteBuffer byteBuffer = ByteBuffer.allocate(curVal.smallByteSize()); | ||
curVal.asSmallBytes(byteBuffer); | ||
return byteBuffer; | ||
} | ||
|
||
|
||
@Override | ||
public long getCount() { | ||
return distRef.get().size(); | ||
} | ||
|
||
@VisibleForTesting | ||
TDigest tDigest() { | ||
return distRef.get(); | ||
} | ||
|
||
private TDigest create() { | ||
return TDigest.createDigest(COMPRESSION_DEFAULT_LEVEL); | ||
} | ||
} |
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
Oops, something went wrong.