From 7ea2da3d0b16c861aa648ecdbd3ba9a799ab8d75 Mon Sep 17 00:00:00 2001 From: Sergei Malafeev Date: Wed, 20 May 2020 06:58:41 +0800 Subject: [PATCH] Add Zipkin exporter support (#411) * #375 Add Zipkin exporter support Signed-off-by: Sergei Malafeev * #375 use OkHttpSender for Zipkin exporter Signed-off-by: Sergei Malafeev * #375 add Zipkin exporter to README Signed-off-by: Sergei Malafeev Co-authored-by: Trask Stalnaker --- .circleci/config.yml | 2 +- README.md | 8 ++++ auto-exporters/auto-exporters.gradle | 3 ++ .../ExporterAdaptersTest.groovy | 6 ++- .../zipkin/ZipkinExporterFactory.java | 42 +++++++++++++++++++ ...dk.contrib.auto.config.SpanExporterFactory | 1 + auto-exporters/zipkin/zipkin.gradle | 17 ++++++++ gradle/dependencies.gradle | 1 + settings.gradle | 2 + 9 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 auto-exporters/zipkin/src/main/java/io/opentelemetry/auto/exporters/zipkin/ZipkinExporterFactory.java create mode 100644 auto-exporters/zipkin/src/main/resources/META-INF/services/io.opentelemetry.sdk.contrib.auto.config.SpanExporterFactory create mode 100644 auto-exporters/zipkin/zipkin.gradle diff --git a/.circleci/config.yml b/.circleci/config.yml index d47b11370a6a..b5bd8de97757 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -27,7 +27,7 @@ jobs: - run: name: Build Project - command: GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx1G -Xms64M' -Dota.forkedMaxHeapSize=1G -Dota.forkedMinHeapSize=64M" ./gradlew clean compileTestGroovy compileLatestDepTestGroovy compileTestScala compileLatestDepTestScala compileTestJava compileLatestDepTestJava :opentelemetry-auto:shadowJar :auto-exporters:opentelemetry-auto-exporters-jaeger:shadowJar :auto-exporters:opentelemetry-auto-exporters-otlp:shadowJar :auto-exporters:opentelemetry-auto-exporters-logging:shadowJar --build-cache --parallel --stacktrace --no-daemon --max-workers=8 + command: GRADLE_OPTS="-Dorg.gradle.jvmargs='-Xmx1G -Xms64M' -Dota.forkedMaxHeapSize=1G -Dota.forkedMinHeapSize=64M" ./gradlew clean compileTestGroovy compileLatestDepTestGroovy compileTestScala compileLatestDepTestScala compileTestJava compileLatestDepTestJava :opentelemetry-auto:shadowJar :auto-exporters:opentelemetry-auto-exporters-jaeger:shadowJar :auto-exporters:opentelemetry-auto-exporters-otlp:shadowJar :auto-exporters:opentelemetry-auto-exporters-logging:shadowJar :auto-exporters:opentelemetry-auto-exporters-zipkin:shadowJar --build-cache --parallel --stacktrace --no-daemon --max-workers=8 - run: name: Collect Libs diff --git a/README.md b/README.md index a86300bcf77a..4381e0d6fea0 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,14 @@ only supports gRPC as its communications protocol. | ota.exporter.jaeger.endpoint | OTA_EXPORTER_JAEGER_ENDPOINT | The Jaeger endpoint to connect to. Currently only gRPC is supported. | | ota.exporter.jaeger.service.name | OTA_EXPORTER_JAEGER_SERVICE_NAME | The service name of this JVM instance | +#### Zipkin exporter +A simple wrapper for the Zipkin exporter of opentelemetry-java. It POSTs json in [Zipkin format](https://zipkin.io/zipkin-api/#/default/post_spans) to a specified HTTP URL. + +| System property | Environment variable | Purpose | +|----------------------------------|----------------------------------|----------------------------------------------------------------------| +| ota.exporter.zipkin.endpoint | OTA_EXPORTER_ZIPKIN_ENDPOINT | The Zipkin endpoint to connect to. Currently only HTTP is supported. | +| ota.exporter.zipkin.service.name | OTA_EXPORTER_ZIPKIN_SERVICE_NAME | The service name of this JVM instance + #### OTLP exporter A simple wrapper for the OTLP exporter of opentelemetry-java. diff --git a/auto-exporters/auto-exporters.gradle b/auto-exporters/auto-exporters.gradle index e633f0dc7a9b..00e605e413a1 100644 --- a/auto-exporters/auto-exporters.gradle +++ b/auto-exporters/auto-exporters.gradle @@ -6,17 +6,20 @@ dependencies { testCompile project(':auto-exporters:opentelemetry-auto-exporters-otlp') testCompile project(':auto-exporters:opentelemetry-auto-exporters-jaeger') testCompile project(':auto-exporters:opentelemetry-auto-exporters-logging') + testCompile project(':auto-exporters:opentelemetry-auto-exporters-zipkin') } tasks.withType(Test).configureEach() { dependsOn ':auto-exporters:opentelemetry-auto-exporters-otlp:shadowJar' dependsOn ':auto-exporters:opentelemetry-auto-exporters-jaeger:shadowJar' dependsOn ':auto-exporters:opentelemetry-auto-exporters-logging:shadowJar' + dependsOn ':auto-exporters:opentelemetry-auto-exporters-zipkin:shadowJar' doFirst { systemProperty 'projectVersion', allprojects.version[0] systemProperty 'adapterRoot', "${rootDir}/auto-exporters" systemProperty 'otlpExporterJar', project(':auto-exporters:opentelemetry-auto-exporters-otlp').tasks.shadowJar.archivePath systemProperty 'jaegerExporterJar', project(':auto-exporters:opentelemetry-auto-exporters-jaeger').tasks.shadowJar.archivePath systemProperty 'loggingExporterJar', project(':auto-exporters:opentelemetry-auto-exporters-logging').tasks.shadowJar.archivePath + systemProperty 'zipkinExporterJar', project(':auto-exporters:opentelemetry-auto-exporters-zipkin').tasks.shadowJar.archivePath } } diff --git a/auto-exporters/src/test/groovy/io/opentelemetry/auto/exporteradapters/ExporterAdaptersTest.groovy b/auto-exporters/src/test/groovy/io/opentelemetry/auto/exporteradapters/ExporterAdaptersTest.groovy index 552fc540742a..66356210d01d 100644 --- a/auto-exporters/src/test/groovy/io/opentelemetry/auto/exporteradapters/ExporterAdaptersTest.groovy +++ b/auto-exporters/src/test/groovy/io/opentelemetry/auto/exporteradapters/ExporterAdaptersTest.groovy @@ -34,6 +34,9 @@ class ExporterAdaptersTest extends Specification { @Shared def loggingExporterJar = System.getProperty("loggingExporterJar") + @Shared + def zipkinExporterJar = System.getProperty("zipkinExporterJar") + @Shared def jaegerDir = new File("${adapterRoot}/jaeger-adapter/build/libs") @@ -45,7 +48,7 @@ class ExporterAdaptersTest extends Specification { file != null where: - exporter << [otlpExporterJar, jaegerExporterJar, loggingExporterJar] + exporter << [otlpExporterJar, jaegerExporterJar, loggingExporterJar, zipkinExporterJar] } def "test exporter load"() { @@ -70,5 +73,6 @@ class ExporterAdaptersTest extends Specification { otlpExporterJar | 'io.opentelemetry.auto.exporters.otlp.OtlpSpanExporterFactory' jaegerExporterJar | 'io.opentelemetry.auto.exporters.jaeger.JaegerExporterFactory' loggingExporterJar | 'io.opentelemetry.auto.exporters.logging.LoggingExporterFactory' + zipkinExporterJar | 'io.opentelemetry.auto.exporters.zipkin.ZipkinExporterFactory' } } diff --git a/auto-exporters/zipkin/src/main/java/io/opentelemetry/auto/exporters/zipkin/ZipkinExporterFactory.java b/auto-exporters/zipkin/src/main/java/io/opentelemetry/auto/exporters/zipkin/ZipkinExporterFactory.java new file mode 100644 index 000000000000..785cd345c7cd --- /dev/null +++ b/auto-exporters/zipkin/src/main/java/io/opentelemetry/auto/exporters/zipkin/ZipkinExporterFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright The 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.auto.exporters.zipkin; + +import io.opentelemetry.exporters.zipkin.ZipkinExporterConfiguration; +import io.opentelemetry.exporters.zipkin.ZipkinSpanExporter; +import io.opentelemetry.sdk.contrib.auto.config.Config; +import io.opentelemetry.sdk.contrib.auto.config.SpanExporterFactory; +import io.opentelemetry.sdk.trace.export.SpanExporter; +import zipkin2.reporter.okhttp3.OkHttpSender; + +public class ZipkinExporterFactory implements SpanExporterFactory { + private static final String ZIPKIN_ENDPOINT = "zipkin.endpoint"; + private static final String DEFAULT_ZIPKIN_ENDPOINT = "http://localhost:9411/api/v2/spans"; + + private static final String ZIPKIN_SERVICE_NAME = "zipkin.service.name"; + private static final String DEFAULT_ZIPKIN_SERVICE_NAME = "(unknown service)"; + + @Override + public SpanExporter fromConfig(Config config) { + final String zipkinEndpoint = config.getString(ZIPKIN_ENDPOINT, DEFAULT_ZIPKIN_ENDPOINT); + final String serviceName = config.getString(ZIPKIN_SERVICE_NAME, DEFAULT_ZIPKIN_SERVICE_NAME); + return ZipkinSpanExporter.create( + ZipkinExporterConfiguration.builder() + .setSender(OkHttpSender.create(zipkinEndpoint)) + .setServiceName(serviceName) + .build()); + } +} diff --git a/auto-exporters/zipkin/src/main/resources/META-INF/services/io.opentelemetry.sdk.contrib.auto.config.SpanExporterFactory b/auto-exporters/zipkin/src/main/resources/META-INF/services/io.opentelemetry.sdk.contrib.auto.config.SpanExporterFactory new file mode 100644 index 000000000000..975a26a2da95 --- /dev/null +++ b/auto-exporters/zipkin/src/main/resources/META-INF/services/io.opentelemetry.sdk.contrib.auto.config.SpanExporterFactory @@ -0,0 +1 @@ +io.opentelemetry.auto.exporters.zipkin.ZipkinExporterFactory diff --git a/auto-exporters/zipkin/zipkin.gradle b/auto-exporters/zipkin/zipkin.gradle new file mode 100644 index 000000000000..c3ccbec1777f --- /dev/null +++ b/auto-exporters/zipkin/zipkin.gradle @@ -0,0 +1,17 @@ +plugins { + id "com.github.johnrengelman.shadow" +} + +apply from: "${rootDir}/gradle/java.gradle" + +dependencies { + compile(deps.opentelemetryZipkin) { + exclude group: 'io.opentelemetry', module: 'opentelemetry-sdk' + } + compileOnly deps.opentelemetrySdkAutoConfig + compile group: 'io.zipkin.reporter2', name: 'zipkin-sender-okhttp3', version: '2.12.2' +} + +shadowJar { + archiveClassifier = '' +} diff --git a/gradle/dependencies.gradle b/gradle/dependencies.gradle index 458309e6789e..82240dd30fac 100644 --- a/gradle/dependencies.gradle +++ b/gradle/dependencies.gradle @@ -33,6 +33,7 @@ ext { opentelemetrySdkAutoConfig : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-sdk-contrib-auto-config', version: versions.opentelemetry), opentelemetryJaeger : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-exporters-jaeger', version: versions.opentelemetry), opentelemetryOtlp : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-exporters-otlp', version: versions.opentelemetry), + opentelemetryZipkin : dependencies.create(group: 'io.opentelemetry', name: 'opentelemetry-exporters-zipkin', version: versions.opentelemetry), // General slf4j : "org.slf4j:slf4j-api:${versions.slf4j}", diff --git a/settings.gradle b/settings.gradle index 436d84641925..da890be76290 100644 --- a/settings.gradle +++ b/settings.gradle @@ -152,6 +152,7 @@ include ":auto-exporters" include ":auto-exporters:jaeger" include ":auto-exporters:logging" include ":auto-exporters:otlp" +include ":auto-exporters:zipkin" // benchmark include ':benchmark' @@ -174,3 +175,4 @@ project(':java-agent').name = 'opentelemetry-auto' project(':auto-exporters:jaeger').name = 'opentelemetry-auto-exporters-jaeger' project(':auto-exporters:logging').name = 'opentelemetry-auto-exporters-logging' project(':auto-exporters:otlp').name = 'opentelemetry-auto-exporters-otlp' +project(':auto-exporters:zipkin').name = 'opentelemetry-auto-exporters-zipkin'