1 /* 2 * Copyright 2017, 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.stats; 18 19 import com.google.auto.value.AutoValue; 20 import io.opencensus.common.Function; 21 import io.opencensus.internal.DefaultVisibilityForTesting; 22 import io.opencensus.internal.StringUtils; 23 import io.opencensus.internal.Utils; 24 import javax.annotation.concurrent.Immutable; 25 26 /** 27 * The definition of the {@link Measurement} that is taken by OpenCensus library. 28 * 29 * @since 0.8 30 */ 31 @Immutable 32 public abstract class Measure { 33 @DefaultVisibilityForTesting static final int NAME_MAX_LENGTH = 255; 34 private static final String ERROR_MESSAGE_INVALID_NAME = 35 "Name should be a ASCII string with a length no greater than " 36 + NAME_MAX_LENGTH 37 + " characters."; 38 39 /** 40 * Applies the given match function to the underlying data type. 41 * 42 * @since 0.8 43 */ match( Function<? super MeasureDouble, T> p0, Function<? super MeasureLong, T> p1, Function<? super Measure, T> defaultFunction)44 public abstract <T> T match( 45 Function<? super MeasureDouble, T> p0, 46 Function<? super MeasureLong, T> p1, 47 Function<? super Measure, T> defaultFunction); 48 49 /** 50 * Name of measure, as a {@code String}. Should be a ASCII string with a length no greater than 51 * 255 characters. 52 * 53 * <p>Suggested format for name: {@code <web_host>/<path>}. 54 * 55 * @since 0.8 56 */ getName()57 public abstract String getName(); 58 59 /** 60 * Detailed description of the measure, used in documentation. 61 * 62 * @since 0.8 63 */ getDescription()64 public abstract String getDescription(); 65 66 /** 67 * The units in which {@link Measure} values are measured. 68 * 69 * <p>The suggested grammar for a unit is as follows: 70 * 71 * <ul> 72 * <li>Expression = Component { "." Component } {"/" Component }; 73 * <li>Component = [ PREFIX ] UNIT [ Annotation ] | Annotation | "1"; 74 * <li>Annotation = "{" NAME "}" ; 75 * </ul> 76 * 77 * <p>For example, string “MBy{transmitted}/ms” stands for megabytes per milliseconds, and the 78 * annotation transmitted inside {} is just a comment of the unit. 79 * 80 * @since 0.8 81 */ 82 // TODO(songya): determine whether we want to check the grammar on string unit. getUnit()83 public abstract String getUnit(); 84 85 // Prevents this class from being subclassed anywhere else. Measure()86 private Measure() {} 87 88 /** 89 * {@link Measure} with {@code Double} typed values. 90 * 91 * @since 0.8 92 */ 93 @Immutable 94 @AutoValue 95 public abstract static class MeasureDouble extends Measure { 96 MeasureDouble()97 MeasureDouble() {} 98 99 /** 100 * Constructs a new {@link MeasureDouble}. 101 * 102 * @param name name of {@code Measure}. Suggested format: {@code <web_host>/<path>}. 103 * @param description description of {@code Measure}. 104 * @param unit unit of {@code Measure}. 105 * @return a {@code MeasureDouble}. 106 * @since 0.8 107 */ create(String name, String description, String unit)108 public static MeasureDouble create(String name, String description, String unit) { 109 Utils.checkArgument( 110 StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH, 111 ERROR_MESSAGE_INVALID_NAME); 112 return new AutoValue_Measure_MeasureDouble(name, description, unit); 113 } 114 115 @Override match( Function<? super MeasureDouble, T> p0, Function<? super MeasureLong, T> p1, Function<? super Measure, T> defaultFunction)116 public <T> T match( 117 Function<? super MeasureDouble, T> p0, 118 Function<? super MeasureLong, T> p1, 119 Function<? super Measure, T> defaultFunction) { 120 return p0.apply(this); 121 } 122 123 @Override getName()124 public abstract String getName(); 125 126 @Override getDescription()127 public abstract String getDescription(); 128 129 @Override getUnit()130 public abstract String getUnit(); 131 } 132 133 /** 134 * {@link Measure} with {@code Long} typed values. 135 * 136 * @since 0.8 137 */ 138 @Immutable 139 @AutoValue 140 public abstract static class MeasureLong extends Measure { 141 MeasureLong()142 MeasureLong() {} 143 144 /** 145 * Constructs a new {@link MeasureLong}. 146 * 147 * @param name name of {@code Measure}. Suggested format: {@code <web_host>/<path>}. 148 * @param description description of {@code Measure}. 149 * @param unit unit of {@code Measure}. 150 * @return a {@code MeasureLong}. 151 * @since 0.8 152 */ create(String name, String description, String unit)153 public static MeasureLong create(String name, String description, String unit) { 154 Utils.checkArgument( 155 StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH, 156 ERROR_MESSAGE_INVALID_NAME); 157 return new AutoValue_Measure_MeasureLong(name, description, unit); 158 } 159 160 @Override match( Function<? super MeasureDouble, T> p0, Function<? super MeasureLong, T> p1, Function<? super Measure, T> defaultFunction)161 public <T> T match( 162 Function<? super MeasureDouble, T> p0, 163 Function<? super MeasureLong, T> p1, 164 Function<? super Measure, T> defaultFunction) { 165 return p1.apply(this); 166 } 167 168 @Override getName()169 public abstract String getName(); 170 171 @Override getDescription()172 public abstract String getDescription(); 173 174 @Override getUnit()175 public abstract String getUnit(); 176 } 177 } 178