Releases: openzipkin/zipkin-reporter-java
Zipkin Reporter 3.4
Zipkin Reporter 3.4 deprecates AsyncReporter/SpanHandler
queuedMaxBytes
and disables it by default.
When introduced, AsyncReporter
had three ways to trigger a queue flush:
queuedMaxSpans
- when the number of spans in the queue exceeds a thresholdqueuedMaxBytes
- when the size of the spans in the queue exceeds a thresholdmessageTimeout
- when a span has been in the queue longer than a threshold
queuedMaxBytes
was deprecated because requires time in the critical path, to calculate the size of a span to make sure it doesn't breach the threshold. This is problematic in tools that check for pinning, like Virtual Threads.
Thanks a lot to @reta for sorting this out!
Full Changelog: https://github.com/openzipkin/zipkin-reporter-java/compare/3.3.0..3.4.1
Zipkin Reporter 3.3
Zipkin Reporter 3.3 adds a BaseHttpSender
type, which eases http library integration. It also adds HttpEndpointSupplier
which supports dynamic endpoint discovery such as from Eureka, as well utilities to create constants or rate-limit suppliers. Finally, brave users get a native PROTO3 encoder through the new MutableSpanBytesEncoder
type.
These features were made in support of spring-boot, but available to any user with no new dependencies. For example, the PROTO encoder adds no library dependency, even if it increases the size of zipkin-reporter-brave by a couple dozen KB. A lion's share of thanks goes to @reta and @anuraaga who were on design and review duty for several days leading to this.
Here's an example of pulling most of these things together, integrating a sender with spring-cloud-loadbalancer (a client-side loadbalancer library).
This endpoint supplier will get the configuration endpoint value and look up the next target to use with the loadBalancerClient
. The rate limiter will ensure a gap of 30 seconds between queries. While below is hard-coded, it covers some routine advanced features formerly only available in spring-cloud-sleuth. Now, anyone can use them!
@Configuration(proxyBeanMethods = false)
public class ZipkinDiscoveryConfiguration {
@Bean HttpEndpointSupplier.Factory loadbalancerEndpoints(LoadBalancerClient loadBalancerClient) {
LoadBalancerHttpEndpointSupplier.Factory httpEndpointSupplierFactory =
new LoadBalancerHttpEndpointSupplier.Factory(loadBalancerClient);
// don't ask more than 30 seconds (just to show)
return HttpEndpointSuppliers.newRateLimitedFactory(httpEndpointSupplierFactory, 30);
}
record LoadBalancerHttpEndpointSupplier(LoadBalancerClient loadBalancerClient, URI virtualURL)
implements HttpEndpointSupplier {
record Factory(LoadBalancerClient loadBalancerClient) implements HttpEndpointSupplier.Factory {
@Override public HttpEndpointSupplier create(String endpoint) {
return new LoadBalancerHttpEndpointSupplier(loadBalancerClient, URI.create(endpoint));
}
}
@Override public String get() {
ServiceInstance instance = loadBalancerClient.choose(virtualURL.getHost());
if (instance != null) {
return instance.getUri() + virtualURL.getPath();
}
throw new IllegalArgumentException(virtualURL.getHost() + " is not registered");
}
@Override public void close() {
}
@Override public String toString() {
return "LoadBalancer{" + virtualURL + "}";
}
}
}
Full Changelog: https://github.com/openzipkin/zipkin-reporter-java/compare/3.2.1..3.3.0
Zipkin Reporter 3.2
Zipkin Reporter 3.2 deprecates Sender
for a simpler type BytesMessageSender
. This only supports synchronous invocation (as used by the async reporters in the reporting thread) and requires senders to pass an empty list vs a complicated and usually implemented check()
function. The result is being able to implement a custom sender in less than 50 lines including imports like below! Thank a lot to @anuraaga and @reta for the review on this.
package brave.example;
import com.linecorp.armeria.client.WebClient;
import com.linecorp.armeria.common.AggregatedHttpResponse;
import com.linecorp.armeria.common.HttpData;
import com.linecorp.armeria.common.HttpMethod;
import com.linecorp.armeria.common.HttpRequest;
import com.linecorp.armeria.common.MediaType;
import java.io.IOException;
import java.util.List;
import zipkin2.reporter.BytesMessageEncoder;
import zipkin2.reporter.BytesMessageSender;
import zipkin2.reporter.ClosedSenderException;
import zipkin2.reporter.Encoding;
final class WebClientSender extends BytesMessageSender.Base {
final WebClient zipkinApiV2SpansClient;
volatile boolean closeCalled; // volatile as not called from the reporting thread.
WebClientSender(WebClient zipkinApiV2SpansClient) {
super(Encoding.JSON);
this.zipkinApiV2SpansClient = zipkinApiV2SpansClient;
}
@Override public int messageMaxBytes() {
return 500_000; // Use the most common HTTP default
}
@Override public void send(List<byte[]> encodedSpans) throws IOException {
if (closeCalled) throw new ClosedSenderException();
byte[] body = BytesMessageEncoder.JSON.encode(encodedSpans);
HttpRequest request =
HttpRequest.of(HttpMethod.POST, "", MediaType.JSON, HttpData.wrap(body));
AggregatedHttpResponse response = zipkinApiV2SpansClient.blocking().execute(request);
try (HttpData content = response.content()) {
if (!response.status().isSuccess()) {
if (content.isEmpty()) {
throw new IOException("response failed: " + response);
}
throw new IOException("response failed: " + content.toStringAscii());
}
}
}
@Override public void close() {
closeCalled = true;
}
Full Changelog: https://github.com/openzipkin/zipkin-reporter-java/compare/3.1.1..3.2.1
Zipkin Reporter 3.1
Zipkin Reporter 3.1 adds custom encoding (non-JSON) support for zipkin-reporter-brave's AsyncZipkinSpanHandler
.
This was first used in encoder-stackdriver-brave) to allow traced apps to send spans to stackdriver without a zipkin core jar dependency
spanHandler = AsyncZipkinSpanHandler.newBuilder(sender).build(new StackdriverV2Encoder(Tags.ERROR));
Full Changelog: 3.0.1...3.1.1
Zipkin Reporter 3.0.1
Zipkin Reporter 3.0.1 fixes a problem where classpath scanners such as spring would trigger a zipkin2.Span
class load on AsyncZipkinSpanHandler
in zipkin-reporter-brave, which intentionally has no dependency on that.
Zipkin Reporter 3.0.0
Zipkin Reporter 3.0.0 makes the io.zipkin.zipkin2:zipkin dependency of io.zipkin.reporter2:zipkin-reporter-brave optional. This means those using the AsyncZipkinSpanHandler
will have no dependencies except any sender they configure. In particular, this allows those using Brave for things besides zipkin (e.g. wavefront) to avoid a dependency. Also, those sending spans zipkin have simpler dependency configuration and save a couple hundred KB, as well.
Those using types from the core io.zipkin.reporter2:zipkin-reporter artifact should depend on this directly, possibly using our bom to align deps. io.zipkin.reporter2:zipkin-reporter
still defaults to depend on io.zipkin.zipkin2:zipkin
, but it can be excluded if you know what you are doing.
Technically, some base classes to accommodate this, but they don't have affect on call sites except those implementing a custom Reporter
or Sender
. Due to these type changes, this is a major version change. However, must users will have a drop-in experience, except possibly dependency configuration changes.
Thanks a lot to @anuraaga and @reta who helped think through this!
Zipkin Reporter 2.17.2
Zipkin Reporter v2.17.2 fixes a bug where the jars that should be at Java 1.6 or 1.7 bytecode were not.
Full Changelog: https://github.com/openzipkin/zipkin-reporter-java/compare/2.17.0..2.17.2
Zipkin Reporter 2.17.0
Zipkin Reporter v2.17.0 updates default versions of dependencies so that CVE scanners like trivy pass by default. Details below for the interested.
For example, trivy is now clean.
$ trivy -q --skip-files "**/src/it/*/pom.xml" repo https://github.com/openzipkin/zipkin-reporter-java
In order to do this, and based on user demand, we had to change some default practice in our senders (the transport plug-in for sending spans to a zipkin compatible endpoint). Here is a summary of each and how versions are handled.
- activemq-client - Note that the recently released 6.x version is not compatible with 5.x due to package import change from javax.jms to jakarta.jms. Raise an issue if you need a later client as it will require a copy of the entire module to resolve.
- amqp-client (rabbitmq) - The 4.x version is no longer maintained, so we set a 5.x version and test the old one.
- kafka - the kafka-clients driver has not had any known compatibility problems, so we've left it as-is.
- libthrift (scribe) - libthrift (used for the deprecated scribe transport) has never released a 1.0 version, so occasionally causes revlocks. @zhfeng noticed this in apache camel, as updating past the 4 year old 0.13 was impossible to work around. Luckily versions after that seem compatible with each other.
- okhttp3 - The 3.x version is no longer maintained, so we set a 4.x version and test the old one. Thanks @evantorrie for explaining why this is important and @shakuzen for helping in the discussion.
While not end-user affecting, we have also migrated from JUnit 4 to JUnit 5, thanks to OpenRewrite recipes from @TeamModerne. Also, we use docker images to test all messaging transports. This ensures compatibility with upstream in transparent ways, and also removes classpath conflicts from java-based messaging transports such as ActiveMQ and Kafka.
Thanks a lot to @anuraaga for copious support work on this release, as well.
Full Changelog: 2.16.5...2.17.0
Note: To pass Trivy at the moment, we have to skip old versions used only for compatibility testing. There is a discussion about making this default.
Zipkin Reporter 2.16.5
Zipkin Reporter v2.16.5 updates dependencies and moves the build to work on current LTS JDKs (11, 17 and 21). Runtime Java versions remain the same. For example, the minimum Java version of the core jar remains 1.6.
Full Changelog: 2.16.4...2.16.5