Skip to content

Brave 5.8

Compare
Choose a tag to compare
@codefromthecrypt codefromthecrypt released this 07 Oct 20:16
· 429 commits to master since this release

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.