Skip to content

Commit

Permalink
brave: adds PROTO3 encoding (#252)
Browse files Browse the repository at this point in the history
This adds `MutableSpanEncoder.PROTO3` similar to what's available for
`zipkin2.Span`. The code and tests are based on similar inside zipkin
and brave. This is added to the reporter, not brave, to reduce version
lock-up for a useful, but more rare encoding type.

Fixes #178

Signed-off-by: Adrian Cole <[email protected]>
  • Loading branch information
codefromthecrypt authored Feb 13, 2024
1 parent bb3f5b7 commit be50820
Show file tree
Hide file tree
Showing 28 changed files with 2,317 additions and 161 deletions.
10 changes: 10 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -199,3 +199,13 @@
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.

This product contains a modified part of Guava, distributed by Google:

* License: Apache License v2.0
* Homepage: https:/google/guava

This product contains a modified part of Okio, distributed by Square:

* License: Apache License v2.0
* Homepage: https:/square/okio
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright 2016-2024 The OpenZipkin 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 zipkin2.reporter.brave;

import brave.handler.MutableSpan;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import zipkin2.reporter.BytesEncoder;

import static zipkin2.reporter.brave.MutableSpans.newBigClientSpan;
import static zipkin2.reporter.brave.MutableSpans.newServerSpan;

@Measurement(iterations = 5, time = 1)
@Warmup(iterations = 10, time = 1)
@Fork(3)
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@State(Scope.Thread)
@Threads(1)
public class MutableSpanBytesEncoderBenchmarks {

static final BytesEncoder<MutableSpan> jsonEncoder = MutableSpanBytesEncoder.JSON_V2;
static final BytesEncoder<MutableSpan> protoEncoder = MutableSpanBytesEncoder.PROTO3;
static final MutableSpan serverSpan = newServerSpan();
static final MutableSpan bigClientSpan = newBigClientSpan();

@Benchmark public int sizeInBytes_serverSpan_json() {
return jsonEncoder.sizeInBytes(serverSpan);
}

@Benchmark public int sizeInBytes_serverSpan_proto() {
return protoEncoder.sizeInBytes(serverSpan);
}

@Benchmark public byte[] encode_serverSpan_json() {
return jsonEncoder.encode(serverSpan);
}

@Benchmark public byte[] encode_serverSpan_proto() {
return protoEncoder.encode(serverSpan);
}

@Benchmark public int sizeInBytes_bigClientSpan_json() {
return jsonEncoder.sizeInBytes(bigClientSpan);
}

@Benchmark public int sizeInBytes_bigClientSpan_proto() {
return protoEncoder.sizeInBytes(bigClientSpan);
}

@Benchmark public byte[] encode_bigClientSpan_json() {
return jsonEncoder.encode(bigClientSpan);
}

@Benchmark public byte[] encode_bigClientSpan_proto() {
return protoEncoder.encode(bigClientSpan);
}

// Convenience main entry-point
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.addProfiler("gc")
.include(".*" + MutableSpanBytesEncoderBenchmarks.class.getSimpleName() + ".*")
.build();

new Runner(opt).run();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 The OpenZipkin Authors
* Copyright 2016-2024 The OpenZipkin 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
Expand All @@ -15,36 +15,9 @@

import brave.Span;
import brave.handler.MutableSpan;
import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.annotations.Warmup;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

@Measurement(iterations = 5, time = 1)
@Warmup(iterations = 10, time = 1)
@Fork(3)
@BenchmarkMode(Mode.SampleTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
@State(Scope.Thread)
@Threads(1)
public class MutableSpanBenchmarks {

@Benchmark public MutableSpan makeServerSpan() {
return newServerSpan();
}

public static MutableSpan newServerSpan() {
class MutableSpans {
static MutableSpan newServerSpan() {
MutableSpan span = new MutableSpan();
span.name("get /");
span.kind(Span.Kind.SERVER);
Expand All @@ -58,11 +31,7 @@ public static MutableSpan newServerSpan() {
return span;
}

@Benchmark public MutableSpan makeBigClientSpan() {
return newBigClientSpan();
}

public static MutableSpan newBigClientSpan() {
static MutableSpan newBigClientSpan() {
MutableSpan span = new MutableSpan();
span.name("getuserinfobyaccesstoken");
span.kind(Span.Kind.CLIENT);
Expand All @@ -77,19 +46,11 @@ public static MutableSpan newBigClientSpan() {
span.tag("http.path", "/thrift/shopForTalk");
span.tag("http.status_code", "200");
span.tag("http.url", "tbinary+h2c://abasdasgad.hsadas.ism/thrift/shopForTalk");
span.tag("error", "true");
span.tag("instanceId", "line-wallet-api");
span.tag("phase", "beta");
span.tag("siteId", "shop");
span.error(new RuntimeException("ice cream"));
return span;
}

// Convenience main entry-point
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.addProfiler("gc")
.include(".*" + MutableSpanBenchmarks.class.getSimpleName() + ".*")
.build();

new Runner(opt).run();
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2016-2020 The OpenZipkin Authors
* Copyright 2016-2024 The OpenZipkin 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
Expand Down Expand Up @@ -33,8 +33,8 @@
import org.openjdk.jmh.runner.options.OptionsBuilder;
import zipkin2.reporter.Reporter;

import static zipkin2.reporter.brave.MutableSpanBenchmarks.newBigClientSpan;
import static zipkin2.reporter.brave.MutableSpanBenchmarks.newServerSpan;
import static zipkin2.reporter.brave.MutableSpans.newBigClientSpan;
import static zipkin2.reporter.brave.MutableSpans.newServerSpan;

@Measurement(iterations = 5, time = 1)
@Warmup(iterations = 10, time = 1)
Expand All @@ -45,7 +45,7 @@
@Threads(1)
public class ZipkinSpanHandlerBenchmarks {
final SpanHandler handler =
ZipkinSpanHandler.newBuilder(Reporter.NOOP).alwaysReportSpans(true).build();
ZipkinSpanHandler.newBuilder(Reporter.NOOP).alwaysReportSpans(true).build();
final TraceContext context = TraceContext.newBuilder().traceId(1).spanId(2).sampled(true).build();
final MutableSpan serverSpan = newServerSpan();
final MutableSpan bigClientSpan = newBigClientSpan();
Expand All @@ -61,9 +61,9 @@ public class ZipkinSpanHandlerBenchmarks {
// Convenience main entry-point
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.addProfiler("gc")
.include(".*" + ZipkinSpanHandlerBenchmarks.class.getSimpleName() + ".*")
.build();
.addProfiler("gc")
.include(".*" + ZipkinSpanHandlerBenchmarks.class.getSimpleName() + ".*")
.build();

new Runner(opt).run();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ public enum MutableSpanBytesEncoder implements BytesEncoder<MutableSpan> {
@Override public byte[] encode(MutableSpan input) {
return JsonV2Encoder.INSTANCE.encode(input);
}
},
PROTO3 {
@Override public Encoding encoding() {
return Encoding.PROTO3;
}

@Override public int sizeInBytes(MutableSpan input) {
return ZipkinProto3Encoder.INSTANCE.sizeInBytes(input);
}

@Override public byte[] encode(MutableSpan input) {
return ZipkinProto3Encoder.INSTANCE.encode(input);
}
};

/**
Expand All @@ -48,7 +61,7 @@ public static BytesEncoder<MutableSpan> forEncoding(Encoding encoding) {
case JSON:
return JSON_V2;
case PROTO3:
throw new UnsupportedOperationException("PROTO3 is not yet a built-in encoder");
return PROTO3;
case THRIFT:
throw new UnsupportedOperationException("THRIFT is not yet a built-in encoder");
default: // BUG: as encoding is an enum!
Expand All @@ -70,7 +83,7 @@ public static BytesEncoder<MutableSpan> create(Encoding encoding, Tag<Throwable>
case JSON:
return new JsonV2Encoder(errorTag);
case PROTO3:
throw new UnsupportedOperationException("PROTO3 is not yet a built-in encoder");
return new ZipkinProto3Encoder(errorTag);
case THRIFT:
throw new UnsupportedOperationException("THRIFT is not yet a built-in encoder");
default: // BUG: as encoding is an enum!
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2016-2024 The OpenZipkin 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 zipkin2.reporter.brave;

import brave.Tag;
import brave.Tags;
import brave.handler.MutableSpan;
import zipkin2.reporter.BytesEncoder;
import zipkin2.reporter.Encoding;
import zipkin2.reporter.brave.internal.ZipkinProto3Writer;

final class ZipkinProto3Encoder implements BytesEncoder<MutableSpan> {
static final BytesEncoder<MutableSpan> INSTANCE = new ZipkinProto3Encoder(Tags.ERROR);
final ZipkinProto3Writer delegate;

ZipkinProto3Encoder(Tag<Throwable> errorTag) {
if (errorTag == null) throw new NullPointerException("errorTag == null");
this.delegate = new ZipkinProto3Writer(errorTag);
}

@Override public Encoding encoding() {
return Encoding.PROTO3;
}

@Override public int sizeInBytes(MutableSpan span) {
return delegate.sizeInBytes(span);
}

@Override public byte[] encode(MutableSpan span) {
return delegate.write(span);
}
}
Loading

0 comments on commit be50820

Please sign in to comment.