1 /* 2 * Copyright 2018, OpenCensus Authors 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package io.opencensus.metrics.export; 18 19 import com.google.auto.value.AutoValue; 20 import io.opencensus.common.ExperimentalApi; 21 import io.opencensus.internal.Utils; 22 import io.opencensus.metrics.export.Value.ValueDistribution; 23 import io.opencensus.metrics.export.Value.ValueDouble; 24 import io.opencensus.metrics.export.Value.ValueLong; 25 import io.opencensus.metrics.export.Value.ValueSummary; 26 import java.util.ArrayList; 27 import java.util.Collections; 28 import java.util.List; 29 import javax.annotation.concurrent.Immutable; 30 31 /** 32 * A {@link Metric} with one or more {@link TimeSeries}. 33 * 34 * @since 0.17 35 */ 36 @ExperimentalApi 37 @Immutable 38 @AutoValue 39 public abstract class Metric { 40 41 Metric() {} 42 43 /** 44 * Creates a {@link Metric}. 45 * 46 * @param metricDescriptor the {@link MetricDescriptor}. 47 * @param timeSeriesList the {@link TimeSeries} list for this metric. 48 * @return a {@code Metric}. 49 * @since 0.17 50 */ 51 public static Metric create(MetricDescriptor metricDescriptor, List<TimeSeries> timeSeriesList) { 52 Utils.checkListElementNotNull( 53 Utils.checkNotNull(timeSeriesList, "timeSeriesList"), "timeSeries"); 54 return createInternal( 55 metricDescriptor, Collections.unmodifiableList(new ArrayList<TimeSeries>(timeSeriesList))); 56 } 57 58 /** 59 * Creates a {@link Metric}. 60 * 61 * @param metricDescriptor the {@link MetricDescriptor}. 62 * @param timeSeries the single {@link TimeSeries} for this metric. 63 * @return a {@code Metric}. 64 * @since 0.17 65 */ 66 public static Metric createWithOneTimeSeries( 67 MetricDescriptor metricDescriptor, TimeSeries timeSeries) { 68 return createInternal( 69 metricDescriptor, Collections.singletonList(Utils.checkNotNull(timeSeries, "timeSeries"))); 70 } 71 72 /** 73 * Creates a {@link Metric}. 74 * 75 * @param metricDescriptor the {@link MetricDescriptor}. 76 * @param timeSeriesList the {@link TimeSeries} list for this metric. 77 * @return a {@code Metric}. 78 * @since 0.17 79 */ 80 private static Metric createInternal( 81 MetricDescriptor metricDescriptor, List<TimeSeries> timeSeriesList) { 82 Utils.checkNotNull(metricDescriptor, "metricDescriptor"); 83 checkTypeMatch(metricDescriptor.getType(), timeSeriesList); 84 return new AutoValue_Metric(metricDescriptor, timeSeriesList); 85 } 86 87 /** 88 * Returns the {@link MetricDescriptor} of this metric. 89 * 90 * @return the {@code MetricDescriptor} of this metric. 91 * @since 0.17 92 */ 93 public abstract MetricDescriptor getMetricDescriptor(); 94 95 /** 96 * Returns the {@link TimeSeries} list for this metric. 97 * 98 * <p>The type of the {@link TimeSeries#getPoints()} must match {@link MetricDescriptor.Type}. 99 * 100 * @return the {@code TimeSeriesList} for this metric. 101 * @since 0.17 102 */ 103 public abstract List<TimeSeries> getTimeSeriesList(); 104 105 private static void checkTypeMatch(MetricDescriptor.Type type, List<TimeSeries> timeSeriesList) { 106 for (TimeSeries timeSeries : timeSeriesList) { 107 for (Point point : timeSeries.getPoints()) { 108 Value value = point.getValue(); 109 String valueClassName = ""; 110 if (value.getClass().getSuperclass() != null) { // work around nullness check 111 // AutoValue classes should always have a super class. 112 valueClassName = value.getClass().getSuperclass().getSimpleName(); 113 } 114 switch (type) { 115 case GAUGE_INT64: 116 case CUMULATIVE_INT64: 117 Utils.checkArgument( 118 value instanceof ValueLong, "Type mismatch: %s, %s.", type, valueClassName); 119 break; 120 case CUMULATIVE_DOUBLE: 121 case GAUGE_DOUBLE: 122 Utils.checkArgument( 123 value instanceof ValueDouble, "Type mismatch: %s, %s.", type, valueClassName); 124 break; 125 case GAUGE_DISTRIBUTION: 126 case CUMULATIVE_DISTRIBUTION: 127 Utils.checkArgument( 128 value instanceof ValueDistribution, "Type mismatch: %s, %s.", type, valueClassName); 129 break; 130 case SUMMARY: 131 Utils.checkArgument( 132 value instanceof ValueSummary, "Type mismatch: %s, %s.", type, valueClassName); 133 } 134 } 135 } 136 } 137 } 138