diff options
| author | Adrian Cole <adriancole@users.noreply.github.com> | 2017-09-24 10:46:17 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-09-24 10:46:17 +0800 |
| commit | d05056c351f301e52efc07eb6389afd10d3949ca (patch) | |
| tree | b6d5a0801fe5d329aab57363399276ad0f95bb03 | |
| parent | 83f82dbe96fd5e0fc2468aa2b696a92953666c65 (diff) | |
| download | platform_external_opencensus-java-d05056c351f301e52efc07eb6389afd10d3949ca.tar.gz platform_external_opencensus-java-d05056c351f301e52efc07eb6389afd10d3949ca.tar.bz2 platform_external_opencensus-java-d05056c351f301e52efc07eb6389afd10d3949ca.zip | |
Adds ZipkinExporter (#620)
This adds `ZipkinExporter` which allows you to report traces to Zipkin.
By default, this uses http, but it can also work with Kafka, SQS, etc
as you can override the `Sender`.
8 files changed, 567 insertions, 0 deletions
diff --git a/build.gradle b/build.gradle index 0048a24a..60ebe354 100644 --- a/build.gradle +++ b/build.gradle @@ -108,6 +108,7 @@ subprojects { guavaVersion = '19.0' googleAuthVersion = '0.8.0' googleCloudVersion = '0.24.0-alpha' + zipkinReporterVersion = '2.0.0' libraries = [ auto_value: "com.google.auto.value:auto-value:${autoValueVersion}", @@ -118,6 +119,8 @@ subprojects { findbugs_annotations: "com.google.code.findbugs:annotations:${findBugsVersion}", google_auth: "com.google.auth:google-auth-library-credentials:${googleAuthVersion}", google_cloud_trace: "com.google.cloud:google-cloud-trace:${googleCloudVersion}", + zipkin_reporter: "io.zipkin.reporter2:zipkin-reporter:${zipkinReporterVersion}", + zipkin_urlconnection: "io.zipkin.reporter2:zipkin-sender-urlconnection:${zipkinReporterVersion}", grpc_context: "io.grpc:grpc-context:${grpcVersion}", grpc_core: "io.grpc:grpc-core:${grpcVersion}", guava: "com.google.guava:guava:${guavaVersion}", diff --git a/exporters/trace_zipkin/README.md b/exporters/trace_zipkin/README.md new file mode 100644 index 00000000..2e2a5e42 --- /dev/null +++ b/exporters/trace_zipkin/README.md @@ -0,0 +1,74 @@ +# OpenCensus Zipkin Trace Exporter +[![Build Status][travis-image]][travis-url] [![Build status][appveyor-image]][appveyor-url] [![Maven Central][maven-image]][maven-url] + +The *OpenCensus Zipkin Trace Exporter* is a trace exporter that exports +data to Zipkin. [Zipkin](http://zipkin.io/) Zipkin is a distributed +tracing system. It helps gather timing data needed to troubleshoot +latency problems in microservice architectures. It manages both the +collection and lookup of this data. + +## Quickstart + +### Prerequisites + +[Zipkin](http://zipkin.io/) stores and queries traces exported by +applications instrumented with Census. The easiest way to start a zipkin +server is to paste the below: + +```bash +wget -O zipkin.jar 'https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec' +java -jar zipkin.jar +``` + + +### Hello Zipkin + +#### Add the dependencies to your project + +For Maven add to your `pom.xml`: +```xml +<dependencies> + <dependency> + <groupId>io.opencensus</groupId> + <artifactId>opencensus-exporter-trace-zipkin</artifactId> + <version>0.7.0</version> + </dependency> + <dependency> + <groupId>io.opencensus</groupId> + <artifactId>opencensus-impl</artifactId> + <version>0.7.0</version> + <scope>runtime</scope> + </dependency> +</dependencies> +``` + +For Gradle add to your dependencies: +```groovy +compile 'io.opencensus:opencensus-exporter-trace-zipkin:0.7.0' +runtime 'io.opencensus:opencensus-impl:0.7.0' +``` + +#### Register the exporter + +This will report Zipkin v2 json format to a single server. Alternate +[senders](https://github.com/openzipkin/zipkin-reporter-java) are available. + +```java +public class MyMainClass { + public static void main(String[] args) throws Exception { + ZipkinExporter.createAndRegister("http://127.0.0.1:9411/api/v2/spans"); + // ... + } +} +``` + +#### 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/instrumentationjavateam/opencensus-java/branch/master +[maven-image]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-exporter-trace-zipkin/badge.svg +[maven-url]: https://maven-badges.herokuapp.com/maven-central/io.opencensus/opencensus-exporter-trace-zipkin
\ No newline at end of file diff --git a/exporters/trace_zipkin/build.gradle b/exporters/trace_zipkin/build.gradle new file mode 100644 index 00000000..3a479690 --- /dev/null +++ b/exporters/trace_zipkin/build.gradle @@ -0,0 +1,16 @@ +description = 'OpenCensus Trace Zipkin Exporter' + +[compileJava, compileTestJava].each() { + it.sourceCompatibility = 1.6 + it.targetCompatibility = 1.6 +} + +dependencies { + compile project(':opencensus-api'), + libraries.zipkin_reporter, + libraries.zipkin_urlconnection + + testCompile project(':opencensus-api') + + signature "org.codehaus.mojo.signature:java16:+@signature" +} diff --git a/exporters/trace_zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporter.java b/exporters/trace_zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporter.java new file mode 100644 index 00000000..b90abfd4 --- /dev/null +++ b/exporters/trace_zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporter.java @@ -0,0 +1,116 @@ +/* + * Copyright 2017, 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.zipkin; + +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 javax.annotation.concurrent.GuardedBy; +import zipkin2.Span; +import zipkin2.codec.SpanBytesEncoder; +import zipkin2.reporter.Sender; +import zipkin2.reporter.urlconnection.URLConnectionSender; + +/** + * An OpenCensus span exporter implementation which exports data to Zipkin. + * + * <p>Example of usage: + * + * <pre><code> + * public static void main(String[] args) { + * ZipkinExporter.createAndRegister("http://127.0.0.1:9411/api/v2/spans", "myservicename"); + * ... // Do work. + * } + * </code></pre> + */ +public final class ZipkinExporter { + + private static final String REGISTER_NAME = ZipkinExporter.class.getName(); + private static final Object monitor = new Object(); + + @GuardedBy("monitor") + private static Handler handler = null; + + private ZipkinExporter() {} + + /** + * Creates and registers the Zipkin Trace exporter to the OpenCensus library. Only one Zipkin + * exporter can be registered at any point. + * + * @param v2Url Ex http://127.0.0.1:9411/api/v2/spans + * @param serviceName the {@link Span#localServiceName() local service name} of the process. + * @throws IllegalStateException if a Zipkin exporter is already registered. + */ + public static void createAndRegister(String v2Url, String serviceName) { + createAndRegister(SpanBytesEncoder.JSON_V2, URLConnectionSender.create(v2Url), serviceName); + } + + /** + * Creates and registers the Zipkin Trace exporter to the OpenCensus library. Only one Zipkin + * exporter can be registered at any point. + * + * @param encoder Usually {@link SpanBytesEncoder#JSON_V2} + * @param sender Often, but not necessarily an http sender. This could be Kafka or SQS. + * @param serviceName the {@link Span#localServiceName() local service name} of the process. + * @throws IllegalStateException if a Zipkin exporter is already registered. + */ + public static void createAndRegister(SpanBytesEncoder encoder, Sender sender, + String serviceName) { + synchronized (monitor) { + checkState(handler == null, "Zipkin exporter is already registered."); + handler = new ZipkinExporterHandler(encoder, sender, serviceName); + register(Tracing.getExportComponent().getSpanExporter(), handler); + } + } + + /** + * Registers the {@code ZipkinExporter}. + * + * @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 Zipkin Trace exporter from the OpenCensus library. + * + * @throws IllegalStateException if a Zipkin exporter is not registered. + */ + public static void unregister() { + synchronized (monitor) { + checkState(handler != null, "Zipkin exporter is not registered."); + unregister(Tracing.getExportComponent().getSpanExporter()); + handler = null; + } + } + + /** + * Unregisters the {@code ZipkinExporter}. + * + * @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_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 new file mode 100644 index 00000000..96d8352a --- /dev/null +++ b/exporters/trace_zipkin/src/main/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandler.java @@ -0,0 +1,189 @@ +/* + * Copyright 2017, 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.zipkin; + +import static java.util.concurrent.TimeUnit.NANOSECONDS; +import static java.util.concurrent.TimeUnit.SECONDS; + +import com.google.common.io.BaseEncoding; +import io.opencensus.common.Function; +import io.opencensus.common.Functions; +import io.opencensus.common.Timestamp; +import io.opencensus.trace.Annotation; +import io.opencensus.trace.AttributeValue; +import io.opencensus.trace.NetworkEvent; +import io.opencensus.trace.SpanContext; +import io.opencensus.trace.SpanId; +import io.opencensus.trace.TraceId; +import io.opencensus.trace.export.SpanData; +import io.opencensus.trace.export.SpanData.TimedEvent; +import io.opencensus.trace.export.SpanExporter; +import java.io.IOException; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; +import zipkin2.Endpoint; +import zipkin2.Span; +import zipkin2.codec.SpanBytesEncoder; +import zipkin2.reporter.Sender; + +final class ZipkinExporterHandler extends SpanExporter.Handler { + + static final Logger logger = Logger.getLogger(ZipkinExporterHandler.class.getName()); + + private static final String STATUS_CODE = "census.status_code"; + private static final String STATUS_DESCRIPTION = "census.status_description"; + private static final Function<Object, String> RETURN_STRING = + new Function<Object, String>() { + @Override + public String apply(Object input) { + return input.toString(); + } + }; + private final SpanBytesEncoder encoder; + private final Sender sender; + private final Endpoint localEndpoint; + + ZipkinExporterHandler(SpanBytesEncoder encoder, Sender sender, String serviceName) { + this.encoder = encoder; + this.sender = sender; + this.localEndpoint = produceLocalEndpoint(serviceName); + } + + /** + * Logic borrowed from brave.internal.Platform.produceLocalEndpoint + */ + static Endpoint produceLocalEndpoint(String serviceName) { + Endpoint.Builder builder = Endpoint.newBuilder().serviceName(serviceName); + try { + Enumeration<NetworkInterface> nics = NetworkInterface.getNetworkInterfaces(); + if (nics == null) { + return builder.build(); + } + while (nics.hasMoreElements()) { + NetworkInterface nic = nics.nextElement(); + Enumeration<InetAddress> addresses = nic.getInetAddresses(); + while (addresses.hasMoreElements()) { + InetAddress address = addresses.nextElement(); + if (address.isSiteLocalAddress()) { + builder.ip(address); + break; + } + } + } + } catch (Exception e) { + // don't crash the caller if there was a problem reading nics. + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, "error reading nics", e); + } + } + return builder.build(); + } + + static Span generateSpan(SpanData spanData, Endpoint localEndpoint) { + SpanContext context = spanData.getContext(); + long startTimestamp = toEpochMicros(spanData.getStartTimestamp()); + long endTimestamp = toEpochMicros(spanData.getEndTimestamp()); + Span.Builder spanBuilder = Span.newBuilder() + .traceId(encodeTraceId(context.getTraceId())) + .id(encodeSpanId(context.getSpanId())) + .kind(toSpanKind(spanData)) + .name(spanData.getName()) + .timestamp(toEpochMicros(spanData.getStartTimestamp())) + .duration(endTimestamp - startTimestamp) + .localEndpoint(localEndpoint); + + if (spanData.getParentSpanId() != null && spanData.getParentSpanId().isValid()) { + spanBuilder.parentId(encodeSpanId(spanData.getParentSpanId())); + } + + for (Map.Entry<String, AttributeValue> label : + spanData.getAttributes().getAttributeMap().entrySet()) { + spanBuilder.putTag(label.getKey(), attributeValueToString(label.getValue())); + } + spanBuilder.putTag(STATUS_CODE, spanData.getStatus().getCanonicalCode().toString()); + if (spanData.getStatus().getDescription() != null) { + spanBuilder.putTag(STATUS_DESCRIPTION, spanData.getStatus().getDescription()); + } + + for (TimedEvent<Annotation> annotation : spanData.getAnnotations().getEvents()) { + spanBuilder.addAnnotation( + toEpochMicros(annotation.getTimestamp()), + annotation.getEvent().getDescription() + ); + } + + for (TimedEvent<NetworkEvent> networkEvent : spanData.getNetworkEvents().getEvents()) { + spanBuilder.addAnnotation( + toEpochMicros(networkEvent.getTimestamp()), + networkEvent.getEvent().getType().name() + ); + } + + return spanBuilder.build(); + } + + private static String encodeTraceId(TraceId traceId) { + return BaseEncoding.base16().lowerCase().encode(traceId.getBytes()); + } + + private static String encodeSpanId(SpanId spanId) { + return BaseEncoding.base16().lowerCase().encode(spanId.getBytes()); + } + + private static Span.Kind toSpanKind(SpanData spanData) { + if (Boolean.TRUE.equals(spanData.getHasRemoteParent())) { + return Span.Kind.SERVER; + } + + // 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 Span.Kind.CLIENT; + } + + return null; + } + + private static long toEpochMicros(Timestamp timestamp) { + return SECONDS.toMicros(timestamp.getSeconds()) + NANOSECONDS.toMicros(timestamp.getNanos()); + } + + private static String attributeValueToString(AttributeValue attributeValue) { + return attributeValue.match( + RETURN_STRING, RETURN_STRING, RETURN_STRING, Functions.<String>returnNull()); + } + + @Override + public void export(Collection<SpanData> spanDataList) { + List<byte[]> encodedSpans = new ArrayList<byte[]>(spanDataList.size()); + for (SpanData spanData : spanDataList) { + encodedSpans.add(encoder.encode(generateSpan(spanData, localEndpoint))); + } + try { + sender.sendSpans(encodedSpans).execute(); + } catch (IOException e) { + throw new RuntimeException(e); // TODO: should we instead do drop metrics? + } + } +} diff --git a/exporters/trace_zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandlerTest.java b/exporters/trace_zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandlerTest.java new file mode 100644 index 00000000..3d95a795 --- /dev/null +++ b/exporters/trace_zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterHandlerTest.java @@ -0,0 +1,110 @@ +/* + * Copyright 2017, 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.zipkin; + +import static com.google.common.truth.Truth.assertThat; + +import com.google.common.collect.ImmutableList; +import com.google.common.io.BaseEncoding; +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; +import zipkin2.Endpoint; +import zipkin2.Span; +import zipkin2.Span.Kind; + +/** + * Unit tests for {@link ZipkinExporterHandler}. + */ +@RunWith(JUnit4.class) +public class ZipkinExporterHandlerTest { + + @Test + public void generateSpan() { + Endpoint localEndpoint = Endpoint.newBuilder().serviceName("tweetiebird").build(); + String traceId = "d239036e7d5cec116b562147388b35bf"; + String spanId = "9cc1e3049173be09"; + String parentId = "8b03ab423da481c5"; + Map<String, AttributeValue> attributes = Collections.emptyMap(); + 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( + // TODO SpanId.fromLowerBase16 + TraceId.fromBytes(BaseEncoding.base16().lowerCase().decode(traceId)), + // TODO SpanId.fromLowerBase16 + SpanId.fromBytes(BaseEncoding.base16().lowerCase().decode(spanId)), + TraceOptions.fromBytes(new byte[]{1} /* sampled */) + ), + // TODO SpanId.fromLowerBase16 + SpanId.fromBytes(BaseEncoding.base16().lowerCase().decode(parentId)), + true, /* hasRemoteParent */ + "Recv.helloworld.Greeter.SayHello", /* 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(ZipkinExporterHandler.generateSpan(data, localEndpoint)).isEqualTo(Span.newBuilder() + .traceId(traceId) + .parentId(parentId) + .id(spanId) + .kind(Kind.SERVER) + .name(data.getName()) + .timestamp(1505855794000000L + 194009601L / 1000) + .duration((1505855799000000L + 465726528L / 1000) - (1505855794000000L + 194009601L / 1000)) + .localEndpoint(localEndpoint) + .addAnnotation(1505855799000000L + 433901068L / 1000, "RECV") + .addAnnotation(1505855799000000L + 459486280L / 1000, "SENT") + .putTag("census.status_code", "OK") + .build() + ); + } +} diff --git a/exporters/trace_zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterTest.java b/exporters/trace_zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterTest.java new file mode 100644 index 00000000..d43dc205 --- /dev/null +++ b/exporters/trace_zipkin/src/test/java/io/opencensus/exporter/trace/zipkin/ZipkinExporterTest.java @@ -0,0 +1,57 @@ +/* + * Copyright 2017, 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.zipkin; + +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 ZipkinExporter}. + */ +@RunWith(JUnit4.class) +public class ZipkinExporterTest { + @Mock + private SpanExporter spanExporter; + @Mock + private Handler handler; + + @Before + public void setUp() { + MockitoAnnotations.initMocks(this); + } + + @Test + public void registerUnregisterZipkinExporter() { + ZipkinExporter.register(spanExporter, handler); + verify(spanExporter) + .registerHandler( + eq("io.opencensus.exporter.trace.zipkin.ZipkinExporter"), same(handler)); + ZipkinExporter.unregister(spanExporter); + verify(spanExporter) + .unregisterHandler(eq("io.opencensus.exporter.trace.zipkin.ZipkinExporter")); + } +} diff --git a/settings.gradle b/settings.gradle index c3f164e3..abdebed8 100644 --- a/settings.gradle +++ b/settings.gradle @@ -7,6 +7,7 @@ include ":opencensus-impl" include ":opencensus-testing" include ":opencensus-exporter-trace-logging" include ":opencensus-exporter-trace-stackdriver" +include ":opencensus-exporter-trace-zipkin" include ":core" include ":core_impl" include ":core_impl_java" @@ -23,6 +24,7 @@ project(':opencensus-contrib-agent').projectDir = "$rootDir/contrib/agent" as Fi project(':opencensus-contrib-grpc-util').projectDir = "$rootDir/contrib/grpc_util" as File project(':opencensus-exporter-trace-logging').projectDir = "$rootDir/exporters/trace_logging" as File project(':opencensus-exporter-trace-stackdriver').projectDir = "$rootDir/exporters/trace_stackdriver" as File +project(':opencensus-exporter-trace-zipkin').projectDir = "$rootDir/exporters/trace_zipkin" as File // Java8 projects only if (JavaVersion.current().isJava8Compatible()) { |
