com.google.gerrit.metrics.Description.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gerrit.metrics.Description.java

Source

// 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();
    }
}