Skip to content

Commit

Permalink
First cut at a Zipkin Span Exporter (#1106)
Browse files Browse the repository at this point in the history
* basic zipkin span exporter with some unit tests

* add tests for the configuration class, hook up a create method and clean up other unit tests

* add a README

* Update exporters/zipkin/README.md

Co-Authored-By: Adrian Cole <adriancole@users.noreply.github.com>

* Update exporters/zipkin/src/main/java/io/opentelemetry/exporters/zipkin/ZipkinSpanExporter.java

Co-Authored-By: Adrian Cole <adriancole@users.noreply.github.com>

* Update exporters/zipkin/README.md

Co-Authored-By: Adrian Cole <adriancole@users.noreply.github.com>

* apply PR review comments

* Update build.gradle

Co-Authored-By: Adrian Cole <adriancole@users.noreply.github.com>

* a little bit of cleanup from PR review

* implement shutdown and provide javadoc about the closing of the Sender

* don't set attributes if they're already set.

* formatting

* grpc tweaks, and an exception thrown

* Update the comment to be a little more accurate.

* formatting

* Update exporters/zipkin/src/main/java/io/opentelemetry/exporters/zipkin/ZipkinExporterConfiguration.java

Co-Authored-By: Adrian Cole <adriancole@users.noreply.github.com>

* Update exporters/zipkin/src/main/java/io/opentelemetry/exporters/zipkin/ZipkinExporterConfiguration.java

Co-Authored-By: Adrian Cole <adriancole@users.noreply.github.com>

* doc/naming cleanup

* simplify the builder, provide two simple factory methods

* strip out the endpoint logic and instead get it from the Resource

* formatting

* restore the serviceName option, but keep the Resource-based override.

* update for changes from master.

* remove factory methods on the configuration, and update the README

* update the docs to match the requirements

* fix a typo

* tiny re-arrange of javadoc

* Add zipkin to the top-level docs

Co-authored-by: Adrian Cole <adriancole@users.noreply.github.com>
  • Loading branch information
jkwatson and adriancole authored May 1, 2020
1 parent 5211c97 commit 0ce1a38
Show file tree
Hide file tree
Showing 12 changed files with 850 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@

- Initial Java API and SDK for context, trace, metrics, resource.
- Initial implementation of the Jaeger exporter.
- Initial implementation of the Zipkin exporter.
- Initial implementation of the OTLP exporters for trace and metrics.
1 change: 1 addition & 0 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -352,6 +352,7 @@ Span processors are initialized with an exporter which is responsible for sendin
a particular backend. OpenTelemetry offers four exporters out of the box:
- In-Memory Exporter: keeps the data in memory, useful for debugging.
- Jaeger Exporter: prepares and sends the collected telemetry data to a Jaeger backend via gRPC.
- Zipkin Exporter: prepares and sends the collected telemetry data to a Zipkin backend via the Zipkin APIs.
- Logging Exporter: saves the telemetry data into log streams.
- OpenTelemetry Exporter: sends the data to the [OpenTelemetry Collector] (not yet implemented).

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ This is a **current** feature status list:
| Metrics SDK | v0.3.0 |
| OTLP Exporter | v0.3.0 |
| Jaeger Trace Exporter | v0.3.0 |
| Zipkin Trace Exporter | N/A |
| Zipkin Trace Exporter | dev |
| Prometheus Metrics Exporter | dev |
| Context Propagation | v0.3.0 |
| OpenTracing Bridge | v0.3.0 |
Expand Down
1 change: 1 addition & 0 deletions all/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ def subprojects = [
project(':opentelemetry-exporters-jaeger'),
project(':opentelemetry-exporters-otlp'),
project(':opentelemetry-exporters-prometheus'),
project(':opentelemetry-exporters-zipkin'),
project(':opentelemetry-opentracing-shim'),
project(':opentelemetry-sdk'),
project(':opentelemetry-sdk-contrib-async-processor'),
Expand Down
3 changes: 3 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ subprojects {
prometheusVersion = '0.8.1'
protobufVersion = '3.11.4'
protocVersion = '3.11.4'
zipkinReporterVersion = '2.12.2'

libraries = [
auto_value : "com.google.auto.value:auto-value:${autoValueVersion}",
Expand All @@ -117,6 +118,8 @@ subprojects {
prometheus_client_common: "io.prometheus:simpleclient_common:${prometheusVersion}",
protobuf : "com.google.protobuf:protobuf-java:${protobufVersion}",
protobuf_util : "com.google.protobuf:protobuf-java-util:${protobufVersion}",
zipkin_reporter : "io.zipkin.reporter2:zipkin-reporter:${zipkinReporterVersion}",
zipkin_urlconnection : "io.zipkin.reporter2:zipkin-sender-urlconnection:${zipkinReporterVersion}",

// Compatibility layer
opentracing : "io.opentracing:opentracing-api:${opentracingVersion}",
Expand Down
40 changes: 40 additions & 0 deletions exporters/zipkin/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# OpenTelemetry - Zipkin Span Exporter

[![Javadocs][javadoc-image]][javadoc-url]

This is an OpenTelemetry exporter that sends span data using the [io.zipkin.reporter2:zipkin-reporter](https://github.com/openzipkin/zipkin-reporter-java") library.

By default, this POSTs json in [Zipkin format](https://zipkin.io/zipkin-api/#/default/post_spans) to
a specified HTTP URL. This could be to a [Zipkin](https://zipkin.io) service, or anything that
consumes the same format.

You can alternatively use other formats, such as protobuf, or override the `Sender` to use a non-HTTP transport, such as Kafka.

## Configuration

The Zipkin span exporter can be configured programmatically.

An example of simple Zipkin exporter initialization. In this case
spans will be sent to a Zipkin endpoint running on `localhost`:

```java
ZipkinExporterConfiguration configuration =
ZipkinExporterConfiguration.builder()
.setEndpoint("http://localhost/api/v2/spans")
.setServiceName("my-service")
.build();

ZipkinSpanExporter exporter = ZipkinSpanExporter.create(configuration);
```

## Compatibility

As with the OpenTelemetry SDK itself, this exporter is compatible with Java 7+ and Android API level 24+.

## Attribution

The code in this module is based on the [OpenCensus Zipkin exporter][oc-origin] code.

[javadoc-image]: https://www.javadoc.io/badge/io.opentelemetry/opentelemetry-exporters-zipkin.svg
[javadoc-url]: https://www.javadoc.io/doc/io.opentelemetry/opentelemetry-exporters-zipkin
[oc-origin]: https://github.com/census-instrumentation/opencensus-java/
32 changes: 32 additions & 0 deletions exporters/zipkin/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
plugins {
id "java"
id "maven-publish"

id "ru.vyarus.animalsniffer"
}

description = 'OpenTelemetry - Zipkin Exporter'
ext.moduleName = "io.opentelemetry.exporters.zipkin"

dependencies {
compileOnly libraries.auto_value

api project(':opentelemetry-sdk')

annotationProcessor libraries.auto_value

implementation libraries.zipkin_reporter
implementation libraries.zipkin_urlconnection

testImplementation libraries.guava

signature "org.codehaus.mojo.signature:java17:1.0@signature"
signature "net.sf.androidscents.signature:android-api-level-24:7.0_r2@signature"
}

animalsniffer {
// Don't check sourceSets.jmh and sourceSets.test
sourceSets = [
sourceSets.main
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
* Copyright 2020, OpenTelemetry 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.opentelemetry.exporters.zipkin;

import com.google.auto.value.AutoValue;
import javax.annotation.concurrent.Immutable;
import zipkin2.Span;
import zipkin2.codec.BytesEncoder;
import zipkin2.codec.SpanBytesEncoder;
import zipkin2.reporter.Sender;
import zipkin2.reporter.urlconnection.URLConnectionSender;

/**
* Configurations for {@link ZipkinSpanExporter}.
*
* @since 0.4.0
*/
@AutoValue
@Immutable
public abstract class ZipkinExporterConfiguration {

ZipkinExporterConfiguration() {}

abstract String getServiceName();

abstract Sender getSender();

abstract BytesEncoder<Span> getEncoder();

/**
* Returns a new {@link Builder}, defaulted to use the {@link SpanBytesEncoder#JSON_V2} encoder.
*
* @return a {@code Builder}.
* @since 0.4.0
*/
public static Builder builder() {
return new AutoValue_ZipkinExporterConfiguration.Builder().setEncoder(SpanBytesEncoder.JSON_V2);
}

/**
* Builder for {@link ZipkinExporterConfiguration}.
*
* @since 0.4.0
*/
@AutoValue.Builder
public abstract static class Builder {

Builder() {}

/**
* Label of the remote node in the service graph, such as "favstar". Avoid names with variables
* or unique identifiers embedded. Defaults to "unknown".
*
* <p>This is a primary label for trace lookup and aggregation, so it should be intuitive and
* consistent. Many use a name from service discovery.
*
* <p>Note: this value, will be superceded by the value of {@link
* io.opentelemetry.sdk.resources.ResourceConstants#SERVICE_NAME} if it has been set in the
* {@link io.opentelemetry.sdk.resources.Resource} associated with the Tracer that created the
* spans.
*
* <p>This property is required to be set.
*
* @see io.opentelemetry.sdk.resources.Resource
* @see io.opentelemetry.sdk.resources.ResourceConstants
* @since 0.4.0
*/
public abstract Builder setServiceName(String serviceName);

/**
* Sets the Zipkin sender. Implements the client side of the span transport. A {@link
* URLConnectionSender} is a good default.
*
* <p>The {@link Sender#close()} method will be called when the exporter is shut down.
*
* @param sender the Zipkin sender implementation.
* @since 0.4.0
*/
public abstract Builder setSender(Sender sender);

/**
* Sets the {@link BytesEncoder}, which controls the format used by the {@link Sender}. Defaults
* to the {@link SpanBytesEncoder#JSON_V2}.
*
* @param encoder the {@code BytesEncoder} to use.
* @see SpanBytesEncoder
* @since 0.4.0
*/
public abstract Builder setEncoder(BytesEncoder<Span> encoder);

/**
* Sets the zipkin endpoint. This will use the endpoint to assign a {@link URLConnectionSender}
* instance to this builder.
*
* @param endpoint The Zipkin endpoint URL, ex. "http://zipkinhost:9411/api/v2/spans".
* @see URLConnectionSender
* @since 0.4.0
*/
public Builder setEndpoint(String endpoint) {
setSender(URLConnectionSender.create(endpoint));
return this;
}

/**
* Builds a {@link ZipkinExporterConfiguration}.
*
* @return a {@code ZipkinExporterConfiguration}.
* @since 0.4.0
*/
public abstract ZipkinExporterConfiguration build();
}
}
Loading

0 comments on commit 0ce1a38

Please sign in to comment.