aboutsummaryrefslogtreecommitdiffstats
path: root/contrib
diff options
context:
space:
mode:
authorYang Song <songy23@users.noreply.github.com>2018-07-12 11:16:35 -0700
committerGitHub <noreply@github.com>2018-07-12 11:16:35 -0700
commit5f7a05ed40ac80e3743e0bf101a62c5286821a61 (patch)
treeead58e613f6edd23ea860ed691cecec8da4e6fb1 /contrib
parentee73299fd10bb29d727760be3fcb2a2de1836763 (diff)
downloadplatform_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')
-rw-r--r--contrib/exemplar_util/README.md36
-rw-r--r--contrib/exemplar_util/build.gradle14
-rw-r--r--contrib/exemplar_util/src/main/java/io/opencensus/contrib/exemplar/util/ExemplarUtils.java79
-rw-r--r--contrib/exemplar_util/src/test/java/io/opencensus/contrib/exemplar/util/ExemplarUtilsTest.java105
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) {}
+ }
+}