summaryrefslogtreecommitdiffstats
path: root/java/com/google/gerrit/metrics/Description.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/google/gerrit/metrics/Description.java')
-rw-r--r--java/com/google/gerrit/metrics/Description.java199
1 files changed, 199 insertions, 0 deletions
diff --git a/java/com/google/gerrit/metrics/Description.java b/java/com/google/gerrit/metrics/Description.java
new file mode 100644
index 0000000000..10568bcd6d
--- /dev/null
+++ b/java/com/google/gerrit/metrics/Description.java
@@ -0,0 +1,199 @@
+// 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();
+ }
+}