Change to metrics to keep track of when the metric value was first set

This CL also adds IncrementableMetric#reset() methods to allow resetting the
value and start timestamp of IncrementableMetrics.

This is necessary because some backends, like Stackdriver, use non-monotonic
changes in cumulative metric values to detect timeseries restarts. Tracking and
re-setting the start timestamp allows users to track mostly monotonic metrics
which may have non-monotonic discontinuities.

See https://cloud.google.com/monitoring/api/ref_v3/rest/v3/TimeSeries#Point for
more details.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=130795229
This commit is contained in:
shikhman 2016-08-19 14:56:35 -07:00 committed by Ben McIlwain
parent b6eaba08eb
commit 91f8b6da38
7 changed files with 192 additions and 26 deletions

View file

@ -32,7 +32,11 @@ import org.joda.time.Instant;
* <p>The values are stored and set over time. This metric is generally suitable for state
* indicators, such as indicating that a server is in a RUNNING state or in a STOPPED state.
*
* <p>See {@link Counter} for a subclass which is suitable for incremental values.
* <p>See {@link Counter} for a subclass which is suitable for stateful incremental values.
*
* <p>The {@link MetricPoint#interval()} of values of instances of this metric will always have a
* start time equal to the end time, since the metric value represents a point-in-time snapshot with
* no relationship to prior values.
*/
@ThreadSafe
public class StoredMetric<V> extends AbstractMetric<V> implements SettableMetric<V> {
@ -82,7 +86,8 @@ public class StoredMetric<V> extends AbstractMetric<V> implements SettableMetric
final ImmutableList<MetricPoint<V>> getTimestampedValues(Instant timestamp) {
ImmutableList.Builder<MetricPoint<V>> timestampedValues = new Builder<>();
for (Entry<ImmutableList<String>, V> entry : values.entrySet()) {
timestampedValues.add(MetricPoint.create(this, entry.getKey(), timestamp, entry.getValue()));
timestampedValues.add(
MetricPoint.create(this, entry.getKey(), timestamp, timestamp, entry.getValue()));
}
return timestampedValues.build();