blob: f563ff9a5511976d9a621d0ad32d68d3584f826d [file] [log] [blame]
/*
* Copyright 2016-17, OpenCensus Authors
*
* 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 io.opencensus.stats;
import com.google.auto.value.AutoValue;
import io.opencensus.common.Duration;
import io.opencensus.common.Function;
import io.opencensus.internal.DefaultVisibilityForTesting;
import io.opencensus.internal.StringUtils;
import io.opencensus.internal.Utils;
import io.opencensus.tags.TagKey;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import javax.annotation.concurrent.Immutable;
/**
* A View specifies an aggregation and a set of tag keys. The aggregation will be broken down by the
* unique set of matching tag values for each measure.
*
* @since 0.8
*/
@Immutable
@AutoValue
@AutoValue.CopyAnnotations
@SuppressWarnings("deprecation")
public abstract class View {
@DefaultVisibilityForTesting static final int NAME_MAX_LENGTH = 255;
private static final Comparator<TagKey> TAG_KEY_COMPARATOR =
new Comparator<TagKey>() {
@Override
public int compare(TagKey key1, TagKey key2) {
return key1.getName().compareTo(key2.getName());
}
};
View() {}
/**
* Name of view. Must be unique.
*
* @since 0.8
*/
public abstract Name getName();
/**
* More detailed description, for documentation purposes.
*
* @since 0.8
*/
public abstract String getDescription();
/**
* Measure type of this view.
*
* @since 0.8
*/
public abstract Measure getMeasure();
/**
* The {@link Aggregation} associated with this {@link View}.
*
* @since 0.8
*/
public abstract Aggregation getAggregation();
/**
* Columns (a.k.a Tag Keys) to match with the associated {@link Measure}.
*
* <p>{@link Measure} will be recorded in a "greedy" way. That is, every view aggregates every
* measure. This is similar to doing a GROUPBY on view’s columns. Columns must be unique.
*
* @since 0.8
*/
public abstract List<TagKey> getColumns();
/**
* Returns the time {@link AggregationWindow} for this {@code View}.
*
* @return the time {@link AggregationWindow}.
* @since 0.8
* @deprecated since 0.13. In the future all {@link View}s will be cumulative.
*/
@Deprecated
public abstract AggregationWindow getWindow();
/**
* Constructs a new {@link View}.
*
* @param name the {@link Name} of view. Must be unique.
* @param description the description of view.
* @param measure the {@link Measure} to be aggregated by this view.
* @param aggregation the basic {@link Aggregation} that this view will support.
* @param columns the {@link TagKey}s that this view will aggregate on. Columns should not contain
* duplicates.
* @param window the {@link AggregationWindow} of view.
* @return a new {@link View}.
* @since 0.8
* @deprecated in favor of {@link #create(Name, String, Measure, Aggregation, List)}.
*/
@Deprecated
public static View create(
Name name,
String description,
Measure measure,
Aggregation aggregation,
List<TagKey> columns,
AggregationWindow window) {
Utils.checkArgument(
new HashSet<TagKey>(columns).size() == columns.size(), "Columns have duplicate.");
List<TagKey> tagKeys = new ArrayList<TagKey>(columns);
Collections.sort(tagKeys, TAG_KEY_COMPARATOR);
return new AutoValue_View(
name, description, measure, aggregation, Collections.unmodifiableList(tagKeys), window);
}
/**
* Constructs a new {@link View}.
*
* @param name the {@link Name} of view. Must be unique.
* @param description the description of view.
* @param measure the {@link Measure} to be aggregated by this view.
* @param aggregation the basic {@link Aggregation} that this view will support.
* @param columns the {@link TagKey}s that this view will aggregate on. Columns should not contain
* duplicates.
* @return a new {@link View}.
* @since 0.13
*/
public static View create(
Name name,
String description,
Measure measure,
Aggregation aggregation,
List<TagKey> columns) {
Utils.checkArgument(
new HashSet<TagKey>(columns).size() == columns.size(), "Columns have duplicate.");
return create(
name, description, measure, aggregation, columns, AggregationWindow.Cumulative.create());
}
/**
* The name of a {@code View}.
*
* @since 0.8
*/
// This type should be used as the key when associating data with Views.
@Immutable
@AutoValue
public abstract static class Name {
Name() {}
/**
* Returns the name as a {@code String}.
*
* @return the name as a {@code String}.
* @since 0.8
*/
public abstract String asString();
/**
* Creates a {@code View.Name} from a {@code String}. Should be a ASCII string with a length no
* greater than 255 characters.
*
* <p>Suggested format for name: {@code <web_host>/<path>}.
*
* @param name the name {@code String}.
* @return a {@code View.Name} with the given name {@code String}.
* @since 0.8
*/
public static Name create(String name) {
Utils.checkArgument(
StringUtils.isPrintableString(name) && name.length() <= NAME_MAX_LENGTH,
"Name should be a ASCII string with a length no greater than 255 characters.");
return new AutoValue_View_Name(name);
}
}
/**
* The time window for a {@code View}.
*
* @since 0.8
* @deprecated since 0.13. In the future all {@link View}s will be cumulative.
*/
@Deprecated
@Immutable
public abstract static class AggregationWindow {
private AggregationWindow() {}
/**
* Applies the given match function to the underlying data type.
*
* @since 0.8
*/
public abstract <T> T match(
Function<? super Cumulative, T> p0,
Function<? super Interval, T> p1,
Function<? super AggregationWindow, T> defaultFunction);
/**
* Cumulative (infinite interval) time {@code AggregationWindow}.
*
* @since 0.8
* @deprecated since 0.13. In the future all {@link View}s will be cumulative.
*/
@Deprecated
@Immutable
@AutoValue
@AutoValue.CopyAnnotations
public abstract static class Cumulative extends AggregationWindow {
private static final Cumulative CUMULATIVE =
new AutoValue_View_AggregationWindow_Cumulative();
Cumulative() {}
/**
* Constructs a cumulative {@code AggregationWindow} that does not have an explicit {@code
* Duration}. Instead, cumulative {@code AggregationWindow} always has an interval of infinite
* {@code Duration}.
*
* @return a cumulative {@code AggregationWindow}.
* @since 0.8
*/
public static Cumulative create() {
return CUMULATIVE;
}
@Override
public final <T> T match(
Function<? super Cumulative, T> p0,
Function<? super Interval, T> p1,
Function<? super AggregationWindow, T> defaultFunction) {
return p0.apply(this);
}
}
/**
* Interval (finite interval) time {@code AggregationWindow}.
*
* @since 0.8
* @deprecated since 0.13. In the future all {@link View}s will be cumulative.
*/
@Deprecated
@Immutable
@AutoValue
@AutoValue.CopyAnnotations
public abstract static class Interval extends AggregationWindow {
private static final Duration ZERO = Duration.create(0, 0);
Interval() {}
/**
* Returns the {@code Duration} associated with this {@code Interval}.
*
* @return a {@code Duration}.
* @since 0.8
*/
public abstract Duration getDuration();
/**
* Constructs an interval {@code AggregationWindow} that has a finite explicit {@code
* Duration}.
*
* <p>The {@code Duration} should be able to round to milliseconds. Currently interval window
* cannot have smaller {@code Duration} such as microseconds or nanoseconds.
*
* @return an interval {@code AggregationWindow}.
* @since 0.8
*/
public static Interval create(Duration duration) {
Utils.checkArgument(duration.compareTo(ZERO) > 0, "Duration must be positive");
return new AutoValue_View_AggregationWindow_Interval(duration);
}
@Override
public final <T> T match(
Function<? super Cumulative, T> p0,
Function<? super Interval, T> p1,
Function<? super AggregationWindow, T> defaultFunction) {
return p1.apply(this);
}
}
}
}