com.google.gerrit.metrics.dropwizard.MetricJson.java Source code

Java tutorial

Introduction

Here is the source code for com.google.gerrit.metrics.dropwizard.MetricJson.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.dropwizard;

import com.codahale.metrics.Counter;
import com.codahale.metrics.Gauge;
import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.codahale.metrics.Metric;
import com.codahale.metrics.Snapshot;
import com.codahale.metrics.Timer;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.gerrit.metrics.Description;
import com.google.gerrit.metrics.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

class MetricJson {
    String description;
    String unit;
    Boolean constant;
    Boolean rate;
    Boolean gauge;
    Boolean cumulative;

    Long count;
    Object value;

    Double rate_1m;
    Double rate_5m;
    Double rate_15m;
    Double rate_mean;

    Double p50;
    Double p75;
    Double p95;
    Double p98;
    Double p99;
    Double p99_9;

    Double min;
    Double avg;
    Double max;
    Double sum;
    Double std_dev;

    List<FieldJson> fields;
    Map<String, Object> buckets;

    MetricJson(Metric metric, ImmutableMap<String, String> atts, boolean dataOnly) {
        if (!dataOnly) {
            description = atts.get(Description.DESCRIPTION);
            unit = atts.get(Description.UNIT);
            constant = toBool(atts, Description.CONSTANT);
            rate = toBool(atts, Description.RATE);
            gauge = toBool(atts, Description.GAUGE);
            cumulative = toBool(atts, Description.CUMULATIVE);
        }
        init(metric, atts);
    }

    private void init(Metric metric, ImmutableMap<String, String> atts) {
        if (metric instanceof BucketedMetric) {
            BucketedMetric m = (BucketedMetric) metric;
            if (m.getTotal() != null) {
                init(m.getTotal(), atts);
            }

            Field<?>[] fieldList = m.getFields();
            fields = new ArrayList<>(fieldList.length);
            for (Field<?> f : fieldList) {
                fields.add(new FieldJson(f));
            }
            buckets = makeBuckets(fieldList, m.getCells(), atts);

        } else if (metric instanceof Counter) {
            Counter c = (Counter) metric;
            count = c.getCount();

        } else if (metric instanceof Gauge) {
            Gauge<?> g = (Gauge<?>) metric;
            value = g.getValue();

        } else if (metric instanceof Meter) {
            Meter m = (Meter) metric;
            count = m.getCount();
            rate_1m = m.getOneMinuteRate();
            rate_5m = m.getFiveMinuteRate();
            rate_15m = m.getFifteenMinuteRate();

        } else if (metric instanceof Timer) {
            Timer m = (Timer) metric;
            Snapshot s = m.getSnapshot();
            count = m.getCount();
            rate_1m = m.getOneMinuteRate();
            rate_5m = m.getFiveMinuteRate();
            rate_15m = m.getFifteenMinuteRate();

            double div = Description.getTimeUnit(atts.get(Description.UNIT)).toNanos(1);
            p50 = s.getMedian() / div;
            p75 = s.get75thPercentile() / div;
            p95 = s.get95thPercentile() / div;
            p98 = s.get98thPercentile() / div;
            p99 = s.get99thPercentile() / div;
            p99_9 = s.get999thPercentile() / div;

            min = s.getMin() / div;
            max = s.getMax() / div;
            std_dev = s.getStdDev() / div;

        } else if (metric instanceof Histogram) {
            Histogram m = (Histogram) metric;
            Snapshot s = m.getSnapshot();
            count = m.getCount();

            p50 = s.getMedian();
            p75 = s.get75thPercentile();
            p95 = s.get95thPercentile();
            p98 = s.get98thPercentile();
            p99 = s.get99thPercentile();
            p99_9 = s.get999thPercentile();

            min = (double) s.getMin();
            avg = (double) s.getMean();
            max = (double) s.getMax();
            sum = s.getMean() * m.getCount();
            std_dev = s.getStdDev();
        }
    }

    private static Boolean toBool(ImmutableMap<String, String> atts, String key) {
        return Description.TRUE_VALUE.equals(atts.get(key)) ? true : null;
    }

    @SuppressWarnings("unchecked")
    private static Map<String, Object> makeBuckets(Field<?>[] fields, Map<?, Metric> metrics,
            ImmutableMap<String, String> atts) {
        if (fields.length == 1) {
            Function<Object, String> fmt = (Function<Object, String>) fields[0].formatter();
            Map<String, Object> out = new TreeMap<>();
            for (Map.Entry<?, Metric> e : metrics.entrySet()) {
                out.put(fmt.apply(e.getKey()), new MetricJson(e.getValue(), atts, true));
            }
            return out;
        }

        Map<String, Object> out = new TreeMap<>();
        for (Map.Entry<?, Metric> e : metrics.entrySet()) {
            ImmutableList<Object> keys = (ImmutableList<Object>) e.getKey();
            Map<String, Object> dst = out;

            for (int i = 0; i < fields.length - 1; i++) {
                Function<Object, String> fmt = (Function<Object, String>) fields[i].formatter();
                String key = fmt.apply(keys.get(i));
                Map<String, Object> t = (Map<String, Object>) dst.get(key);
                if (t == null) {
                    t = new TreeMap<>();
                    dst.put(key, t);
                }
                dst = t;
            }

            Function<Object, String> fmt = (Function<Object, String>) fields[fields.length - 1].formatter();
            dst.put(fmt.apply(keys.get(fields.length - 1)), new MetricJson(e.getValue(), atts, true));
        }
        return out;
    }

    static class FieldJson {
        String name;
        String type;
        String description;

        FieldJson(Field<?> field) {
            this.name = field.getName();
            this.description = field.getDescription();
            this.type = Enum.class.isAssignableFrom(field.getType()) ? field.getType().getSimpleName() : null;
        }
    }
}