diff options
| author | Yang Song <songy23@users.noreply.github.com> | 2018-07-12 11:16:35 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-07-12 11:16:35 -0700 |
| commit | 5f7a05ed40ac80e3743e0bf101a62c5286821a61 (patch) | |
| tree | ead58e613f6edd23ea860ed691cecec8da4e6fb1 /contrib | |
| parent | ee73299fd10bb29d727760be3fcb2a2de1836763 (diff) | |
| download | platform_external_opencensus-java-5f7a05ed40ac80e3743e0bf101a62c5286821a61.tar.gz platform_external_opencensus-java-5f7a05ed40ac80e3743e0bf101a62c5286821a61.tar.bz2 platform_external_opencensus-java-5f7a05ed40ac80e3743e0bf101a62c5286821a61.zip | |
Contrib: Add an exemplar_util artifact to help record special exemplars. (#1297)
* Stats: Add attachment key for TraceId and SpanId.
* Move the keys to an independent artifact and add methods for encoding.
* Add this change to CHANGELOG.
* Update description and tests.
* Have one method that takes SpanContext instead of two.
* Rename method to putSpanContextAttachments.
Diffstat (limited to 'contrib')
4 files changed, 234 insertions, 0 deletions
diff --git a/contrib/exemplar_util/README.md b/contrib/exemplar_util/README.md new file mode 100644 index 00000000..88698eb5 --- /dev/null +++ b/contrib/exemplar_util/README.md @@ -0,0 +1,36 @@ +# OpenCensus Exemplar Util + +[![Build Status][travis-image]][travis-url] +[![Windows Build Status][appveyor-image]][appveyor-url] +[![Maven Central][maven-image]][maven-url] + +The *OpenCensus Exemplar Util for Java* is a collection of utilities for recording Exemplars for +OpenCensus stats. + +## Quickstart + +### Add the dependencies to your project + +For Maven add to your `pom.xml`: +```xml +<dependencies> + <dependency> + <groupId>io.opencensus</groupId> + <artifactId>opencensus-contrib-exemplar-util</artifactId> + <version>0.16.0</version> + </dependency> +</dependencies> +``` + +For Gradle add to your dependencies: +```gradle +compile 'io.opencensus:opencensus-contrib-exemplar-util:0.16.0' +``` + +[travis-image]: https://travis-ci.org/census-instrumentation/opencensus-java.svg?branch=master +[travis-url]: https://travis-ci.org/census-instrumentation/opencensus-java +[appveyor-image]: https://ci.appveyor.com/api/projects/status/hxthmpkxar4jq4be/branch/master?svg=true +[appveyor-url]: https://ci.appveyor.com/project/opencensusjavateam/opencensus-java/branch/master +[maven-image]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-contrib-exemplar-util/badge.svg +[maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-contrib-exemplar-util + diff --git a/contrib/exemplar_util/build.gradle b/contrib/exemplar_util/build.gradle new file mode 100644 index 00000000..fd32eb6f --- /dev/null +++ b/contrib/exemplar_util/build.gradle @@ -0,0 +1,14 @@ +description = 'OpenCensus Exemplar Util' + +apply plugin: 'java' + +[compileJava, compileTestJava].each() { + it.sourceCompatibility = 1.6 + it.targetCompatibility = 1.6 +} + +dependencies { + compile project(':opencensus-api') + + signature "org.codehaus.mojo.signature:java16:+@signature" +} diff --git a/contrib/exemplar_util/src/main/java/io/opencensus/contrib/exemplar/util/ExemplarUtils.java b/contrib/exemplar_util/src/main/java/io/opencensus/contrib/exemplar/util/ExemplarUtils.java new file mode 100644 index 00000000..7eb2116b --- /dev/null +++ b/contrib/exemplar_util/src/main/java/io/opencensus/contrib/exemplar/util/ExemplarUtils.java @@ -0,0 +1,79 @@ +/* + * Copyright 2018, 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.contrib.exemplar.util; + +import io.opencensus.stats.AggregationData.DistributionData.Exemplar; +import io.opencensus.stats.MeasureMap; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import javax.annotation.Nullable; + +/** + * Utils for recording {@link Exemplar}s for OpenCensus stats. + * + * @since 0.16 + */ +public final class ExemplarUtils { + + /** + * Key for {@link TraceId} in the contextual information of an {@link Exemplar}. + * + * <p>For the {@code TraceId} value of this key, it is suggested to encode it in hex (base 16) + * lower case. + * + * @since 0.16 + */ + public static final String ATTACHMENT_KEY_TRACE_ID = "TraceId"; + + /** + * Key for {@link SpanId} in the contextual information of an {@link Exemplar}. + * + * <p>For the {@code SpanId} value of this key, it is suggested to encode it in hex (base 16) + * lower case. + * + * @since 0.16 + */ + public static final String ATTACHMENT_KEY_SPAN_ID = "SpanId"; + + /** + * Puts a {@link SpanContext} into the attachments of the given {@link MeasureMap}. + * + * <p>{@link TraceId} and {@link SpanId} of the {@link SpanContext} will be encoded in base 16 + * lower case encoding. + * + * @param measureMap the {@code MeasureMap} + * @param spanContext the {@code SpanContext} to be put as attachments. + * @since 0.16 + */ + public static void putSpanContextAttachments(MeasureMap measureMap, SpanContext spanContext) { + checkNotNull(measureMap, "measureMap"); + checkNotNull(spanContext, "spanContext"); + measureMap.putAttachment(ATTACHMENT_KEY_TRACE_ID, spanContext.getTraceId().toLowerBase16()); + measureMap.putAttachment(ATTACHMENT_KEY_SPAN_ID, spanContext.getSpanId().toLowerBase16()); + } + + // TODO: reuse this method from shared artifact. + private static <T> T checkNotNull(T reference, @Nullable Object errorMessage) { + if (reference == null) { + throw new NullPointerException(String.valueOf(errorMessage)); + } + return reference; + } + + private ExemplarUtils() {} +} diff --git a/contrib/exemplar_util/src/test/java/io/opencensus/contrib/exemplar/util/ExemplarUtilsTest.java b/contrib/exemplar_util/src/test/java/io/opencensus/contrib/exemplar/util/ExemplarUtilsTest.java new file mode 100644 index 00000000..766f2c43 --- /dev/null +++ b/contrib/exemplar_util/src/test/java/io/opencensus/contrib/exemplar/util/ExemplarUtilsTest.java @@ -0,0 +1,105 @@ +/* + * Copyright 2018, 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.contrib.exemplar.util; + +import static com.google.common.truth.Truth.assertThat; +import static io.opencensus.contrib.exemplar.util.ExemplarUtils.ATTACHMENT_KEY_SPAN_ID; +import static io.opencensus.contrib.exemplar.util.ExemplarUtils.ATTACHMENT_KEY_TRACE_ID; + +import io.opencensus.stats.Measure.MeasureDouble; +import io.opencensus.stats.Measure.MeasureLong; +import io.opencensus.stats.MeasureMap; +import io.opencensus.tags.TagContext; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; +import java.util.HashMap; +import java.util.Map; +import java.util.Random; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link ExemplarUtils}. */ +@RunWith(JUnit4.class) +public class ExemplarUtilsTest { + + private static final Random RANDOM = new Random(1234); + private static final TraceId TRACE_ID = TraceId.generateRandomId(RANDOM); + private static final SpanId SPAN_ID = SpanId.generateRandomId(RANDOM); + private static final SpanContext SPAN_CONTEXT = + SpanContext.create(TRACE_ID, SPAN_ID, TraceOptions.DEFAULT); + + @Rule public final ExpectedException thrown = ExpectedException.none(); + + @Test + public void putSpanContext() { + FakeMeasureMap measureMap = new FakeMeasureMap(); + ExemplarUtils.putSpanContextAttachments(measureMap, SPAN_CONTEXT); + assertThat(measureMap.attachments) + .containsExactly( + ATTACHMENT_KEY_TRACE_ID, + TRACE_ID.toLowerBase16(), + ATTACHMENT_KEY_SPAN_ID, + SPAN_ID.toLowerBase16()); + } + + @Test + public void putSpanContext_PreventNullMeasureMap() { + thrown.expect(NullPointerException.class); + thrown.expectMessage("measureMap"); + ExemplarUtils.putSpanContextAttachments(null, SPAN_CONTEXT); + } + + @Test + public void putSpanContext_PreventNullSpanContext() { + FakeMeasureMap measureMap = new FakeMeasureMap(); + thrown.expect(NullPointerException.class); + thrown.expectMessage("spanContext"); + ExemplarUtils.putSpanContextAttachments(measureMap, null); + } + + private static final class FakeMeasureMap extends MeasureMap { + + private final Map<String, String> attachments = new HashMap<String, String>(); + + @Override + public MeasureMap putAttachment(String key, String value) { + attachments.put(key, value); + return this; + } + + @Override + public MeasureMap put(MeasureDouble measure, double value) { + return this; + } + + @Override + public MeasureMap put(MeasureLong measure, long value) { + return this; + } + + @Override + public void record() {} + + @Override + public void record(TagContext tags) {} + } +} |
