Brave 5.8
Brave 5.8 significantly improves sampling infrastructure and begins an Rpc abstraction
Functional sampling with SamplerFunction
Over time, we've accumulated a number of sampling tools. For example, we have DeclarativeSampler
, which can be used to process Java annotations, and HttpRuleSampler
for path and method rules. We've consolidated all parameterized samplers under a functional interface: SamplerFunction
, which allows better re-use as we journey into more models such as RPC and Messaging.
Here's an example using functional expressions to declare "/health" should never be sampled, while we want POST /api
requests limited to 100 traces per second:
import static brave.http.HttpRequestMatchers.*;
import static brave.sampler.Matchers.and;
httpTracing = httpTracingBuilder.serverSampler(HttpRuleSampler.newBuilder()
.putRule(pathStartsWith("/health"), Sampler.NEVER_SAMPLE)
.putRule(and(methodEquals("POST"), pathStartsWith("/api")), RateLimitingSampler.create(100))
.build()).build();
As a side effect, we've deprecated Tracer.withSampler
in favor of lighter methods that accomplish the same:
Tracer.startScopedSpan(name, sampler, param)
Tracer.nextSpan(sampler, param)
New RPC abstraction
In Brave's main repository, we have two different RPC libraries: Dubbo and gRPC. We've started an RPC abstraction with sampling.
For example, here's a sampler that traces 100 "GetUserToken" requests per second. This doesn't start new traces for requests to the health check service. Other requests will use a global rate provided by the tracing component.
import static brave.rpc.RpcRequestMatchers.*;
rpcTracing = rpcTracingBuilder.serverSampler(RpcRuleSampler.newBuilder()
.putRule(serviceEquals("grpc.health.v1.Health"), Sampler.NEVER_SAMPLE)
.putRule(methodEquals("GetUserToken"), RateLimitingSampler.create(100))
.build()).build();
While the conventions above are gRPC centric, the code is 100% portable. In other words, Dubbo tracing uses exactly the same RpcTracing
component and rules can be mixed in the same way as they can with our HttpTracing
component.
Thanks very much to @trustin @anuraaga and @jeqo for design and code review.
Tracing.Builder.alwaysReportSpans()
Most users will want to use defaults, when deciding where to report trace data. Some advanced sites will have a trace forwarder, a proxy that sends data to one or more places. One open source example is https://github.com/HotelsDotCom/pitchfork. In cases like this, one proxy may want all data, regardless of if it is B3 sampled or not. This change introduces Tracing.Builder.alwaysReportSpans()
, primarily in support of the secondary sampling project.