diff options
author | Bogdan Drutu <bdrutu@google.com> | 2018-07-24 11:04:01 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-24 11:04:01 +0200 |
commit | b83ea423ea423af12478b2e0adb587125bd234e5 (patch) | |
tree | 65e7aa0298bdcc1758a1bac9ed18da4ba3ebd1d0 /exporters | |
parent | afea7a205f7d7e2edb63555d7a0b42a7fcaa2ccf (diff) | |
download | opencensus-java-b83ea423ea423af12478b2e0adb587125bd234e5.tar.gz |
Extract constant functions when used in match to reduce number of allocations. (#1336)
* Extract constant functions when used in match to reduce number of allocations.
* Fix names for non-constant functions. Fix deprecated warnings.
* Add more optimization and clean zipkin exporter.
* Use correct name format for RETURN_STRING.
* Fix formatting.
* Fix import for Nullable.
Diffstat (limited to 'exporters')
5 files changed, 195 insertions, 148 deletions
diff --git a/exporters/stats/prometheus/src/main/java/io/opencensus/exporter/stats/prometheus/PrometheusExportUtils.java b/exporters/stats/prometheus/src/main/java/io/opencensus/exporter/stats/prometheus/PrometheusExportUtils.java index b13af308..288813d3 100644 --- a/exporters/stats/prometheus/src/main/java/io/opencensus/exporter/stats/prometheus/PrometheusExportUtils.java +++ b/exporters/stats/prometheus/src/main/java/io/opencensus/exporter/stats/prometheus/PrometheusExportUtils.java @@ -88,6 +88,15 @@ final class PrometheusExportUtils { @VisibleForTesting static final String SAMPLE_SUFFIX_SUM = "_sum"; @VisibleForTesting static final String LABEL_NAME_BUCKET_BOUND = "le"; + private static final Function<Object, Type> TYPE_UNTYPED_FUNCTION = + Functions.returnConstant(Type.UNTYPED); + private static final Function<Object, Type> TYPE_COUNTER_FUNCTION = + Functions.returnConstant(Type.COUNTER); + private static final Function<Object, Type> TYPE_HISTOGRAM_FUNCTION = + Functions.returnConstant(Type.HISTOGRAM); + private static final Function<Object, Type> TYPE_GAUGE_FUNCTION = + Functions.returnConstant(Type.GAUGE); + // Converts a ViewData to a Prometheus MetricFamilySamples. static MetricFamilySamples createMetricFamilySamples(ViewData viewData) { View view = viewData.getView(); @@ -125,10 +134,10 @@ final class PrometheusExportUtils { return Type.UNTYPED; } return aggregation.match( - Functions.returnConstant(Type.UNTYPED), // SUM - Functions.returnConstant(Type.COUNTER), // COUNT - Functions.returnConstant(Type.HISTOGRAM), // DISTRIBUTION - Functions.returnConstant(Type.GAUGE), // LAST VALUE + TYPE_UNTYPED_FUNCTION, // SUM + TYPE_COUNTER_FUNCTION, // COUNT + TYPE_HISTOGRAM_FUNCTION, // DISTRIBUTION + TYPE_GAUGE_FUNCTION, // LAST VALUE new Function<Aggregation, Type>() { @Override public Type apply(Aggregation arg) { diff --git a/exporters/stats/stackdriver/src/main/java/io/opencensus/exporter/stats/stackdriver/StackdriverExportUtils.java b/exporters/stats/stackdriver/src/main/java/io/opencensus/exporter/stats/stackdriver/StackdriverExportUtils.java index e87170b7..9b5b77da 100644 --- a/exporters/stats/stackdriver/src/main/java/io/opencensus/exporter/stats/stackdriver/StackdriverExportUtils.java +++ b/exporters/stats/stackdriver/src/main/java/io/opencensus/exporter/stats/stackdriver/StackdriverExportUtils.java @@ -35,6 +35,7 @@ import com.google.monitoring.v3.Point; import com.google.monitoring.v3.TimeInterval; import com.google.monitoring.v3.TimeSeries; import com.google.monitoring.v3.TypedValue; +import com.google.monitoring.v3.TypedValue.Builder; import com.google.protobuf.Timestamp; import io.opencensus.common.Function; import io.opencensus.common.Functions; @@ -75,6 +76,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; /** Util methods to convert OpenCensus Stats data models to StackDriver monitoring data models. */ @SuppressWarnings("deprecation") final class StackdriverExportUtils { + // TODO(songya): do we want these constants to be customizable? @VisibleForTesting static final String LABEL_DESCRIPTION = "OpenCensus TagKey"; @VisibleForTesting static final String OPENCENSUS_TASK = "opencensus_task"; @@ -90,6 +92,99 @@ final class StackdriverExportUtils { private static final String OPENCENSUS_TASK_VALUE_DEFAULT = generateDefaultTaskValue(); private static final String PROJECT_ID_LABEL_KEY = "project_id"; + // Constant functions for ValueType. + private static final Function<Object, MetricDescriptor.ValueType> VALUE_TYPE_DOUBLE_FUNCTION = + Functions.returnConstant(MetricDescriptor.ValueType.DOUBLE); + private static final Function<Object, MetricDescriptor.ValueType> VALUE_TYPE_INT64_FUNCTION = + Functions.returnConstant(MetricDescriptor.ValueType.INT64); + private static final Function<Object, MetricDescriptor.ValueType> + VALUE_TYPE_UNRECOGNIZED_FUNCTION = + Functions.returnConstant(MetricDescriptor.ValueType.UNRECOGNIZED); + private static final Function<Object, MetricDescriptor.ValueType> + VALUE_TYPE_DISTRIBUTION_FUNCTION = + Functions.returnConstant(MetricDescriptor.ValueType.DISTRIBUTION); + private static final Function<Aggregation, MetricDescriptor.ValueType> valueTypeMeanFunction = + new Function<Aggregation, MetricDescriptor.ValueType>() { + @Override + public MetricDescriptor.ValueType apply(Aggregation arg) { + // TODO(songya): remove this once Mean aggregation is completely removed. Before that + // we need to continue supporting Mean, since it could still be used by users and some + // deprecated RPC views. + if (arg instanceof Aggregation.Mean) { + return MetricDescriptor.ValueType.DOUBLE; + } + return MetricDescriptor.ValueType.UNRECOGNIZED; + } + }; + + // Constant functions for MetricKind. + private static final Function<Object, MetricKind> METRIC_KIND_CUMULATIVE_FUNCTION = + Functions.returnConstant(MetricKind.CUMULATIVE); + private static final Function<Object, MetricKind> METRIC_KIND_UNRECOGNIZED_FUNCTION = + Functions.returnConstant(MetricKind.UNRECOGNIZED); + + // Constant functions for TypedValue. + private static final Function<SumDataDouble, TypedValue> typedValueSumDoubleFunction = + new Function<SumDataDouble, TypedValue>() { + @Override + public TypedValue apply(SumDataDouble arg) { + Builder builder = TypedValue.newBuilder(); + builder.setDoubleValue(arg.getSum()); + return builder.build(); + } + }; + private static final Function<SumDataLong, TypedValue> typedValueSumLongFunction = + new Function<SumDataLong, TypedValue>() { + @Override + public TypedValue apply(SumDataLong arg) { + Builder builder = TypedValue.newBuilder(); + builder.setInt64Value(arg.getSum()); + return builder.build(); + } + }; + private static final Function<CountData, TypedValue> typedValueCountFunction = + new Function<CountData, TypedValue>() { + @Override + public TypedValue apply(CountData arg) { + Builder builder = TypedValue.newBuilder(); + builder.setInt64Value(arg.getCount()); + return builder.build(); + } + }; + private static final Function<LastValueDataDouble, TypedValue> typedValueLastValueDoubleFunction = + new Function<LastValueDataDouble, TypedValue>() { + @Override + public TypedValue apply(LastValueDataDouble arg) { + Builder builder = TypedValue.newBuilder(); + builder.setDoubleValue(arg.getLastValue()); + return builder.build(); + } + }; + private static final Function<LastValueDataLong, TypedValue> typedValueLastValueLongFunction = + new Function<LastValueDataLong, TypedValue>() { + @Override + public TypedValue apply(LastValueDataLong arg) { + Builder builder = TypedValue.newBuilder(); + builder.setInt64Value(arg.getLastValue()); + return builder.build(); + } + }; + private static final Function<AggregationData, TypedValue> typedValueMeanFunction = + new Function<AggregationData, TypedValue>() { + @Override + public TypedValue apply(AggregationData arg) { + Builder builder = TypedValue.newBuilder(); + // TODO(songya): remove this once Mean aggregation is completely removed. Before that + // we need to continue supporting Mean, since it could still be used by users and some + // deprecated RPC views. + if (arg instanceof AggregationData.MeanData) { + builder.setDoubleValue(((AggregationData.MeanData) arg).getMean()); + return builder.build(); + } + throw new IllegalArgumentException("Unknown Aggregation"); + } + }; + private static String generateDefaultTaskValue() { // Something like '<pid>@<hostname>', at least in Oracle and OpenJdk JVMs final String jvmName = ManagementFactory.getRuntimeMXBean().getName(); @@ -161,21 +256,19 @@ final class StackdriverExportUtils { return MetricKind.GAUGE; } return window.match( - Functions.returnConstant(MetricKind.CUMULATIVE), // Cumulative + METRIC_KIND_CUMULATIVE_FUNCTION, // Cumulative // TODO(songya): We don't support exporting Interval stats to StackDriver in this version. - Functions.returnConstant(MetricKind.UNRECOGNIZED), // Interval - Functions.returnConstant(MetricKind.UNRECOGNIZED)); + METRIC_KIND_UNRECOGNIZED_FUNCTION, // Interval + METRIC_KIND_UNRECOGNIZED_FUNCTION); } // Construct a MetricDescriptor.ValueType from an Aggregation and a Measure @VisibleForTesting static String createUnit(Aggregation aggregation, final Measure measure) { - return aggregation.match( - Functions.returnConstant(measure.getUnit()), - Functions.returnConstant("1"), // Count - Functions.returnConstant(measure.getUnit()), // Distribution - Functions.returnConstant(measure.getUnit()), // LastValue - Functions.returnConstant(measure.getUnit())); + if (aggregation instanceof Aggregation.Count) { + return "1"; + } + return measure.getUnit(); } // Construct a MetricDescriptor.ValueType from an Aggregation and a Measure @@ -185,28 +278,17 @@ final class StackdriverExportUtils { return aggregation.match( Functions.returnConstant( measure.match( - Functions.returnConstant(MetricDescriptor.ValueType.DOUBLE), // Sum Double - Functions.returnConstant(MetricDescriptor.ValueType.INT64), // Sum Long - Functions.returnConstant(MetricDescriptor.ValueType.UNRECOGNIZED))), - Functions.returnConstant(MetricDescriptor.ValueType.INT64), // Count - Functions.returnConstant(MetricDescriptor.ValueType.DISTRIBUTION), // Distribution + VALUE_TYPE_DOUBLE_FUNCTION, // Sum Double + VALUE_TYPE_INT64_FUNCTION, // Sum Long + VALUE_TYPE_UNRECOGNIZED_FUNCTION)), + VALUE_TYPE_INT64_FUNCTION, // Count + VALUE_TYPE_DISTRIBUTION_FUNCTION, // Distribution Functions.returnConstant( measure.match( - Functions.returnConstant(MetricDescriptor.ValueType.DOUBLE), // LastValue Double - Functions.returnConstant(MetricDescriptor.ValueType.INT64), // LastValue Long - Functions.returnConstant(MetricDescriptor.ValueType.UNRECOGNIZED))), - new Function<Aggregation, MetricDescriptor.ValueType>() { - @Override - public MetricDescriptor.ValueType apply(Aggregation arg) { - // TODO(songya): remove this once Mean aggregation is completely removed. Before that - // we need to continue supporting Mean, since it could still be used by users and some - // deprecated RPC views. - if (arg instanceof Aggregation.Mean) { - return MetricDescriptor.ValueType.DOUBLE; - } - return MetricDescriptor.ValueType.UNRECOGNIZED; - } - }); + VALUE_TYPE_DOUBLE_FUNCTION, // LastValue Double + VALUE_TYPE_INT64_FUNCTION, // LastValue Long + VALUE_TYPE_UNRECOGNIZED_FUNCTION)), + valueTypeMeanFunction); } // Convert ViewData to a list of TimeSeries, so that ViewData can be uploaded to Stackdriver. @@ -280,21 +362,20 @@ final class StackdriverExportUtils { @VisibleForTesting static TimeInterval createTimeInterval( ViewData.AggregationWindowData windowData, final Aggregation aggregation) { - final TimeInterval.Builder builder = TimeInterval.newBuilder(); - windowData.match( - new Function<ViewData.AggregationWindowData.CumulativeData, Void>() { + return windowData.match( + new Function<ViewData.AggregationWindowData.CumulativeData, TimeInterval>() { @Override - public Void apply(ViewData.AggregationWindowData.CumulativeData arg) { + public TimeInterval apply(ViewData.AggregationWindowData.CumulativeData arg) { + TimeInterval.Builder builder = TimeInterval.newBuilder(); builder.setEndTime(convertTimestamp(arg.getEnd())); if (!(aggregation instanceof LastValue)) { builder.setStartTime(convertTimestamp(arg.getStart())); } - return null; + return builder.build(); } }, - Functions.</*@Nullable*/ Void>throwIllegalArgumentException(), - Functions.</*@Nullable*/ Void>throwIllegalArgumentException()); - return builder.build(); + Functions.</*@Nullable*/ TimeInterval>throwIllegalArgumentException(), + Functions.</*@Nullable*/ TimeInterval>throwIllegalArgumentException()); } // Create a TypedValue using AggregationData and Aggregation @@ -302,69 +383,26 @@ final class StackdriverExportUtils { @VisibleForTesting static TypedValue createTypedValue( final Aggregation aggregation, AggregationData aggregationData) { - final TypedValue.Builder builder = TypedValue.newBuilder(); - aggregationData.match( - new Function<SumDataDouble, Void>() { + return aggregationData.match( + typedValueSumDoubleFunction, + typedValueSumLongFunction, + typedValueCountFunction, + new Function<DistributionData, TypedValue>() { @Override - public Void apply(SumDataDouble arg) { - builder.setDoubleValue(arg.getSum()); - return null; - } - }, - new Function<SumDataLong, Void>() { - @Override - public Void apply(SumDataLong arg) { - builder.setInt64Value(arg.getSum()); - return null; - } - }, - new Function<CountData, Void>() { - @Override - public Void apply(CountData arg) { - builder.setInt64Value(arg.getCount()); - return null; - } - }, - new Function<DistributionData, Void>() { - @Override - public Void apply(DistributionData arg) { + public TypedValue apply(DistributionData arg) { + TypedValue.Builder builder = TypedValue.newBuilder(); checkArgument( aggregation instanceof Aggregation.Distribution, "Aggregation and AggregationData mismatch."); builder.setDistributionValue( createDistribution( arg, ((Aggregation.Distribution) aggregation).getBucketBoundaries())); - return null; - } - }, - new Function<LastValueDataDouble, Void>() { - @Override - public Void apply(LastValueDataDouble arg) { - builder.setDoubleValue(arg.getLastValue()); - return null; + return builder.build(); } }, - new Function<LastValueDataLong, Void>() { - @Override - public Void apply(LastValueDataLong arg) { - builder.setInt64Value(arg.getLastValue()); - return null; - } - }, - new Function<AggregationData, Void>() { - @Override - public Void apply(AggregationData arg) { - // TODO(songya): remove this once Mean aggregation is completely removed. Before that - // we need to continue supporting Mean, since it could still be used by users and some - // deprecated RPC views. - if (arg instanceof AggregationData.MeanData) { - builder.setDoubleValue(((AggregationData.MeanData) arg).getMean()); - return null; - } - throw new IllegalArgumentException("Unknown Aggregation"); - } - }); - return builder.build(); + typedValueLastValueDoubleFunction, + typedValueLastValueLongFunction, + typedValueMeanFunction); } // Create a StackDriver Distribution from DistributionData and BucketBoundaries diff --git a/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaExporterHandler.java b/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaExporterHandler.java index 5bb8c642..fd329c4a 100644 --- a/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaExporterHandler.java +++ b/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaExporterHandler.java @@ -113,7 +113,7 @@ final class InstanaExporterHandler extends SpanExporter.Handler { // The return type needs to be nullable when this function is used as an argument to 'match' in // attributeValueToString, because 'match' doesn't allow covariant return types. - private static final Function<Object, /*@Nullable*/ String> RETURN_STRING = + private static final Function<Object, /*@Nullable*/ String> returnToString = new Function<Object, /*@Nullable*/ String>() { @Override public String apply(Object input) { @@ -124,7 +124,10 @@ final class InstanaExporterHandler extends SpanExporter.Handler { @javax.annotation.Nullable private static String attributeValueToString(AttributeValue attributeValue) { return attributeValue.match( - RETURN_STRING, RETURN_STRING, RETURN_STRING, Functions.</*@Nullable*/ String>returnNull()); + returnToString, + returnToString, + returnToString, + Functions.</*@Nullable*/ String>returnNull()); } static String convertToJson(Collection<SpanData> spanDataList) { diff --git a/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandler.java b/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandler.java index 2ced3bf2..9588a425 100644 --- a/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandler.java +++ b/exporters/trace/stackdriver/src/main/java/io/opencensus/exporter/trace/stackdriver/StackdriverV2ExporterHandler.java @@ -25,6 +25,7 @@ import com.google.cloud.trace.v2.TraceServiceSettings; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableMap; import com.google.devtools.cloudtrace.v2.AttributeValue; +import com.google.devtools.cloudtrace.v2.AttributeValue.Builder; import com.google.devtools.cloudtrace.v2.ProjectName; import com.google.devtools.cloudtrace.v2.Span; import com.google.devtools.cloudtrace.v2.Span.Attributes; @@ -74,6 +75,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; /** Exporter to Stackdriver Trace API v2. */ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { + private static final Tracer tracer = Tracing.getTracer(); private static final Sampler probabilitySampler = Samplers.probabilitySampler(0.0001); private static final String AGENT_LABEL_KEY = "g.co/agent"; @@ -102,6 +104,35 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { // Only initialize once. private static final Map<String, AttributeValue> RESOURCE_LABELS = getResourceLabels(RESOURCE); + // Constant functions for AttributeValue. + private static final Function<String, AttributeValue> stringAttributeValueFunction = + new Function<String, AttributeValue>() { + @Override + public AttributeValue apply(String stringValue) { + Builder attributeValueBuilder = AttributeValue.newBuilder(); + attributeValueBuilder.setStringValue(toTruncatableStringProto(stringValue)); + return attributeValueBuilder.build(); + } + }; + private static final Function<Boolean, AttributeValue> booleanAttributeValueFunction = + new Function<Boolean, AttributeValue>() { + @Override + public AttributeValue apply(Boolean booleanValue) { + Builder attributeValueBuilder = AttributeValue.newBuilder(); + attributeValueBuilder.setBoolValue(booleanValue); + return attributeValueBuilder.build(); + } + }; + private static final Function<Long, AttributeValue> longAttributeValueFunction = + new Function<Long, AttributeValue>() { + @Override + public AttributeValue apply(Long longValue) { + Builder attributeValueBuilder = AttributeValue.newBuilder(); + attributeValueBuilder.setIntValue(longValue); + return attributeValueBuilder.build(); + } + }; + private final String projectId; private final TraceServiceClient traceServiceClient; private final ProjectName projectName; @@ -387,31 +418,11 @@ final class StackdriverV2ExporterHandler extends SpanExporter.Handler { private static AttributeValue toAttributeValueProto( io.opencensus.trace.AttributeValue attributeValue) { - final AttributeValue.Builder attributeValueBuilder = AttributeValue.newBuilder(); - attributeValue.match( - new Function<String, Void>() { - @Override - public Void apply(String stringValue) { - attributeValueBuilder.setStringValue(toTruncatableStringProto(stringValue)); - return null; - } - }, - new Function<Boolean, Void>() { - @Override - public Void apply(Boolean booleanValue) { - attributeValueBuilder.setBoolValue(booleanValue); - return null; - } - }, - new Function<Long, Void>() { - @Override - public Void apply(Long longValue) { - attributeValueBuilder.setIntValue(longValue); - return null; - } - }, - Functions.</*@Nullable*/ Void>returnNull()); - return attributeValueBuilder.build(); + return attributeValue.match( + stringAttributeValueFunction, + booleanAttributeValueFunction, + longAttributeValueFunction, + Functions.</*@Nullable*/ AttributeValue>returnNull()); } private static Link.Type toLinkTypeProto(io.opencensus.trace.Link.Type type) { diff --git a/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandler.java b/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandler.java index 4d0c44e7..baa2f459 100644 --- a/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandler.java +++ b/exporters/trace/zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandler.java @@ -45,12 +45,15 @@ import java.util.List; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; -import javax.annotation.Nullable; import zipkin2.Endpoint; import zipkin2.Span; import zipkin2.codec.SpanBytesEncoder; import zipkin2.reporter.Sender; +/*>>> +import org.checkerframework.checker.nullness.qual.Nullable; +*/ + final class ZipkinExporterHandler extends SpanExporter.Handler { private static final Tracer tracer = Tracing.getTracer(); private static final Sampler probabilitySampler = Samplers.probabilitySampler(0.0001); @@ -147,7 +150,7 @@ final class ZipkinExporterHandler extends SpanExporter.Handler { return spanBuilder.build(); } - @Nullable + @javax.annotation.Nullable private static Span.Kind toSpanKind(SpanData spanData) { // This is a hack because the Span API did not have SpanKind. if (spanData.getKind() == Kind.SERVER @@ -167,36 +170,19 @@ final class ZipkinExporterHandler extends SpanExporter.Handler { return SECONDS.toMicros(timestamp.getSeconds()) + NANOSECONDS.toMicros(timestamp.getNanos()); } - private static final Function<String, String> STRING_ATTRIBUTE_FUNCTION = - new Function<String, String>() { - @Override - public String apply(String stringValue) { - return stringValue; - } - }; - - private static final Function<Boolean, String> BOOLEAN_ATTRIBUTE_FUNCTION = - new Function<Boolean, String>() { - @Override - public String apply(Boolean booleanValue) { - return booleanValue.toString(); - } - }; - - private static final Function<Long, String> LONG_ATTRIBUTE_FUNCTION = - new Function<Long, String>() { + // The return type needs to be nullable when this function is used as an argument to 'match' in + // attributeValueToString, because 'match' doesn't allow covariant return types. + private static final Function<Object, /*@Nullable*/ String> returnToString = + new Function<Object, /*@Nullable*/ String>() { @Override - public String apply(Long longValue) { - return longValue.toString(); + public String apply(Object input) { + return input.toString(); } }; private static String attributeValueToString(AttributeValue attributeValue) { return attributeValue.match( - STRING_ATTRIBUTE_FUNCTION, - BOOLEAN_ATTRIBUTE_FUNCTION, - LONG_ATTRIBUTE_FUNCTION, - Functions.<String>returnConstant("")); + returnToString, returnToString, returnToString, Functions.<String>returnConstant("")); } @Override |