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.common.Timestamp; 22 import io.opencensus.internal.Utils; 23 import java.util.ArrayList; 24 import java.util.Collections; 25 import java.util.HashMap; 26 import java.util.List; 27 import java.util.Map; 28 import java.util.Map.Entry; 29 import javax.annotation.concurrent.Immutable; 30 31 /** 32 * {@link AggregationData} is the result of applying a given {@link Aggregation} to a set of {@code 33 * MeasureValue}s. 34 * 35 * <p>{@link AggregationData} currently supports 6 types of basic aggregation values: 36 * 37 * <ul> 38 * <li>SumDataDouble 39 * <li>SumDataLong 40 * <li>CountData 41 * <li>DistributionData 42 * <li>LastValueDataDouble 43 * <li>LastValueDataLong 44 * </ul> 45 * 46 * <p>{@link ViewData} will contain one {@link AggregationData}, corresponding to its {@link 47 * Aggregation} definition in {@link View}. 48 * 49 * @since 0.8 50 */ 51 @Immutable 52 public abstract class AggregationData { 53 AggregationData()54 private AggregationData() {} 55 56 /** 57 * Applies the given match function to the underlying data type. 58 * 59 * @since 0.13 60 */ match( Function<? super SumDataDouble, T> p0, Function<? super SumDataLong, T> p1, Function<? super CountData, T> p2, Function<? super DistributionData, T> p3, Function<? super LastValueDataDouble, T> p4, Function<? super LastValueDataLong, T> p5, Function<? super AggregationData, T> defaultFunction)61 public abstract <T> T match( 62 Function<? super SumDataDouble, T> p0, 63 Function<? super SumDataLong, T> p1, 64 Function<? super CountData, T> p2, 65 Function<? super DistributionData, T> p3, 66 Function<? super LastValueDataDouble, T> p4, 67 Function<? super LastValueDataLong, T> p5, 68 Function<? super AggregationData, T> defaultFunction); 69 70 /** 71 * The sum value of aggregated {@code MeasureValueDouble}s. 72 * 73 * @since 0.8 74 */ 75 @Immutable 76 @AutoValue 77 public abstract static class SumDataDouble extends AggregationData { 78 SumDataDouble()79 SumDataDouble() {} 80 81 /** 82 * Creates a {@code SumDataDouble}. 83 * 84 * @param sum the aggregated sum. 85 * @return a {@code SumDataDouble}. 86 * @since 0.8 87 */ create(double sum)88 public static SumDataDouble create(double sum) { 89 return new AutoValue_AggregationData_SumDataDouble(sum); 90 } 91 92 /** 93 * Returns the aggregated sum. 94 * 95 * @return the aggregated sum. 96 * @since 0.8 97 */ getSum()98 public abstract double getSum(); 99 100 @Override match( Function<? super SumDataDouble, T> p0, Function<? super SumDataLong, T> p1, Function<? super CountData, T> p2, Function<? super DistributionData, T> p3, Function<? super LastValueDataDouble, T> p4, Function<? super LastValueDataLong, T> p5, Function<? super AggregationData, T> defaultFunction)101 public final <T> T match( 102 Function<? super SumDataDouble, T> p0, 103 Function<? super SumDataLong, T> p1, 104 Function<? super CountData, T> p2, 105 Function<? super DistributionData, T> p3, 106 Function<? super LastValueDataDouble, T> p4, 107 Function<? super LastValueDataLong, T> p5, 108 Function<? super AggregationData, T> defaultFunction) { 109 return p0.apply(this); 110 } 111 } 112 113 /** 114 * The sum value of aggregated {@code MeasureValueLong}s. 115 * 116 * @since 0.8 117 */ 118 @Immutable 119 @AutoValue 120 public abstract static class SumDataLong extends AggregationData { 121 SumDataLong()122 SumDataLong() {} 123 124 /** 125 * Creates a {@code SumDataLong}. 126 * 127 * @param sum the aggregated sum. 128 * @return a {@code SumDataLong}. 129 * @since 0.8 130 */ create(long sum)131 public static SumDataLong create(long sum) { 132 return new AutoValue_AggregationData_SumDataLong(sum); 133 } 134 135 /** 136 * Returns the aggregated sum. 137 * 138 * @return the aggregated sum. 139 * @since 0.8 140 */ getSum()141 public abstract long getSum(); 142 143 @Override match( Function<? super SumDataDouble, T> p0, Function<? super SumDataLong, T> p1, Function<? super CountData, T> p2, Function<? super DistributionData, T> p3, Function<? super LastValueDataDouble, T> p4, Function<? super LastValueDataLong, T> p5, Function<? super AggregationData, T> defaultFunction)144 public final <T> T match( 145 Function<? super SumDataDouble, T> p0, 146 Function<? super SumDataLong, T> p1, 147 Function<? super CountData, T> p2, 148 Function<? super DistributionData, T> p3, 149 Function<? super LastValueDataDouble, T> p4, 150 Function<? super LastValueDataLong, T> p5, 151 Function<? super AggregationData, T> defaultFunction) { 152 return p1.apply(this); 153 } 154 } 155 156 /** 157 * The count value of aggregated {@code MeasureValue}s. 158 * 159 * @since 0.8 160 */ 161 @Immutable 162 @AutoValue 163 public abstract static class CountData extends AggregationData { 164 CountData()165 CountData() {} 166 167 /** 168 * Creates a {@code CountData}. 169 * 170 * @param count the aggregated count. 171 * @return a {@code CountData}. 172 * @since 0.8 173 */ create(long count)174 public static CountData create(long count) { 175 return new AutoValue_AggregationData_CountData(count); 176 } 177 178 /** 179 * Returns the aggregated count. 180 * 181 * @return the aggregated count. 182 * @since 0.8 183 */ getCount()184 public abstract long getCount(); 185 186 @Override match( Function<? super SumDataDouble, T> p0, Function<? super SumDataLong, T> p1, Function<? super CountData, T> p2, Function<? super DistributionData, T> p3, Function<? super LastValueDataDouble, T> p4, Function<? super LastValueDataLong, T> p5, Function<? super AggregationData, T> defaultFunction)187 public final <T> T match( 188 Function<? super SumDataDouble, T> p0, 189 Function<? super SumDataLong, T> p1, 190 Function<? super CountData, T> p2, 191 Function<? super DistributionData, T> p3, 192 Function<? super LastValueDataDouble, T> p4, 193 Function<? super LastValueDataLong, T> p5, 194 Function<? super AggregationData, T> defaultFunction) { 195 return p2.apply(this); 196 } 197 } 198 199 /** 200 * The mean value of aggregated {@code MeasureValue}s. 201 * 202 * @since 0.8 203 * @deprecated since 0.13, use {@link DistributionData} instead. 204 */ 205 @Immutable 206 @AutoValue 207 @Deprecated 208 @AutoValue.CopyAnnotations 209 public abstract static class MeanData extends AggregationData { 210 MeanData()211 MeanData() {} 212 213 /** 214 * Creates a {@code MeanData}. 215 * 216 * @param mean the aggregated mean. 217 * @param count the aggregated count. 218 * @return a {@code MeanData}. 219 * @since 0.8 220 */ create(double mean, long count)221 public static MeanData create(double mean, long count) { 222 return new AutoValue_AggregationData_MeanData(mean, count); 223 } 224 225 /** 226 * Returns the aggregated mean. 227 * 228 * @return the aggregated mean. 229 * @since 0.8 230 */ getMean()231 public abstract double getMean(); 232 233 /** 234 * Returns the aggregated count. 235 * 236 * @return the aggregated count. 237 * @since 0.8 238 */ getCount()239 public abstract long getCount(); 240 241 @Override match( Function<? super SumDataDouble, T> p0, Function<? super SumDataLong, T> p1, Function<? super CountData, T> p2, Function<? super DistributionData, T> p3, Function<? super LastValueDataDouble, T> p4, Function<? super LastValueDataLong, T> p5, Function<? super AggregationData, T> defaultFunction)242 public final <T> T match( 243 Function<? super SumDataDouble, T> p0, 244 Function<? super SumDataLong, T> p1, 245 Function<? super CountData, T> p2, 246 Function<? super DistributionData, T> p3, 247 Function<? super LastValueDataDouble, T> p4, 248 Function<? super LastValueDataLong, T> p5, 249 Function<? super AggregationData, T> defaultFunction) { 250 return defaultFunction.apply(this); 251 } 252 } 253 254 /** 255 * The distribution stats of aggregated {@code MeasureValue}s. Distribution stats include mean, 256 * count, histogram, min, max and sum of squared deviations. 257 * 258 * @since 0.8 259 */ 260 @Immutable 261 @AutoValue 262 public abstract static class DistributionData extends AggregationData { 263 DistributionData()264 DistributionData() {} 265 266 /** 267 * Creates a {@code DistributionData}. 268 * 269 * @param mean mean value. 270 * @param count count value. 271 * @param min min value. 272 * @param max max value. 273 * @param sumOfSquaredDeviations sum of squared deviations. 274 * @param bucketCounts histogram bucket counts. 275 * @param exemplars the exemplars associated with histogram buckets. 276 * @return a {@code DistributionData}. 277 * @since 0.16 278 */ create( double mean, long count, double min, double max, double sumOfSquaredDeviations, List<Long> bucketCounts, List<Exemplar> exemplars)279 public static DistributionData create( 280 double mean, 281 long count, 282 double min, 283 double max, 284 double sumOfSquaredDeviations, 285 List<Long> bucketCounts, 286 List<Exemplar> exemplars) { 287 if (min != Double.POSITIVE_INFINITY || max != Double.NEGATIVE_INFINITY) { 288 Utils.checkArgument(min <= max, "max should be greater or equal to min."); 289 } 290 291 Utils.checkNotNull(bucketCounts, "bucketCounts"); 292 List<Long> bucketCountsCopy = Collections.unmodifiableList(new ArrayList<Long>(bucketCounts)); 293 for (Long bucket : bucketCountsCopy) { 294 Utils.checkNotNull(bucket, "bucket"); 295 } 296 297 Utils.checkNotNull(exemplars, "exemplar list should not be null."); 298 for (Exemplar exemplar : exemplars) { 299 Utils.checkNotNull(exemplar, "exemplar"); 300 } 301 302 return new AutoValue_AggregationData_DistributionData( 303 mean, 304 count, 305 min, 306 max, 307 sumOfSquaredDeviations, 308 bucketCountsCopy, 309 Collections.<Exemplar>unmodifiableList(new ArrayList<Exemplar>(exemplars))); 310 } 311 312 /** 313 * Creates a {@code DistributionData}. 314 * 315 * @param mean mean value. 316 * @param count count value. 317 * @param min min value. 318 * @param max max value. 319 * @param sumOfSquaredDeviations sum of squared deviations. 320 * @param bucketCounts histogram bucket counts. 321 * @return a {@code DistributionData}. 322 * @since 0.8 323 */ create( double mean, long count, double min, double max, double sumOfSquaredDeviations, List<Long> bucketCounts)324 public static DistributionData create( 325 double mean, 326 long count, 327 double min, 328 double max, 329 double sumOfSquaredDeviations, 330 List<Long> bucketCounts) { 331 return create( 332 mean, 333 count, 334 min, 335 max, 336 sumOfSquaredDeviations, 337 bucketCounts, 338 Collections.<Exemplar>emptyList()); 339 } 340 341 /** 342 * Returns the aggregated mean. 343 * 344 * @return the aggregated mean. 345 * @since 0.8 346 */ getMean()347 public abstract double getMean(); 348 349 /** 350 * Returns the aggregated count. 351 * 352 * @return the aggregated count. 353 * @since 0.8 354 */ getCount()355 public abstract long getCount(); 356 357 /** 358 * Returns the minimum of the population values. 359 * 360 * @return the minimum of the population values. 361 * @since 0.8 362 */ getMin()363 public abstract double getMin(); 364 365 /** 366 * Returns the maximum of the population values. 367 * 368 * @return the maximum of the population values. 369 * @since 0.8 370 */ getMax()371 public abstract double getMax(); 372 373 /** 374 * Returns the aggregated sum of squared deviations. 375 * 376 * @return the aggregated sum of squared deviations. 377 * @since 0.8 378 */ getSumOfSquaredDeviations()379 public abstract double getSumOfSquaredDeviations(); 380 381 /** 382 * Returns the aggregated bucket counts. The returned list is immutable, trying to update it 383 * will throw an {@code UnsupportedOperationException}. 384 * 385 * @return the aggregated bucket counts. 386 * @since 0.8 387 */ getBucketCounts()388 public abstract List<Long> getBucketCounts(); 389 390 /** 391 * Returns the {@link Exemplar}s associated with histogram buckets. 392 * 393 * @return the {@code Exemplar}s associated with histogram buckets. 394 * @since 0.16 395 */ getExemplars()396 public abstract List<Exemplar> getExemplars(); 397 398 @Override match( Function<? super SumDataDouble, T> p0, Function<? super SumDataLong, T> p1, Function<? super CountData, T> p2, Function<? super DistributionData, T> p3, Function<? super LastValueDataDouble, T> p4, Function<? super LastValueDataLong, T> p5, Function<? super AggregationData, T> defaultFunction)399 public final <T> T match( 400 Function<? super SumDataDouble, T> p0, 401 Function<? super SumDataLong, T> p1, 402 Function<? super CountData, T> p2, 403 Function<? super DistributionData, T> p3, 404 Function<? super LastValueDataDouble, T> p4, 405 Function<? super LastValueDataLong, T> p5, 406 Function<? super AggregationData, T> defaultFunction) { 407 return p3.apply(this); 408 } 409 410 /** 411 * An example point that may be used to annotate aggregated distribution values, associated with 412 * a histogram bucket. 413 * 414 * @since 0.16 415 */ 416 @Immutable 417 @AutoValue 418 public abstract static class Exemplar { 419 Exemplar()420 Exemplar() {} 421 422 /** 423 * Returns value of the {@link Exemplar} point. 424 * 425 * @return value of the {@code Exemplar} point. 426 * @since 0.16 427 */ getValue()428 public abstract double getValue(); 429 430 /** 431 * Returns the time that this {@link Exemplar}'s value was recorded. 432 * 433 * @return the time that this {@code Exemplar}'s value was recorded. 434 * @since 0.16 435 */ getTimestamp()436 public abstract Timestamp getTimestamp(); 437 438 /** 439 * Returns the contextual information about the example value, represented as a string map. 440 * 441 * @return the contextual information about the example value. 442 * @since 0.16 443 */ getAttachments()444 public abstract Map<String, String> getAttachments(); 445 446 /** 447 * Creates an {@link Exemplar}. 448 * 449 * @param value value of the {@link Exemplar} point. 450 * @param timestamp the time that this {@code Exemplar}'s value was recorded. 451 * @param attachments the contextual information about the example value. 452 * @return an {@code Exemplar}. 453 * @since 0.16 454 */ create( double value, Timestamp timestamp, Map<String, String> attachments)455 public static Exemplar create( 456 double value, Timestamp timestamp, Map<String, String> attachments) { 457 Utils.checkNotNull(attachments, "attachments"); 458 Map<String, String> attachmentsCopy = 459 Collections.unmodifiableMap(new HashMap<String, String>(attachments)); 460 for (Entry<String, String> entry : attachmentsCopy.entrySet()) { 461 Utils.checkNotNull(entry.getKey(), "key of attachments"); 462 Utils.checkNotNull(entry.getValue(), "value of attachments"); 463 } 464 return new AutoValue_AggregationData_DistributionData_Exemplar( 465 value, timestamp, attachmentsCopy); 466 } 467 } 468 } 469 470 /** 471 * The last value of aggregated {@code MeasureValueDouble}s. 472 * 473 * @since 0.13 474 */ 475 @Immutable 476 @AutoValue 477 public abstract static class LastValueDataDouble extends AggregationData { 478 LastValueDataDouble()479 LastValueDataDouble() {} 480 481 /** 482 * Creates a {@code LastValueDataDouble}. 483 * 484 * @param lastValue the last value. 485 * @return a {@code LastValueDataDouble}. 486 * @since 0.13 487 */ create(double lastValue)488 public static LastValueDataDouble create(double lastValue) { 489 return new AutoValue_AggregationData_LastValueDataDouble(lastValue); 490 } 491 492 /** 493 * Returns the last value. 494 * 495 * @return the last value. 496 * @since 0.13 497 */ getLastValue()498 public abstract double getLastValue(); 499 500 @Override match( Function<? super SumDataDouble, T> p0, Function<? super SumDataLong, T> p1, Function<? super CountData, T> p2, Function<? super DistributionData, T> p3, Function<? super LastValueDataDouble, T> p4, Function<? super LastValueDataLong, T> p5, Function<? super AggregationData, T> defaultFunction)501 public final <T> T match( 502 Function<? super SumDataDouble, T> p0, 503 Function<? super SumDataLong, T> p1, 504 Function<? super CountData, T> p2, 505 Function<? super DistributionData, T> p3, 506 Function<? super LastValueDataDouble, T> p4, 507 Function<? super LastValueDataLong, T> p5, 508 Function<? super AggregationData, T> defaultFunction) { 509 return p4.apply(this); 510 } 511 } 512 513 /** 514 * The last value of aggregated {@code MeasureValueLong}s. 515 * 516 * @since 0.13 517 */ 518 @Immutable 519 @AutoValue 520 public abstract static class LastValueDataLong extends AggregationData { 521 LastValueDataLong()522 LastValueDataLong() {} 523 524 /** 525 * Creates a {@code LastValueDataLong}. 526 * 527 * @param lastValue the last value. 528 * @return a {@code LastValueDataLong}. 529 * @since 0.13 530 */ create(long lastValue)531 public static LastValueDataLong create(long lastValue) { 532 return new AutoValue_AggregationData_LastValueDataLong(lastValue); 533 } 534 535 /** 536 * Returns the last value. 537 * 538 * @return the last value. 539 * @since 0.13 540 */ getLastValue()541 public abstract long getLastValue(); 542 543 @Override match( Function<? super SumDataDouble, T> p0, Function<? super SumDataLong, T> p1, Function<? super CountData, T> p2, Function<? super DistributionData, T> p3, Function<? super LastValueDataDouble, T> p4, Function<? super LastValueDataLong, T> p5, Function<? super AggregationData, T> defaultFunction)544 public final <T> T match( 545 Function<? super SumDataDouble, T> p0, 546 Function<? super SumDataLong, T> p1, 547 Function<? super CountData, T> p2, 548 Function<? super DistributionData, T> p3, 549 Function<? super LastValueDataDouble, T> p4, 550 Function<? super LastValueDataLong, T> p5, 551 Function<? super AggregationData, T> defaultFunction) { 552 return p5.apply(this); 553 } 554 } 555 } 556