Skip to content

Commit

Permalink
Adds gRPC endpoint /zipkin.proto3.SpanService/Report (openzipkin#2328)
Browse files Browse the repository at this point in the history
This adds an opt-in gRPC endpoint for reporting spans. A request to the
gRPC `/zipkin.proto3.SpanService/Report` service is the same proto used
with our `POST /api/v2/spans`, `Content-Type: application/x-protobuf`
endpoint: `zipkin.proto3.ListOfSpans`.

This is currently disabled by default, as the feature is experimental.
Enable it like so:
```bash
$ COLLECTOR_GRPC_ENABLED=true java -jar zipkin.jar
```

Under the scenes the runtime is the same as the POST endpoint (Armeria),
and uses the same port (9411).
  • Loading branch information
ewhauser authored and abesto committed Sep 10, 2019
1 parent 47d7d6b commit 8851e38
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 4 deletions.
2 changes: 1 addition & 1 deletion benchmarks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
<version>${wire.version}</version>
</dependency>
<dependency>
<groupId>io.zipkin.proto3</groupId>
<groupId>org.apache.zipkin.proto3</groupId>
<artifactId>zipkin-proto3</artifactId>
</dependency>
</dependencies>
Expand Down
25 changes: 23 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,26 @@
<url>https://github.com/openzipkin/zipkin/issues</url>
</issueManagement>

<repositories>
<repository>
<id>apache.snapshots.https</id>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
</repository>
</repositories>

<pluginRepositories>
<pluginRepository>
<id>apache.snapshots.https</id>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
</pluginRepositories>

<dependencyManagement>
<dependencies>
<dependency>
Expand Down Expand Up @@ -362,9 +382,9 @@
</dependency>

<dependency>
<groupId>io.zipkin.proto3</groupId>
<groupId>org.apache.zipkin.proto3</groupId>
<artifactId>zipkin-proto3</artifactId>
<version>0.1.0</version>
<version>0.2.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.squareup.wire</groupId>
Expand Down Expand Up @@ -627,6 +647,7 @@
<mapping>
<!-- Don't use javadoc style as this makes code formatters break it by adding tags! -->
<java>SLASHSTAR_STYLE</java>
<kt>SLASHSTAR_STYLE</kt>
</mapping>
<excludes>
<exclude>.travis.yml</exclude>
Expand Down
13 changes: 13 additions & 0 deletions zipkin-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,19 @@ Example usage:
$ RABBIT_ADDRESSES=localhost java -jar zipkin.jar
```

### gRPC Collector (Experimental)
You can enable a gRPC span collector endpoint by setting `COLLECTOR_GRPC_ENABLED=true`. The
`zipkin.proto3.SpanService/Report` endpoint will run on the same port as normal http (9411).


Example usage:

```bash
COLLECTOR_GRPC_ENABLED=true java -jar zipkin.jar
```

As this service is experimental, it is not recommended to run this in production environments.

### 128-bit trace IDs

Zipkin supports 64 and 128-bit trace identifiers, typically serialized
Expand Down
109 changes: 109 additions & 0 deletions zipkin-server/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@
<main.java.version>1.8</main.java.version>
<main.signature.artifact>java18</main.signature.artifact>
<start-class>zipkin.server.ZipkinServer</start-class>
<kotlin.version>1.3.30</kotlin.version>
<maven-invoker-plugin.version>3.2.0</maven-invoker-plugin.version>
<proto.generatedSourceDirectory>${project.build.directory}/generated-test-sources/wire</proto.generatedSourceDirectory>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -82,6 +84,10 @@
<groupId>com.linecorp.armeria</groupId>
<artifactId>armeria-zipkin</artifactId>
</dependency>
<dependency>
<groupId>com.linecorp.armeria</groupId>
<artifactId>armeria-grpc-protocol</artifactId>
</dependency>

<!-- zipkin requires exporting /health endpoint -->
<dependency>
Expand Down Expand Up @@ -125,6 +131,25 @@
<version>1.11.3</version>
</dependency>

<!-- to test the experimental grpc endpoint with the square/wire library -->
<dependency>
<groupId>org.apache.zipkin.proto3</groupId>
<artifactId>zipkin-proto3</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.squareup.wire</groupId>
<artifactId>wire-grpc-client</artifactId>
<version>${wire.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
<version>${kotlin.version}</version>
<scope>test</scope>
</dependency>

<!-- Cassandra and Cassandra 3 backends -->
<dependency>
<groupId>${project.groupId}.zipkin2</groupId>
Expand Down Expand Up @@ -348,6 +373,90 @@
</resource>
</resources>
<plugins>
<!-- wire-maven-plugin cannot get proto definitions from dependencies, so we will -->
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>com.squareup.wire</groupId>
<artifactId>wire-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-test-sources</phase>
<goals>
<goal>generate-sources</goal>
</goals>
<configuration>
<generatedSourceDirectory>${proto.generatedSourceDirectory}</generatedSourceDirectory>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<configuration>
<experimentalCoroutines>enable</experimentalCoroutines>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>none</phase>
</execution>
<execution>
<id>test-compile</id>
<goals>
<goal>test-compile</goal>
</goals>
<configuration>
<sourceDirs>
<sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/test/java</sourceDir>
<sourceDir>${proto.generatedSourceDirectory}</sourceDir>
</sourceDirs>
</configuration>
</execution>
</executions>
</plugin>
<!-- Adds the output directory from proto source generation for the test compiler -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-test-source</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>${proto.generatedSourceDirectory}</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<executions>
<!-- Defer test compilation to the kotlin plugin -->
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
<execution>
<id>java-test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
TracingConfiguration.class,
ZipkinQueryApiV2.class,
ZipkinHttpCollector.class,
ZipkinGrpcCollector.class,
ZipkinKafkaCollectorConfiguration.class,
ZipkinRabbitMQCollectorConfiguration.class,
MetricsHealthController.class,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 zipkin2.server.internal;

import com.linecorp.armeria.common.grpc.protocol.AbstractUnaryGrpcService;
import com.linecorp.armeria.spring.ArmeriaServerConfigurator;
import java.util.concurrent.CompletableFuture;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import zipkin2.Callback;
import zipkin2.codec.SpanBytesDecoder;
import zipkin2.collector.Collector;
import zipkin2.collector.CollectorMetrics;
import zipkin2.collector.CollectorSampler;
import zipkin2.storage.StorageComponent;

/** Collector for receiving spans on a gRPC endpoint. */
@ConditionalOnProperty(name = "zipkin.collector.grpc.enabled") // disabled by default
final class ZipkinGrpcCollector {
static final byte[] EMPTY = new byte[0];

@Bean ArmeriaServerConfigurator grpcCollectorConfigurator(StorageComponent storage,
CollectorSampler sampler, CollectorMetrics metrics) {
CollectorMetrics grpcMetrics = metrics.forTransport("grpc");
Collector collector = Collector.newBuilder(getClass())
.storage(storage)
.sampler(sampler)
.metrics(grpcMetrics)
.build();

return sb ->
sb.service("/zipkin.proto3.SpanService/Report", new SpanService(collector, grpcMetrics));
}

static final class SpanService extends AbstractUnaryGrpcService {

final Collector collector;
final CollectorMetrics metrics;

SpanService(Collector collector, CollectorMetrics metrics) {
this.collector = collector;
this.metrics = metrics;
}

@Override protected CompletableFuture<byte[]> handleMessage(byte[] bytes) {
metrics.incrementMessages();
CompletableFutureCallback result = new CompletableFutureCallback();
collector.acceptSpans(bytes, SpanBytesDecoder.PROTO3, result);
return result;
}
}

static final class CompletableFutureCallback extends CompletableFuture<byte[]>
implements Callback<Void> {

@Override public void onSuccess(Void value) {
complete(EMPTY);
}

@Override public void onError(Throwable t) {
completeExceptionally(t);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,10 @@ public void addViewControllers(ViewControllerRegistry registry) {
// could split the collector's CORS policy into a different property, still allowing POST
// with content-type by default.
.allowRequestMethods(HttpMethod.GET, HttpMethod.POST)
.allowRequestHeaders(HttpHeaderNames.CONTENT_TYPE);
.allowRequestHeaders(HttpHeaderNames.CONTENT_TYPE,
// Use literals to avoid a runtime dependency on armeria-grpc types
HttpHeaderNames.of("X-GRPC-WEB"))
.exposeHeaders("grpc-status", "grpc-message", "armeria.grpc.ThrowableProto-bin");
return builder -> builder.decorator(corsBuilder::build);
}

Expand Down
3 changes: 3 additions & 0 deletions zipkin-server/src/main/resources/zipkin-server-shared.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ zipkin:
http:
# Set to false to disable creation of spans via HTTP collector API
enabled: ${HTTP_COLLECTOR_ENABLED:true}
grpc:
# Set to true to enable the GRPC collector
enabled: ${COLLECTOR_GRPC_ENABLED:false}
kafka:
# Kafka bootstrap broker list, comma-separated host:port values. Setting this activates the
# Kafka 0.10+ collector.
Expand Down
Loading

0 comments on commit 8851e38

Please sign in to comment.