200 lines
6.2 KiB
Java
200 lines
6.2 KiB
Java
// Copyright (C) 2015 The Android Open Source Project
|
|
//
|
|
// 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.google.gerrit.metrics;
|
|
|
|
import com.google.common.base.Strings;
|
|
import com.google.common.collect.ImmutableMap;
|
|
import com.google.common.collect.Maps;
|
|
import java.util.Map;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
/** Describes a metric created by {@link MetricMaker}. */
|
|
public class Description {
|
|
public static final String DESCRIPTION = "DESCRIPTION";
|
|
public static final String UNIT = "UNIT";
|
|
public static final String CUMULATIVE = "CUMULATIVE";
|
|
public static final String RATE = "RATE";
|
|
public static final String GAUGE = "GAUGE";
|
|
public static final String CONSTANT = "CONSTANT";
|
|
public static final String FIELD_ORDERING = "FIELD_ORDERING";
|
|
public static final String TRUE_VALUE = "1";
|
|
|
|
public static class Units {
|
|
public static final String SECONDS = "seconds";
|
|
public static final String MILLISECONDS = "milliseconds";
|
|
public static final String MICROSECONDS = "microseconds";
|
|
public static final String NANOSECONDS = "nanoseconds";
|
|
|
|
public static final String BYTES = "bytes";
|
|
|
|
private Units() {}
|
|
}
|
|
|
|
public enum FieldOrdering {
|
|
/** Default ordering places fields at end of the parent metric name. */
|
|
AT_END,
|
|
|
|
/**
|
|
* Splits the metric name by inserting field values before the last '/' in the metric name. For
|
|
* example {@code "plugins/replication/push_latency"} with a {@code Field.ofString("remote")}
|
|
* will create submetrics named {@code "plugins/replication/some-server/push_latency"}.
|
|
*/
|
|
PREFIX_FIELDS_BASENAME;
|
|
}
|
|
|
|
private final Map<String, String> annotations;
|
|
|
|
/**
|
|
* Describe a metric.
|
|
*
|
|
* @param helpText a short one-sentence string explaining the values captured by the metric. This
|
|
* may be made available to administrators as documentation in the reporting tools.
|
|
*/
|
|
public Description(String helpText) {
|
|
annotations = Maps.newLinkedHashMapWithExpectedSize(4);
|
|
annotations.put(DESCRIPTION, helpText);
|
|
}
|
|
|
|
/**
|
|
* Set unit used to describe the value.
|
|
*
|
|
* @param unitName name of the unit, e.g. "requests", "seconds", etc.
|
|
* @return this
|
|
*/
|
|
public Description setUnit(String unitName) {
|
|
annotations.put(UNIT, unitName);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Mark the value as constant for the life of this process. Typically used for software versions,
|
|
* command line arguments, etc. that cannot change without a process restart.
|
|
*
|
|
* @return this
|
|
*/
|
|
public Description setConstant() {
|
|
annotations.put(CONSTANT, TRUE_VALUE);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Indicates the metric may be usefully interpreted as a count over short periods of time, such as
|
|
* request arrival rate. May only be applied to a {@link Counter0}.
|
|
*
|
|
* @return this
|
|
*/
|
|
public Description setRate() {
|
|
annotations.put(RATE, TRUE_VALUE);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Instantaneously sampled value that may increase or decrease at a later time. Memory allocated
|
|
* or open network connections are examples of gauges.
|
|
*
|
|
* @return this
|
|
*/
|
|
public Description setGauge() {
|
|
annotations.put(GAUGE, TRUE_VALUE);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Indicates the metric accumulates over the lifespan of the process. A {@link Counter0} like
|
|
* total requests handled accumulates over the process and should be {@code setCumulative()}.
|
|
*
|
|
* @return this
|
|
*/
|
|
public Description setCumulative() {
|
|
annotations.put(CUMULATIVE, TRUE_VALUE);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Configure how fields are ordered into submetric names.
|
|
*
|
|
* @param ordering field ordering
|
|
* @return this
|
|
*/
|
|
public Description setFieldOrdering(FieldOrdering ordering) {
|
|
annotations.put(FIELD_ORDERING, ordering.name());
|
|
return this;
|
|
}
|
|
|
|
/** @return true if the metric value never changes after startup. */
|
|
public boolean isConstant() {
|
|
return TRUE_VALUE.equals(annotations.get(CONSTANT));
|
|
}
|
|
|
|
/** @return true if the metric may be interpreted as a rate over time. */
|
|
public boolean isRate() {
|
|
return TRUE_VALUE.equals(annotations.get(RATE));
|
|
}
|
|
|
|
/** @return true if the metric is an instantaneous sample. */
|
|
public boolean isGauge() {
|
|
return TRUE_VALUE.equals(annotations.get(GAUGE));
|
|
}
|
|
|
|
/** @return true if the metric accumulates over the lifespan of the process. */
|
|
public boolean isCumulative() {
|
|
return TRUE_VALUE.equals(annotations.get(CUMULATIVE));
|
|
}
|
|
|
|
/** @return the suggested field ordering. */
|
|
public FieldOrdering getFieldOrdering() {
|
|
String o = annotations.get(FIELD_ORDERING);
|
|
return o != null ? FieldOrdering.valueOf(o) : FieldOrdering.AT_END;
|
|
}
|
|
|
|
/**
|
|
* Decode the unit as a unit of time.
|
|
*
|
|
* @return valid time unit.
|
|
* @throws IllegalArgumentException if the unit is not a valid unit of time.
|
|
*/
|
|
public TimeUnit getTimeUnit() {
|
|
return getTimeUnit(annotations.get(UNIT));
|
|
}
|
|
|
|
private static final ImmutableMap<String, TimeUnit> TIME_UNITS =
|
|
ImmutableMap.of(
|
|
Units.NANOSECONDS, TimeUnit.NANOSECONDS,
|
|
Units.MICROSECONDS, TimeUnit.MICROSECONDS,
|
|
Units.MILLISECONDS, TimeUnit.MILLISECONDS,
|
|
Units.SECONDS, TimeUnit.SECONDS);
|
|
|
|
public static TimeUnit getTimeUnit(String unit) {
|
|
if (Strings.isNullOrEmpty(unit)) {
|
|
throw new IllegalArgumentException("no unit configured");
|
|
}
|
|
TimeUnit u = TIME_UNITS.get(unit);
|
|
if (u == null) {
|
|
throw new IllegalArgumentException(String.format("unit %s not TimeUnit", unit));
|
|
}
|
|
return u;
|
|
}
|
|
|
|
/** @return immutable copy of all annotations (configurable properties). */
|
|
public ImmutableMap<String, String> getAnnotations() {
|
|
return ImmutableMap.copyOf(annotations);
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return annotations.toString();
|
|
}
|
|
}
|