diff options
author | Fabian Lange <lange.fabian@gmail.com> | 2018-02-09 14:33:30 -0500 |
---|---|---|
committer | Bogdan Drutu <bdrutu@google.com> | 2018-02-09 11:33:30 -0800 |
commit | 17a1a1a0d19739a19b449c6d28817687ccd5b9d4 (patch) | |
tree | b5ee100816bc7f762d19a21359538f93118af596 | |
parent | ad1a3fb10f5d8a1d958a3d82be264e22ca9e5c5c (diff) | |
download | opencensus-java-17a1a1a0d19739a19b449c6d28817687ccd5b9d4.tar.gz |
First proof of concept for Instana integration (#972)
10 files changed, 584 insertions, 5 deletions
@@ -7,7 +7,7 @@ [![Coverage Status][codecov-image]][codecov-url] -OpenCensus is a toolkit for collecting application performance and behavior data. It currently +OpenCensus is a toolkit for collecting application performance and behavior data. It currently includes 3 apis: stats, tracing and tags. The library is in alpha stage and the API is subject to change. @@ -53,13 +53,13 @@ public final class MyClassWithTracing { doFinalWork(); } } - + private static void doInitialWork() { // ... tracer.getCurrentSpan().addAnnotation("Important."); // ... } - + private static void doFinalWork() { // ... tracer.getCurrentSpan().addAnnotation("More important."); @@ -74,7 +74,7 @@ TODO ## Quickstart for Applications -Besides recording tracing/stats events the application also need to link the implementation, +Besides recording tracing/stats events the application also need to link the implementation, setup exporters, and debugging [Z-Pages](https://github.com/census-instrumentation/opencensus-java/tree/master/contrib/zpages). ### Add the dependencies to your project @@ -105,6 +105,7 @@ runtime 'io.opencensus:opencensus-impl:0.11.1' ### How to setup exporters? #### Trace exporters +* [Instana][TraceExporterInstana] * [Logging][TraceExporterLogging] * [Stackdriver][TraceExporterStackdriver] * [Zipkin][TraceExporterZipkin] @@ -115,7 +116,7 @@ runtime 'io.opencensus:opencensus-impl:0.11.1' ### How to setup debugging Z-Pages? -If the application owner wants to export in-process tracing and stats data via HTML debugging pages +If the application owner wants to export in-process tracing and stats data via HTML debugging pages see this [link](https://github.com/census-instrumentation/opencensus-java/tree/master/contrib/zpages#quickstart). [travis-image]: https://travis-ci.org/census-instrumentation/opencensus-java.svg?branch=master @@ -130,6 +131,7 @@ see this [link](https://github.com/census-instrumentation/opencensus-java/tree/m [gitter-url]: https://gitter.im/census-instrumentation/lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge [codecov-image]: https://codecov.io/gh/census-instrumentation/opencensus-java/branch/master/graph/badge.svg [codecov-url]: https://codecov.io/gh/census-instrumentation/opencensus-java/branch/master/ +[TraceExporterInstana]: https://github.com/census-instrumentation/opencensus-java/tree/master/exporters/trace/instana#quickstart [TraceExporterLogging]: https://github.com/census-instrumentation/opencensus-java/tree/master/exporters/trace/logging#quickstart [TraceExporterStackdriver]: https://github.com/census-instrumentation/opencensus-java/tree/master/exporters/trace/stackdriver#quickstart [TraceExporterZipkin]: https://github.com/census-instrumentation/opencensus-java/tree/master/exporters/trace/zipkin#quickstart diff --git a/RELEASING.md b/RELEASING.md index 9067de65..2d42ed0b 100644 --- a/RELEASING.md +++ b/RELEASING.md @@ -221,6 +221,7 @@ $ README_FILES=( contrib/zpages/README.md exporters/stats/signalfx/README.md exporters/stats/stackdriver/README.md + exporters/trace/instana/README.md exporters/trace/logging/README.md exporters/trace/stackdriver/README.md exporters/trace/zipkin/README.md diff --git a/build.gradle b/build.gradle index 4e467377..a305e91a 100644 --- a/build.gradle +++ b/build.gradle @@ -335,6 +335,7 @@ subprojects { 'opencensus-contrib-zpages', 'opencensus-exporter-stats-signalfx', 'opencensus-exporter-stats-stackdriver', + 'opencensus-exporter-trace-instana', 'opencensus-exporter-trace-logging', 'opencensus-exporter-trace-stackdriver', 'opencensus-exporter-trace-zipkin', diff --git a/exporters/trace/instana/README.md b/exporters/trace/instana/README.md new file mode 100644 index 00000000..e75bfb2c --- /dev/null +++ b/exporters/trace/instana/README.md @@ -0,0 +1,73 @@ +# OpenCensus Instana Trace Exporter +[![Build Status][travis-image]][travis-url] +[![Windows Build Status][appveyor-image]][appveyor-url] +[![Maven Central][maven-image]][maven-url] + +The *OpenCensus Instana Trace Exporter* is a trace exporter that exports +data to Instana. [Instana](http://www.instana.com/) Instana is a distributed +tracing system. + +## Quickstart + +### Prerequisites + +[Instana](http://www.instana.com/) forwards traces exported by applications +instrumented with Census to its backend using the Instana agent processes as proxy. +If the agent is used on the same host as Census, please take care to deactivate +automatic tracing. + + +### Hello Stan + +#### Add the dependencies to your project + +For Maven add to your `pom.xml`: +```xml +<dependencies> + <dependency> + <groupId>io.opencensus</groupId> + <artifactId>opencensus-api</artifactId> + <version>0.12.0</version> + </dependency> + <dependency> + <groupId>io.opencensus</groupId> + <artifactId>opencensus-exporter-trace-instana</artifactId> + <version>0.12.0</version> + </dependency> + <dependency> + <groupId>io.opencensus</groupId> + <artifactId>opencensus-impl</artifactId> + <version>0.12.0</version> + <scope>runtime</scope> + </dependency> +</dependencies> +``` + +For Gradle add to your dependencies: +```groovy +compile 'io.opencensus:opencensus-api:0.12.0' +compile 'io.opencensus:opencensus-exporter-trace-instana:0.12.0' +runtime 'io.opencensus:opencensus-impl:0.12.0' +``` + +#### Register the exporter + +```java +public class MyMainClass { + public static void main(String[] args) throws Exception { + InstanaTraceExporter.createAndRegister("http://localhost:42699/com.instana.plugin.generic.trace"); + // ... + } +} +``` + +#### Java Versions + +Java 6 or above is required for using this exporter. + +[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-exporter-trace-instana/badge.svg +[maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-exporter-trace-instana diff --git a/exporters/trace/instana/build.gradle b/exporters/trace/instana/build.gradle new file mode 100644 index 00000000..edd54fc5 --- /dev/null +++ b/exporters/trace/instana/build.gradle @@ -0,0 +1,14 @@ +description = 'OpenCensus Trace Instana Exporter' + +[compileJava, compileTestJava].each() { + it.sourceCompatibility = 1.6 + it.targetCompatibility = 1.6 +} + +dependencies { + compile project(':opencensus-api') + + testCompile project(':opencensus-api') + + signature "org.codehaus.mojo.signature:java16:+@signature" +} 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 new file mode 100644 index 00000000..aa770674 --- /dev/null +++ b/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaExporterHandler.java @@ -0,0 +1,228 @@ +/* + * 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.exporter.trace.instana; + +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import com.google.common.io.BaseEncoding; +import io.opencensus.common.Duration; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.common.Scope; +import io.opencensus.common.Timestamp; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.Sampler; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.Status; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.Tracer; +import io.opencensus.trace.Tracing; +import io.opencensus.trace.export.SpanData; +import io.opencensus.trace.export.SpanExporter; +import io.opencensus.trace.samplers.Samplers; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.Charset; +import java.util.Collection; +import java.util.Map; +import java.util.Map.Entry; +import java.util.logging.Logger; + +/* + * Exports to an Instana agent acting as proxy to the Instana backend (and handling authentication) + * Uses the Trace SDK documented: + * https://github.com/instana/instana-java-sdk#instana-trace-webservice + * + * Currently does a blocking export using HttpUrlConnection. + * Also uses a StringBuilder to build JSON. + * Both can be improved should 3rd party library usage not be a concern. + * + * Major TODO is the limitation of Instana to only suport 64bit trace ids, which will be resolved. + * Until then it is crossing fingers and treating it as 50% sampler :). + */ +final class InstanaExporterHandler extends SpanExporter.Handler { + + private static final Tracer tracer = Tracing.getTracer(); + private static final Sampler probabilitySpampler = Samplers.probabilitySampler(0.0001); + static final Logger logger = Logger.getLogger(InstanaExporterHandler.class.getName()); + + private static final Function<Object, String> RETURN_STRING = + new Function<Object, String>() { + @Override + public String apply(Object input) { + return input.toString(); + } + }; + + private final URL agentEndpoint; + + InstanaExporterHandler(URL agentEndpoint) { + this.agentEndpoint = agentEndpoint; + } + + private static String encodeTraceId(TraceId traceId) { + return BaseEncoding.base16().lowerCase().encode(traceId.getBytes(), 0, 8); + } + + private static String encodeSpanId(SpanId spanId) { + return BaseEncoding.base16().lowerCase().encode(spanId.getBytes()); + } + + private static String toSpanName(SpanData spanData) { + return spanData.getName(); + } + + private static String toSpanType(SpanData spanData) { + if (spanData.getParentSpanId() == null || Boolean.TRUE.equals(spanData.getHasRemoteParent())) { + return "ENTRY"; + } + + // This is a hack because the v2 API does not have SpanKind. When switch to v2 this will be + // fixed. + if (spanData.getName().startsWith("Sent.")) { + return "EXIT"; + } + + return "INTERMEDIATE"; + } + + private static long toMillis(Timestamp timestamp) { + return SECONDS.toMillis(timestamp.getSeconds()) + NANOSECONDS.toMillis(timestamp.getNanos()); + } + + private static long toMillis(Timestamp start, Timestamp end) { + Duration duration = end.subtractTimestamp(start); + return SECONDS.toMillis(duration.getSeconds()) + NANOSECONDS.toMillis(duration.getNanos()); + } + + private static String attributeValueToString(AttributeValue attributeValue) { + return attributeValue.match( + RETURN_STRING, RETURN_STRING, RETURN_STRING, Functions.<String>returnNull()); + } + + static String convertToJson(Collection<SpanData> spanDataList) { + StringBuilder sb = new StringBuilder(); + sb.append('['); + for (final SpanData span : spanDataList) { + final SpanContext spanContext = span.getContext(); + final SpanId parentSpanId = span.getParentSpanId(); + final Timestamp startTimestamp = span.getStartTimestamp(); + final Timestamp endTimestamp = span.getEndTimestamp(); + final Status status = span.getStatus(); + if (status == null || endTimestamp == null) { + continue; + } + if (sb.length() > 1) { + sb.append(','); + } + sb.append('{'); + sb.append("\"spanId\":\"").append(encodeSpanId(spanContext.getSpanId())).append("\","); + sb.append("\"traceId\":\"").append(encodeTraceId(spanContext.getTraceId())).append("\","); + if (parentSpanId != null) { + sb.append("\"parentId\":\"").append(encodeSpanId(parentSpanId)).append("\","); + } + sb.append("\"timestamp\":").append(toMillis(startTimestamp)).append(','); + sb.append("\"duration\":").append(toMillis(startTimestamp, endTimestamp)).append(','); + sb.append("\"name\":\"").append(toSpanName(span)).append("\","); + sb.append("\"type\":\"").append(toSpanType(span)).append('"'); + if (!status.isOk()) { + sb.append(",\"error\":").append("true"); + } + Map<String, AttributeValue> attributeMap = span.getAttributes().getAttributeMap(); + if (attributeMap.size() > 0) { + StringBuilder dataSb = new StringBuilder(); + dataSb.append('{'); + for (Entry<String, AttributeValue> entry : attributeMap.entrySet()) { + if (dataSb.length() > 1) { + dataSb.append(','); + } + dataSb + .append("\"") + .append(entry.getKey()) + .append("\":\"") + .append(attributeValueToString(entry.getValue())) + .append("\""); + } + dataSb.append('}'); + + sb.append(",\"data\":").append(dataSb); + } + sb.append('}'); + } + sb.append(']'); + return sb.toString(); + } + + @Override + public void export(Collection<SpanData> spanDataList) { + // Start a new span with explicit 1/10000 sampling probability to avoid the case when user + // sets the default sampler to always sample and we get the gRPC span of the instana + // export call always sampled and go to an infinite loop. + Scope scope = + tracer.spanBuilder("ExportInstanaTraces").setSampler(probabilitySpampler).startScopedSpan(); + try { + String json = convertToJson(spanDataList); + + OutputStream outputStream = null; + InputStream inputStream = null; + try { + HttpURLConnection connection = (HttpURLConnection) agentEndpoint.openConnection(); + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + outputStream = connection.getOutputStream(); + outputStream.write(json.getBytes(Charset.defaultCharset())); + outputStream.flush(); + inputStream = connection.getInputStream(); + if (connection.getResponseCode() != 200) { + tracer + .getCurrentSpan() + .setStatus( + Status.UNKNOWN.withDescription("Response " + connection.getResponseCode())); + } + } catch (IOException e) { + tracer + .getCurrentSpan() + .setStatus( + Status.UNKNOWN.withDescription( + e.getMessage() == null ? e.getClass().getSimpleName() : e.getMessage())); + // dropping span batch + } finally { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + // ignore + } + } + if (outputStream != null) { + try { + outputStream.close(); + } catch (IOException e) { + // ignore + } + } + } + } finally { + scope.close(); + } + } +} diff --git a/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaTraceExporter.java b/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaTraceExporter.java new file mode 100644 index 00000000..1f542cdd --- /dev/null +++ b/exporters/trace/instana/src/main/java/io/opencensus/exporter/trace/instana/InstanaTraceExporter.java @@ -0,0 +1,103 @@ +/* + * 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.exporter.trace.instana; + +import static com.google.common.base.Preconditions.checkState; + +import com.google.common.annotations.VisibleForTesting; +import io.opencensus.trace.Tracing; +import io.opencensus.trace.export.SpanExporter; +import io.opencensus.trace.export.SpanExporter.Handler; +import java.net.MalformedURLException; +import java.net.URL; +import javax.annotation.Nullable; +import javax.annotation.concurrent.GuardedBy; + +/** + * An OpenCensus span exporter implementation which exports data to Instana. + * + * <p>Example of usage: + * + * <pre>{@code + * public static void main(String[] args) { + * InstanaTraceExporter.createAndRegister("http://localhost:42699/com.instana.plugin.generic.trace"); + * ... // Do work. + * } + * }</pre> + */ +public final class InstanaTraceExporter { + + private static final String REGISTER_NAME = InstanaTraceExporter.class.getName(); + private static final Object monitor = new Object(); + + @GuardedBy("monitor") + @Nullable + private static Handler handler = null; + + private InstanaTraceExporter() {} + + /** + * Creates and registers the Instana Trace exporter to the OpenCensus library. Only one Instana + * exporter can be registered at any point. + * + * @param agentEndpoint Ex http://localhost:42699/com.instana.plugin.generic.trace + * @throws MalformedURLException if the agentEndpoint is not a valid http url. + * @throws IllegalStateException if a Instana exporter is already registered. + */ + public static void createAndRegister(String agentEndpoint) throws MalformedURLException { + synchronized (monitor) { + checkState(handler == null, "Instana exporter is already registered."); + Handler newHandler = new InstanaExporterHandler(new URL(agentEndpoint)); + handler = newHandler; + register(Tracing.getExportComponent().getSpanExporter(), newHandler); + } + } + + /** + * Registers the {@code InstanaTraceExporter}. + * + * @param spanExporter the instance of the {@code SpanExporter} where this service is registered. + */ + @VisibleForTesting + static void register(SpanExporter spanExporter, Handler handler) { + spanExporter.registerHandler(REGISTER_NAME, handler); + } + + /** + * Unregisters the Instana Trace exporter from the OpenCensus library. + * + * @throws IllegalStateException if a Instana exporter is not registered. + */ + public static void unregister() { + synchronized (monitor) { + checkState(handler != null, "Instana exporter is not registered."); + unregister(Tracing.getExportComponent().getSpanExporter()); + handler = null; + } + } + + /** + * Unregisters the {@code InstanaTraceExporter}. + * + * @param spanExporter the instance of the {@code SpanExporter} from where this service is + * unregistered. + */ + @VisibleForTesting + static void unregister(SpanExporter spanExporter) { + spanExporter.unregisterHandler(REGISTER_NAME); + } +} diff --git a/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaExporterHandlerTest.java b/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaExporterHandlerTest.java new file mode 100644 index 00000000..29d512d5 --- /dev/null +++ b/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaExporterHandlerTest.java @@ -0,0 +1,100 @@ +/* + * 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.exporter.trace.instana; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import io.opencensus.common.Timestamp; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.Link; +import io.opencensus.trace.NetworkEvent; +import io.opencensus.trace.NetworkEvent.Type; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.Status; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.TraceOptions; +import io.opencensus.trace.export.SpanData; +import io.opencensus.trace.export.SpanData.Attributes; +import io.opencensus.trace.export.SpanData.Links; +import io.opencensus.trace.export.SpanData.TimedEvent; +import io.opencensus.trace.export.SpanData.TimedEvents; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Unit tests for {@link InstanaExporterHandler}. */ +@RunWith(JUnit4.class) +public class InstanaExporterHandlerTest { + + @Test + public void generateSpan() { + String traceId = "d239036e7d5cec116b562147388b35bf"; + String spanId = "9cc1e3049173be09"; + String parentId = "8b03ab423da481c5"; + Map<String, AttributeValue> attributes = + Collections.singletonMap( + "http.url", AttributeValue.stringAttributeValue("http://localhost/foo")); + List<TimedEvent<Annotation>> annotations = Collections.emptyList(); + List<TimedEvent<NetworkEvent>> networkEvents = + ImmutableList.of( + TimedEvent.create( + Timestamp.create(1505855799, 433901068), + NetworkEvent.builder(Type.RECV, 0).setCompressedMessageSize(7).build()), + TimedEvent.create( + Timestamp.create(1505855799, 459486280), + NetworkEvent.builder(Type.SENT, 0).setCompressedMessageSize(13).build())); + SpanData data = + SpanData.create( + SpanContext.create( + TraceId.fromLowerBase16(traceId), + SpanId.fromLowerBase16(spanId), + TraceOptions.fromBytes(new byte[] {1} /* sampled */)), + SpanId.fromLowerBase16(parentId), + true, /* hasRemoteParent */ + "SpanName", /* name */ + Timestamp.create(1505855794, 194009601) /* startTimestamp */, + Attributes.create(attributes, 0 /* droppedAttributesCount */), + TimedEvents.create(annotations, 0 /* droppedEventsCount */), + TimedEvents.create(networkEvents, 0 /* droppedEventsCount */), + Links.create(Collections.<Link>emptyList(), 0 /* droppedLinksCount */), + null, /* childSpanCount */ + Status.OK, + Timestamp.create(1505855799, 465726528) /* endTimestamp */); + + assertThat(InstanaExporterHandler.convertToJson(Collections.singletonList(data))) + .isEqualTo( + "[" + + "{" + + "\"spanId\":\"9cc1e3049173be09\"," + + "\"traceId\":\"d239036e7d5cec11\"," + + "\"parentId\":\"8b03ab423da481c5\"," + + "\"timestamp\":1505855794194," + + "\"duration\":5271," + + "\"name\":\"SpanName\"," + + "\"type\":\"ENTRY\"," + + "\"data\":" + + "{\"http.url\":\"http://localhost/foo\"}" + + "}" + + "]"); + } +} diff --git a/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaTraceExporterTest.java b/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaTraceExporterTest.java new file mode 100644 index 00000000..a4d03df3 --- /dev/null +++ b/exporters/trace/instana/src/test/java/io/opencensus/exporter/trace/instana/InstanaTraceExporterTest.java @@ -0,0 +1,54 @@ +/* + * 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.exporter.trace.instana; + +import static org.mockito.Matchers.eq; +import static org.mockito.Matchers.same; +import static org.mockito.Mockito.verify; + +import io.opencensus.trace.export.SpanExporter; +import io.opencensus.trace.export.SpanExporter.Handler; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; + +/** Unit tests for {@link InstanaTraceExporter}. */ +@RunWith(JUnit4.class) +public class InstanaTraceExporterTest { + + @Mock private SpanExporter spanExporter; + @Mock private Handler handler; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void registerUnregisterInstanaExporter() { + InstanaTraceExporter.register(spanExporter, handler); + verify(spanExporter) + .registerHandler( + eq("io.opencensus.exporter.trace.instana.InstanaTraceExporter"), same(handler)); + InstanaTraceExporter.unregister(spanExporter); + verify(spanExporter) + .unregisterHandler(eq("io.opencensus.exporter.trace.instana.InstanaTraceExporter")); + } +} diff --git a/settings.gradle b/settings.gradle index 5456e658..6921de56 100644 --- a/settings.gradle +++ b/settings.gradle @@ -5,6 +5,7 @@ include ":opencensus-impl-core" include ":opencensus-impl-lite" include ":opencensus-impl" include ":opencensus-testing" +include ":opencensus-exporter-trace-instana" include ":opencensus-exporter-trace-logging" include ":opencensus-exporter-trace-stackdriver" include ":opencensus-exporter-trace-zipkin" @@ -24,6 +25,8 @@ project(':opencensus-contrib-agent').projectDir = "$rootDir/contrib/agent" as Fi project(':opencensus-contrib-grpc-metrics').projectDir = "$rootDir/contrib/grpc_metrics" as File project(':opencensus-contrib-grpc-util').projectDir = "$rootDir/contrib/grpc_util" as File project(':opencensus-contrib-http-util').projectDir = "$rootDir/contrib/http_util" as File +project(':opencensus-exporter-trace-instana').projectDir = + "$rootDir/exporters/trace/instana" as File project(':opencensus-exporter-trace-logging').projectDir = "$rootDir/exporters/trace/logging" as File project(':opencensus-exporter-trace-stackdriver').projectDir = |