Skip to content

Commit

Permalink
Migrates to Brave 6 and Zipkin Reporter 3
Browse files Browse the repository at this point in the history
Signed-off-by: Adrian Cole <adrian@tetrate.io>
  • Loading branch information
Adrian Cole committed Feb 10, 2024
1 parent 09a6ae5 commit 81b4084
Show file tree
Hide file tree
Showing 13 changed files with 126 additions and 294 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
import brave.propagation.CurrentTraceContext.ScopeDecorator;
import brave.propagation.Propagation;
import brave.propagation.Propagation.Factory;
import brave.propagation.Propagation.KeyFactory;
import io.micrometer.tracing.brave.bridge.BraveBaggageManager;

import org.springframework.beans.factory.ObjectProvider;
Expand Down Expand Up @@ -99,12 +98,11 @@ BaggagePropagation.FactoryBuilder propagationFactoryBuilder(
return builder;
}

@SuppressWarnings("deprecation")
private Factory createThrowAwayFactory() {
return new Factory() {

@Override
public <K> Propagation<K> create(KeyFactory<K> keyFactory) {
public Propagation<String> get() {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import java.util.function.Predicate;
import java.util.stream.Stream;

import brave.internal.propagation.StringPropagationAdapter;
import brave.propagation.B3Propagation;
import brave.propagation.Propagation;
import brave.propagation.Propagation.Factory;
Expand Down Expand Up @@ -71,9 +70,8 @@ public boolean requires128BitTraceId() {
}

@Override
@SuppressWarnings("deprecation")
public <K> Propagation<K> create(Propagation.KeyFactory<K> keyFactory) {
return StringPropagationAdapter.create(this.propagation, keyFactory);
public Propagation<String> get() {
return this.propagation;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,37 @@

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.util.Collections;
import java.util.List;
import java.util.zip.GZIPOutputStream;

import zipkin2.Call;
import zipkin2.CheckResult;
import zipkin2.codec.Encoding;
import zipkin2.reporter.BytesMessageEncoder;
import zipkin2.reporter.ClosedSenderException;
import zipkin2.reporter.Sender;
import zipkin2.reporter.BytesMessageSender;
import zipkin2.reporter.Encoding;

import org.springframework.http.HttpHeaders;
import org.springframework.util.unit.DataSize;

/**
* A Zipkin {@link Sender} that uses an HTTP client to send JSON spans. Supports automatic
* A Zipkin {@link BytesMessageSender} that uses an HTTP client to send JSON spans. Supports automatic
* compression with gzip.
*
* @author Moritz Halbritter
* @author Stefan Bratanov
*/
abstract class HttpSender extends Sender {
abstract class HttpSender extends BytesMessageSender.Base {

private static final DataSize MESSAGE_MAX_SIZE = DataSize.ofKilobytes(512);

/**
* Only use gzip compression on data which is bigger than this in bytes.
*/
private static final DataSize COMPRESSION_THRESHOLD = DataSize.ofKilobytes(1);

private volatile boolean closed;

@Override
public Encoding encoding() {
return Encoding.JSON;
HttpSender() {
super(Encoding.JSON);
}

@Override
Expand All @@ -57,96 +57,49 @@ public int messageMaxBytes() {
}

@Override
public int messageSizeInBytes(List<byte[]> encodedSpans) {
return encoding().listSizeInBytes(encodedSpans);
}

@Override
public int messageSizeInBytes(int encodedSizeInBytes) {
return encoding().listSizeInBytes(encodedSizeInBytes);
}

@Override
public CheckResult check() {
try {
sendSpans(Collections.emptyList()).execute();
return CheckResult.OK;
}
catch (IOException | RuntimeException ex) {
return CheckResult.failed(ex);
}
}

@Override
public void close() throws IOException {
public void close() {
this.closed = true;
}

/**
* The returned {@link HttpPostCall} will send span(s) as a POST to a zipkin endpoint
* when executed.
* @param batchedEncodedSpans list of encoded spans as a byte array
* @return an instance of a Zipkin {@link Call} which can be executed
* This will send span(s) as a POST to a zipkin endpoint. For example,
* http://localhost:9411/api/v2/spans.
*
* @param headers headers for the POST request
* @param body list of possibly gzipped, encoded spans.
*/
protected abstract HttpPostCall sendSpans(byte[] batchedEncodedSpans);
abstract void postSpans(HttpHeaders headers, byte[] body);

@Override
public Call<Void> sendSpans(List<byte[]> encodedSpans) {
public void send(List<byte[]> encodedSpans) throws IOException {
if (this.closed) {
throw new ClosedSenderException();
}
return sendSpans(BytesMessageEncoder.JSON.encode(encodedSpans));
}

abstract static class HttpPostCall extends Call.Base<Void> {

/**
* Only use gzip compression on data which is bigger than this in bytes.
*/
private static final DataSize COMPRESSION_THRESHOLD = DataSize.ofKilobytes(1);

private final byte[] body;

HttpPostCall(byte[] body) {
this.body = body;
}

protected byte[] getBody() {
if (needsCompression()) {
return compress(this.body);
}
return this.body;
}

protected byte[] getUncompressedBody() {
return this.body;
byte[] body = BytesMessageEncoder.JSON.encode(encodedSpans);
HttpHeaders headers = getDefaultHeaders();
if (needsCompression(body)) {
body = compress(body);
headers.set("Content-Encoding", "gzip");
}
postSpans(headers, body);
}

protected HttpHeaders getDefaultHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.set("b3", "0");
headers.set("Content-Type", "application/json");
if (needsCompression()) {
headers.set("Content-Encoding", "gzip");
}
return headers;
}
HttpHeaders getDefaultHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.set("b3", "0");
headers.set("Content-Type", "application/json");
return headers;
}

private boolean needsCompression() {
return this.body.length > COMPRESSION_THRESHOLD.toBytes();
}
private boolean needsCompression(byte[] body) {
return body.length > COMPRESSION_THRESHOLD.toBytes();
}

private byte[] compress(byte[] input) {
ByteArrayOutputStream result = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(result)) {
gzip.write(input);
}
catch (IOException ex) {
throw new UncheckedIOException(ex);
}
return result.toByteArray();
private byte[] compress(byte[] input) throws IOException {
ByteArrayOutputStream result = new ByteArrayOutputStream();
try (GZIPOutputStream gzip = new GZIPOutputStream(result)) {
gzip.write(input);
}

return result.toByteArray();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,10 @@

package org.springframework.boot.actuate.autoconfigure.tracing.zipkin;

import zipkin2.Span;
import zipkin2.codec.BytesEncoder;
import zipkin2.codec.SpanBytesEncoder;
import zipkin2.reporter.Sender;
import zipkin2.reporter.BytesMessageSender;

import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.BraveConfiguration;
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.OpenTelemetryConfiguration;
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.ReporterConfiguration;
import org.springframework.boot.actuate.autoconfigure.tracing.zipkin.ZipkinConfigurations.SenderConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
Expand All @@ -44,9 +40,8 @@
* @since 3.0.0
*/
@AutoConfiguration(after = RestTemplateAutoConfiguration.class)
@ConditionalOnClass(Sender.class)
@Import({ SenderConfiguration.class, ReporterConfiguration.class, BraveConfiguration.class,
OpenTelemetryConfiguration.class })
@ConditionalOnClass(BytesMessageSender.class)
@Import({ SenderConfiguration.class, BraveConfiguration.class, OpenTelemetryConfiguration.class })
@EnableConfigurationProperties(ZipkinProperties.class)
public class ZipkinAutoConfiguration {

Expand All @@ -56,10 +51,4 @@ PropertiesZipkinConnectionDetails zipkinConnectionDetails(ZipkinProperties prope
return new PropertiesZipkinConnectionDetails(properties);
}

@Bean
@ConditionalOnMissingBean
public BytesEncoder<Span> spanBytesEncoder() {
return SpanBytesEncoder.JSON_V2;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@

package org.springframework.boot.actuate.autoconfigure.tracing.zipkin;

import java.util.Optional;

import brave.handler.MutableSpan;
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder;
import zipkin2.Span;
import zipkin2.codec.BytesEncoder;
import zipkin2.reporter.AsyncReporter;
import zipkin2.reporter.Reporter;
import zipkin2.reporter.Sender;
import zipkin2.reporter.brave.ZipkinSpanHandler;
import zipkin2.reporter.BytesEncoder;
import zipkin2.reporter.BytesMessageSender;
import zipkin2.reporter.brave.AsyncZipkinSpanHandler;
import zipkin2.reporter.brave.AsyncZipkinSpanHandler.Builder;
import zipkin2.reporter.urlconnection.URLConnectionSender;

import org.springframework.beans.factory.ObjectProvider;
Expand Down Expand Up @@ -59,7 +62,7 @@ static class SenderConfiguration {
static class UrlConnectionSenderConfiguration {

@Bean
@ConditionalOnMissingBean(Sender.class)
@ConditionalOnMissingBean(BytesMessageSender.class)
URLConnectionSender urlConnectionSender(ZipkinProperties properties,
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider) {
ZipkinConnectionDetails connectionDetails = connectionDetailsProvider
Expand All @@ -79,7 +82,7 @@ URLConnectionSender urlConnectionSender(ZipkinProperties properties,
static class RestTemplateSenderConfiguration {

@Bean
@ConditionalOnMissingBean(Sender.class)
@ConditionalOnMissingBean(BytesMessageSender.class)
ZipkinRestTemplateSender restTemplateSender(ZipkinProperties properties,
ObjectProvider<ZipkinRestTemplateBuilderCustomizer> customizers,
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider) {
Expand Down Expand Up @@ -111,7 +114,7 @@ private RestTemplateBuilder applyCustomizers(RestTemplateBuilder restTemplateBui
static class WebClientSenderConfiguration {

@Bean
@ConditionalOnMissingBean(Sender.class)
@ConditionalOnMissingBean(BytesMessageSender.class)
ZipkinWebClientSender webClientSender(ZipkinProperties properties,
ObjectProvider<ZipkinWebClientBuilderCustomizer> customizers,
ObjectProvider<ZipkinConnectionDetails> connectionDetailsProvider) {
Expand All @@ -126,29 +129,16 @@ ZipkinWebClientSender webClientSender(ZipkinProperties properties,
}

@Configuration(proxyBeanMethods = false)
static class ReporterConfiguration {

@Bean
@ConditionalOnMissingBean(Reporter.class)
@ConditionalOnBean(Sender.class)
AsyncReporter<Span> spanReporter(Sender sender, BytesEncoder<Span> encoder) {
return AsyncReporter.builder(sender).build(encoder);
}

}

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ZipkinSpanHandler.class)
@ConditionalOnClass(AsyncZipkinSpanHandler.class)
static class BraveConfiguration {

@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(Reporter.class)
@ConditionalOnEnabledTracing
ZipkinSpanHandler zipkinSpanHandler(Reporter<Span> spanReporter) {
return (ZipkinSpanHandler) ZipkinSpanHandler.newBuilder(spanReporter).build();
@ConditionalOnBean(BytesMessageSender.class)
AsyncZipkinSpanHandler spanReporter(BytesMessageSender sender, Optional<BytesEncoder<MutableSpan>> encoder) {
Builder builder = AsyncZipkinSpanHandler.newBuilder(sender);
return encoder.map(builder::build).orElseGet(builder::build);
}

}

@Configuration(proxyBeanMethods = false)
Expand All @@ -157,10 +147,12 @@ static class OpenTelemetryConfiguration {

@Bean
@ConditionalOnMissingBean
@ConditionalOnBean(Sender.class)
@ConditionalOnBean(BytesMessageSender.class)
@ConditionalOnEnabledTracing
ZipkinSpanExporter zipkinSpanExporter(BytesEncoder<Span> encoder, Sender sender) {
return ZipkinSpanExporter.builder().setEncoder(encoder).setSender(sender).build();
ZipkinSpanExporter zipkinSpanExporter(BytesMessageSender sender, Optional<BytesEncoder<Span>> encoder) {
ZipkinSpanExporterBuilder builder = ZipkinSpanExporter.builder().setSender(sender);
encoder.ifPresent(builder::setEncoder);
return builder.build();
}

}
Expand Down
Loading

0 comments on commit 81b4084

Please sign in to comment.