brave.internal.Platform Java Examples

The following examples show how to use brave.internal.Platform. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RpcHandler.java    From brave with Apache License 2.0 6 votes vote down vote up
void handleFinish(Resp response, Span span) {
  if (response == null) throw new NullPointerException("response == null");
  if (span.isNoop()) return;

  if (response.error() != null) {
    span.error(response.error()); // Ensures MutableSpan.error() for SpanHandler
  }

  try {
    parseResponse(response, span);
  } catch (Throwable t) {
    propagateIfFatal(t);
    Platform.get().log("error parsing response {0}", response, t);
  } finally {
    long finishTimestamp = response.finishTimestamp();
    if (finishTimestamp == 0L) {
      span.finish();
    } else {
      span.finish(finishTimestamp);
    }
  }
}
 
Example #2
Source File: RpcHandler.java    From brave with Apache License 2.0 6 votes vote down vote up
Span handleStart(Req request, Span span) {
  if (span.isNoop()) return span;

  try {
    parseRequest(request, span);
  } catch (Throwable t) {
    propagateIfFatal(t);
    Platform.get().log("error parsing request {0}", request, t);
  } finally {
    // all of the above parsing happened before a timestamp on the span
    long timestamp = request.startTimestamp();
    if (timestamp == 0L) {
      span.start();
    } else {
      span.start(timestamp);
    }
  }
  return span;
}
 
Example #3
Source File: PendingSpansClassLoaderTest.java    From brave with Apache License 2.0 6 votes vote down vote up
@Override public void run() {
  MutableSpan defaultSpan = new MutableSpan();
  Clock clock = Platform.get().clock();
  SpanHandler orphanTracker =
      OrphanTracker.newBuilder().clock(clock).defaultSpan(defaultSpan).build();
  PendingSpans pendingSpans =
      new PendingSpans(defaultSpan, clock, orphanTracker, new AtomicBoolean());

  TraceContext context = CONTEXT.toBuilder().build(); // intentionally make a copy
  pendingSpans.getOrCreate(null, context, true);
  context = null; // orphan the context

  GarbageCollectors.blockOnGC();

  pendingSpans.expungeStaleEntries();
}
 
Example #4
Source File: TraceContext.java    From brave with Apache License 2.0 6 votes vote down vote up
/** Parses the span id from the input string. Returns true if the ID is valid. */
<R, K> boolean parseSpanId(Propagation.Getter<R, K> getter, R request, K key) {
  String spanIdString = getter.get(request, key);
  if (isNull(key, spanIdString)) return false;
  int length = spanIdString.length();
  if (invalidIdLength(key, length, 16)) return false;

  spanId = lenientLowerHexToUnsignedLong(spanIdString, 0, length);
  if (spanId == 0) {
    if (isAllZeros(spanIdString, 0, length)) {
      Platform.get().log("Invalid input: spanId was all zeros", null);
      return false;
    }
    maybeLogNotLowerHex(spanIdString);
    return false;
  }
  return true;
}
 
Example #5
Source File: TestServer.java    From brave with Apache License 2.0 6 votes vote down vote up
TestServer(Propagation.Factory propagationFactory) {
  extractor = propagationFactory.get().extractor(Map::get);
  linkLocalIp = Platform.get().linkLocalIp();
  if (linkLocalIp != null) {
    // avoid dubbo's logic which might pick docker ip
    System.setProperty(Constants.DUBBO_IP_TO_BIND, linkLocalIp);
    System.setProperty(Constants.DUBBO_IP_TO_REGISTRY, linkLocalIp);
  }
  service = new ServiceConfig<>();
  service.setApplication(new ApplicationConfig("bean-provider"));
  service.setRegistry(new RegistryConfig(RegistryConfig.NO_AVAILABLE));
  service.setProtocol(new ProtocolConfig("dubbo", PickUnusedPort.get()));
  service.setInterface(GreeterService.class);
  service.setRef((method, parameterTypes, args) -> {
    requestQueue.add(extractor.extract(RpcContext.getContext().getAttachments()));
    return args[0];
  });
}
 
Example #6
Source File: HttpHandler.java    From brave with Apache License 2.0 6 votes vote down vote up
void handleFinish(HttpResponse response, Span span) {
  if (response == null) throw new NullPointerException("response == null");
  if (span == null) throw new NullPointerException("span == null");
  if (span.isNoop()) return;

  if (response.error() != null) {
    span.error(response.error()); // Ensures MutableSpan.error() for SpanHandler
  }

  try {
    parseResponse(response, span);
  } catch (Throwable t) {
    propagateIfFatal(t);
    Platform.get().log("error parsing response {0}", response, t);
  } finally {
    long finishTimestamp = response.finishTimestamp();
    if (finishTimestamp == 0L) {
      span.finish();
    } else {
      span.finish(finishTimestamp);
    }
  }
}
 
Example #7
Source File: B3SingleFormat.java    From brave with Apache License 2.0 6 votes vote down vote up
static void log(int fieldCode, String s) {
  String field;
  switch (fieldCode) {
    case FIELD_TRACE_ID_HIGH:
    case FIELD_TRACE_ID:
      field = "trace ID";
      break;
    case FIELD_SPAN_ID:
      field = "span ID";
      break;
    case FIELD_SAMPLED:
      field = "sampled";
      break;
    case FIELD_PARENT_SPAN_ID:
      field = "parent ID";
      break;
    default:
      throw new AssertionError("field code unmatched: " + fieldCode);
  }
  Platform.get().log(s, field, null);
}
 
Example #8
Source File: HttpHandler.java    From brave with Apache License 2.0 6 votes vote down vote up
Span handleStart(HttpRequest request, Span span) {
  if (span.isNoop()) return span;

  try {
    parseRequest(request, span);
  } catch (Throwable t) {
    propagateIfFatal(t);
    Platform.get().log("error parsing request {0}", request, t);
  } finally {
    // all of the above parsing happened before a timestamp on the span
    long timestamp = request.startTimestamp();
    if (timestamp == 0L) {
      span.start();
    } else {
      span.start(timestamp);
    }
  }
  return span;
}
 
Example #9
Source File: MapExtra.java    From brave with Apache License 2.0 6 votes vote down vote up
/**
 * Updates the value of the {@code key}, or ignores if read-only or not configured.
 *
 * @param value {@code null} is an attempt to remove the value
 * @return {@code true} if the underlying state changed
 * @since 5.12
 */
protected boolean put(K key, @Nullable V value) {
  if (key == null) return false;

  int i = indexOfExistingKey(state(), key);
  if (i == -1 && factory.maxDynamicEntries == 0) {
    Platform.get().log("Ignoring request to add a dynamic key", null);
    return false;
  }

  synchronized (lock) {
    Object[] prior = state();

    // double-check lost race in dynamic case
    if (i == -1) i = indexOfDynamicKey(prior, key);
    if (i == -1) return addNewEntry(prior, key, value);

    if (equal(value, prior[i + 1])) return false;

    Object[] newState = Arrays.copyOf(prior, prior.length); // copy-on-write
    newState[i + 1] = value;
    this.state = newState;
    return true;
  }
}
 
Example #10
Source File: TestServer.java    From brave with Apache License 2.0 6 votes vote down vote up
TestServer(Propagation.Factory propagationFactory, ApplicationConfig application) {
  extractor = propagationFactory.get().extractor(Map::get);
  linkLocalIp = Platform.get().linkLocalIp();
  if (linkLocalIp != null) {
    // avoid dubbo's logic which might pick docker ip
    System.setProperty(CommonConstants.DUBBO_IP_TO_BIND, linkLocalIp);
    System.setProperty(Constants.DUBBO_IP_TO_REGISTRY, linkLocalIp);
  }
  service = new ServiceConfig<>();
  service.setApplication(application);
  service.setRegistry(new RegistryConfig(RegistryConfig.NO_AVAILABLE));
  service.setProtocol(new ProtocolConfig("dubbo", PickUnusedPort.get()));
  service.setInterface(GreeterService.class);
  service.setRef((method, parameterTypes, args) -> {
    requestQueue.add(extractor.extract(RpcContext.getContext().getAttachments()));
    return args[0];
  });
}
 
Example #11
Source File: NoopAwareSpanHandler.java    From brave with Apache License 2.0 5 votes vote down vote up
@Override public boolean end(TraceContext context, MutableSpan span, Cause cause) {
  if (noop.get()) return false;
  try {
    return delegate.end(context, span, cause);
  } catch (Throwable t) {
    propagateIfFatal(t);
    Platform.get().log("error handling end {0}", context, t);
    return true; // user error in this handler shouldn't impact another
  }
}
 
Example #12
Source File: DubboParser.java    From brave with Apache License 2.0 5 votes vote down vote up
static boolean parseRemoteIpAndPort(Span span) {
  RpcContext rpcContext = RpcContext.getContext();
  InetSocketAddress remoteAddress = rpcContext.getRemoteAddress();
  if (remoteAddress == null) return false;
  return span.remoteIpAndPort(
      Platform.get().getHostString(remoteAddress),
      remoteAddress.getPort()
  );
}
 
Example #13
Source File: DubboParser.java    From brave with Apache License 2.0 5 votes vote down vote up
static boolean parseRemoteIpAndPort(Span span) {
  RpcContext rpcContext = RpcContext.getContext();
  InetSocketAddress remoteAddress = rpcContext.getRemoteAddress();
  if (remoteAddress == null) return false;
  return span.remoteIpAndPort(
      Platform.get().getHostString(remoteAddress),
      remoteAddress.getPort()
  );
}
 
Example #14
Source File: Tracing.java    From brave with Apache License 2.0 5 votes vote down vote up
/**
 * Inputs receive {code (context, span)} pairs for every {@linkplain TraceContext#sampledLocal()
 * locally sampled} span. The span is mutable for customization or redaction purposes. Span
 * handlers execute in order: If any handler returns {code false}, the next will not see the
 * span.
 *
 * @param spanHandler skipped if {@link SpanHandler#NOOP} or already added
 * @since 5.12
 */
public Builder addSpanHandler(SpanHandler spanHandler) {
  if (spanHandler == null) throw new NullPointerException("spanHandler == null");

  // Some configuration can coerce to no-op, ignore in this case.
  if (spanHandler == SpanHandler.NOOP) return this;

  if (!spanHandlers.add(spanHandler)) {
    Platform.get().log("Please check configuration as %s was added twice", spanHandler, null);
  }
  return this;
}
 
Example #15
Source File: Tag.java    From brave with Apache License 2.0 5 votes vote down vote up
final void tag(Object span, I input, @Nullable TraceContext context) {
  String key = null;
  String value = null;
  Throwable error = null;

  // Defensively call the only protected methods
  try {
    key = key(input);
    value = parseValue(input, context);
  } catch (Throwable e) {
    error = e;
    propagateIfFatal(e);
  }

  if (key == null || key.isEmpty()) {
    Platform.get().log("Error parsing tag key of input %s", input, error);
    return;
  } else if (error != null) {
    Platform.get().log("Error parsing tag value of input %s", input, error);
    return;
  }

  if (value == null) return;
  if (span instanceof SpanCustomizer) {
    ((SpanCustomizer) span).tag(key, value);
  } else if (span instanceof MutableSpan) {
    ((MutableSpan) span).tag(key, value);
  }
}
 
Example #16
Source File: JsonWriter.java    From brave with Apache License 2.0 5 votes vote down vote up
/** Inability to encode is a programming bug. */
public static <T> byte[] write(Writer<T> writer, T value) {
  byte[] result = new byte[writer.sizeInBytes(value)];
  WriteBuffer b = WriteBuffer.wrap(result);
  try {
    writer.write(value, b);
  } catch (RuntimeException e) {
    int lengthWritten = result.length;
    for (int i = 0; i < result.length; i++) {
      if (result[i] == 0) {
        lengthWritten = i;
        break;
      }
    }

    // Don't use value directly in the message, as its toString might be implemented using this
    // method. If that's the case, we'd stack overflow. Instead, emit what we've written so far.
    String message =
        format(
            "Bug found using %s to write %s as json. Wrote %s/%s bytes: %s",
            writer.getClass().getSimpleName(),
            value.getClass().getSimpleName(),
            lengthWritten,
            result.length,
            new String(result, 0, lengthWritten, UTF_8));
    throw Platform.get().assertionError(message, e);
  }
  return result;
}
 
Example #17
Source File: MapExtra.java    From brave with Apache License 2.0 5 votes vote down vote up
/** Grows the state to append a new key/value pair unless we reached a limit. */
boolean addNewEntry(Object[] prior, K key, @Nullable V value) {
  int newIndex = prior.length;
  int newstateLength = newIndex + 2;
  if (newstateLength / 2 > MAX_DYNAMIC_ENTRIES) {
    Platform.get().log("Ignoring request to add > %s dynamic entries", MAX_DYNAMIC_ENTRIES, null);
    return false;
  }
  Object[] newState = Arrays.copyOf(prior, newstateLength); // copy-on-write
  newState[newIndex] = key;
  newState[newIndex + 1] = value;
  this.state = newState;
  return true;
}
 
Example #18
Source File: NoopAwareSpanHandler.java    From brave with Apache License 2.0 5 votes vote down vote up
@Override public boolean begin(TraceContext context, MutableSpan span, TraceContext parent) {
  if (noop.get()) return false;
  try {
    return delegate.begin(context, span, parent);
  } catch (Throwable t) {
    propagateIfFatal(t);
    Platform.get().log("error handling begin {0}", context, t);
    return true; // user error in this handler shouldn't impact another
  }
}
 
Example #19
Source File: TracingHttpServerHandler.java    From brave with Apache License 2.0 5 votes vote down vote up
@Override public boolean parseClientIpAndPort(Span span) {
  if (parseClientIpFromXForwardedFor(span)) return true;
  if (remoteAddress == null || remoteAddress.getAddress() == null) return false;
  return span.remoteIpAndPort(
    Platform.get().getHostString(remoteAddress),
    remoteAddress.getPort()
  );
}
 
Example #20
Source File: TraceContext.java    From brave with Apache License 2.0 5 votes vote down vote up
/**
 * Returns true when {@link TraceContext#traceId()} and potentially also {@link
 * TraceContext#traceIdHigh()} were parsed from the input. This assumes the input is valid, an
 * up to 32 character lower-hex string.
 *
 * <p>Returns boolean, not this, for conditional, exception free parsing:
 *
 * <p>Example use:
 * <pre>{@code
 * // Attempt to parse the trace ID or break out if unsuccessful for any reason
 * String traceIdString = getter.get(request, key);
 * if (!builder.parseTraceId(traceIdString, propagation.traceIdKey)) {
 *   return TraceContextOrSamplingFlags.EMPTY;
 * }
 * }</pre>
 *
 * @param traceIdString the 1-32 character lowerhex string
 * @param key the name of the propagation field representing the trace ID; only using in
 * logging
 * @return false if the input is null or malformed
 */
// temporarily package protected until we figure out if this is reusable enough to expose
boolean parseTraceId(String traceIdString, Object key) {
  if (isNull(key, traceIdString)) return false;
  int length = traceIdString.length();
  if (invalidIdLength(key, length, 32)) return false;

  boolean traceIdHighAllZeros = false, traceIdAllZeros = false;

  // left-most characters, if any, are the high bits
  int traceIdIndex = Math.max(0, length - 16);
  if (traceIdIndex > 0) {
    traceIdHigh = lenientLowerHexToUnsignedLong(traceIdString, 0, traceIdIndex);
    if (traceIdHigh == 0L) {
      traceIdHighAllZeros = isAllZeros(traceIdString, 0, traceIdIndex);
      if (!traceIdHighAllZeros) {
        maybeLogNotLowerHex(traceIdString);
        return false;
      }
    }
  } else {
    traceIdHighAllZeros = true;
  }

  // right-most up to 16 characters are the low bits
  traceId = lenientLowerHexToUnsignedLong(traceIdString, traceIdIndex, length);
  if (traceId == 0L) {
    traceIdAllZeros = isAllZeros(traceIdString, traceIdIndex, length);
    if (!traceIdAllZeros) {
      maybeLogNotLowerHex(traceIdString);
      return false;
    }
  }

  if (traceIdHighAllZeros && traceIdAllZeros) {
    Platform.get().log("Invalid input: traceId was all zeros", null);
  }
  return traceIdHigh != 0L || traceId != 0L;
}
 
Example #21
Source File: PendingSpansClassLoaderTest.java    From brave with Apache License 2.0 5 votes vote down vote up
@Override public void run() {
  PendingSpans pendingSpans = new PendingSpans(new MutableSpan(),
    Platform.get().clock(), SpanHandler.NOOP, new AtomicBoolean());

  TraceContext context = CONTEXT.toBuilder().build(); // intentionally make a copy
  pendingSpans.getOrCreate(null, context, true);
  pendingSpans.remove(context);
}
 
Example #22
Source File: IntegrationTestSpanHandler.java    From brave with Apache License 2.0 5 votes vote down vote up
public IntegrationTestSpanHandler() {
  // OrphanTracker detects to see if it should add "brave.flushed" or not, as it is used in
  // production some times and avoiding this could be helpful. This forces a failed match,
  // so that we can detect orphans even when no data was added.
  MutableSpan intentionallyWrongDefaultSpan = new MutableSpan();
  intentionallyWrongDefaultSpan.tag("not", "me");
  orphanTracker = OrphanTracker.newBuilder()
      .defaultSpan(intentionallyWrongDefaultSpan)
      // This will not be exactly the right timestamp when Tracing.Builder.clock is overridden.
      // However, it is rare to override this in an integration test and complex to pass it.
      .clock(Platform.get().clock())
      // Make sure CI can see when things leak: Intentional leak tests shouldn't use this handler.
      .logLevel(Level.WARNING).build();
}
 
Example #23
Source File: TraceContextBinaryFormat.java    From brave with Apache License 2.0 4 votes vote down vote up
@Nullable static TraceContext parseBytes(byte[] bytes, @Nullable TagsBin tags) {
  if (bytes == null) throw new NullPointerException("bytes == null"); // programming error
  if (bytes.length == 0) return null;
  if (bytes[0] != VERSION) {
    Platform.get().log("Invalid input: unsupported version {0}", bytes[0], null);
    return null;
  }
  if (bytes.length < FORMAT_LENGTH - 2 /* sampled field + bit is optional */) {
    Platform.get().log("Invalid input: truncated", null);
    return null;
  }
  long traceIdHigh, traceId, spanId;
  int pos = 1;
  if (bytes[pos] == TRACE_ID_FIELD_ID) {
    pos++;
    traceIdHigh = readLong(bytes, pos);
    traceId = readLong(bytes, pos + 8);
    pos += 16;
  } else {
    Platform.get().log("Invalid input: expected trace ID at offset {0}", pos, null);
    return null;
  }
  if (bytes[pos] == SPAN_ID_FIELD_ID) {
    pos++;
    spanId = readLong(bytes, pos);
    pos += 8;
  } else {
    Platform.get().log("Invalid input: expected span ID at offset {0}", pos, null);
    return null;
  }
  // The trace options field is optional. However, when present, it should be valid.
  Boolean sampled = null;
  if (bytes.length > pos && bytes[pos] == TRACE_OPTION_FIELD_ID) {
    pos++;
    if (bytes.length < pos + 1) {
      Platform.get().log("Invalid input: truncated", null);
      return null;
    }
    sampled = bytes[pos] == 1;
  }
  TraceContext.Builder builder = TraceContext.newBuilder()
    .traceIdHigh(traceIdHigh)
    .traceId(traceId)
    .spanId(spanId);
  if (sampled != null) builder.sampled(sampled.booleanValue());
  if (tags != null) builder.extra(Collections.singletonList(tags));
  return builder.build();
}
 
Example #24
Source File: BraveTraceIdGenerator.java    From servicecomb-java-chassis with Apache License 2.0 4 votes vote down vote up
@Override
public String generate() {
  return Long.toHexString(Platform.get().nextTraceIdHigh());
}
 
Example #25
Source File: B3PropagationTest.java    From brave with Apache License 2.0 4 votes vote down vote up
@Before public void setupLogger() {
  mockStatic(Platform.class);
  when(Platform.get()).thenReturn(platform);
}
 
Example #26
Source File: B3SingleFormatTest.java    From brave with Apache License 2.0 4 votes vote down vote up
@Before public void setupLogger() {
  mockStatic(Platform.class);
  when(Platform.get()).thenReturn(platform);
}
 
Example #27
Source File: Tracing.java    From brave with Apache License 2.0 4 votes vote down vote up
Default(Builder builder) {
  this.clock = builder.clock != null ? builder.clock : Platform.get().clock();
  this.errorParser = builder.errorParser;
  this.propagationFactory = builder.propagationFactory;
  this.stringPropagation = builder.propagationFactory.get();
  this.currentTraceContext = builder.currentTraceContext;
  this.sampler = builder.sampler;
  this.noop = new AtomicBoolean();

  MutableSpan defaultSpan = new MutableSpan(builder.defaultSpan); // safe copy

  Set<SpanHandler> spanHandlers = new LinkedHashSet<>(builder.spanHandlers);
  // When present, the Zipkin handler is invoked after the user-supplied ones.
  if (builder.zipkinSpanReporter != null) {
    spanHandlers.add(
        ZipkinSpanHandler.newBuilder((Reporter<zipkin2.Span>) builder.zipkinSpanReporter)
            .errorTag(errorParser)
            .alwaysReportSpans(builder.alwaysReportSpans)
            .build());
  }
  if (spanHandlers.isEmpty()) spanHandlers.add(new LogSpanHandler());
  if (builder.trackOrphans) {
    spanHandlers.add(OrphanTracker.newBuilder().defaultSpan(defaultSpan).clock(clock).build());
  }

  // Make sure any exceptions caused by span handlers don't crash callers
  SpanHandler spanHandler =
    NoopAwareSpanHandler.create(spanHandlers.toArray(new SpanHandler[0]), noop);

  boolean alwaysSampleLocal = builder.alwaysSampleLocal;
  for (SpanHandler handler : spanHandlers) {
    if (handler instanceof FinishedSpanHandler) {
      // Handle deprecated FinishedSpanHandler.alwaysSampleLocal
      if (((FinishedSpanHandler)handler).alwaysSampleLocal()) alwaysSampleLocal = true;
    }
  }

  this.tracer = new Tracer(
    builder.clock,
    builder.propagationFactory,
    spanHandler,
    new PendingSpans(defaultSpan, clock, spanHandler, noop),
    builder.sampler,
    builder.currentTraceContext,
    builder.traceId128Bit || propagationFactory.requires128BitTraceId(),
    builder.supportsJoin && propagationFactory.supportsJoin(),
    alwaysSampleLocal,
    noop
  );
  // assign current IFF there's no instance already current
  CURRENT.compareAndSet(null, this);
}
 
Example #28
Source File: EntrySplitter.java    From brave with Apache License 2.0 4 votes vote down vote up
static boolean logOrThrow(String msg, boolean shouldThrow) {
  if (shouldThrow) throw new IllegalArgumentException(msg);
  Platform.get().log(msg, null);
  return false;
}
 
Example #29
Source File: Tracer.java    From brave with Apache License 2.0 4 votes vote down vote up
/**
 * Creates a trace context object holding the below fields. When fields such as span ID are
 * absent, they will be backfilled. Then, any missing state managed by the tracer are applied,
 * such as the "local root". Finally, decoration hooks apply to ensure any propagation state are
 * added to the "extra" section of the result. This supports functionality like baggage
 * propagation.
 *
 * <p>All parameters except span ID can be empty in the case of a new root span.
 *
 * @param flags any incoming flags from a parent context.
 * @param traceIdHigh See {@link TraceContext#traceIdHigh()}
 * @param traceId Zero is a new trace. Otherwise, {@link TraceContext#traceId()}.
 * @param localRootId Zero is a new local root. Otherwise, {@link TraceContext#localRootId()}.
 * @param parentId Same as {@link TraceContext#parentIdAsLong()}.
 * @param spanId When non-zero this is a shared span. See {@link TraceContext#spanId()}.
 * @param extra Any additional {@link TraceContext#extra() propagated state}.
 * @return a decorated, sampled context with local root information applied.
 */
TraceContext decorateContext(
  int flags,
  long traceIdHigh,
  long traceId,
  long localRootId,
  long parentId,
  long spanId,
  List<Object> extra
) {
  if (alwaysSampleLocal && (flags & FLAG_SAMPLED_LOCAL) != FLAG_SAMPLED_LOCAL) {
    flags |= FLAG_SAMPLED_LOCAL;
  }

  if (spanId == 0L) spanId = nextId();

  if (traceId == 0L) { // make a new trace ID
    traceIdHigh = traceId128Bit ? Platform.get().nextTraceIdHigh() : 0L;
    traceId = spanId;
  }

  if ((flags & FLAG_SAMPLED_SET) != FLAG_SAMPLED_SET) { // cheap check for not yet sampled
    flags = InternalPropagation.sampled(sampler.isSampled(traceId), flags);
    flags &= ~FLAG_SHARED; // cannot be shared if not yet sampled
  }

  // Zero when root or an externally managed context was passed to newChild or scopedWithParent
  if (localRootId == 0L) {
    localRootId = spanId;
    flags |= FLAG_LOCAL_ROOT;
  } else {
    flags &= ~FLAG_LOCAL_ROOT;
  }
  return propagationFactory.decorate(InternalPropagation.instance.newTraceContext(
    flags,
    traceIdHigh,
    traceId,
    localRootId,
    parentId,
    spanId,
    extra
  ));
}
 
Example #30
Source File: B3Propagation.java    From brave with Apache License 2.0 4 votes vote down vote up
@Override public TraceContextOrSamplingFlags extract(R request) {
  if (request == null) throw new NullPointerException("request == null");

  // try to extract single-header format
  String b3 = getter.get(request, B3);
  TraceContextOrSamplingFlags extracted = b3 != null ? parseB3SingleFormat(b3) : null;
  if (extracted != null) return extracted;

  // Start by looking at the sampled state as this is used regardless
  // Official sampled value is 1, though some old instrumentation send true
  String sampled = getter.get(request, SAMPLED);
  Boolean sampledV;
  if (sampled == null) {
    sampledV = null; // defer decision
  } else if (sampled.length() == 1) { // handle fast valid paths
    char sampledC = sampled.charAt(0);

    if (sampledC == '1') {
      sampledV = true;
    } else if (sampledC == '0') {
      sampledV = false;
    } else {
      Platform.get().log(SAMPLED_MALFORMED, sampled, null);
      return TraceContextOrSamplingFlags.EMPTY; // trace context is malformed so return empty
    }
  } else if (sampled.equalsIgnoreCase("true")) { // old clients
    sampledV = true;
  } else if (sampled.equalsIgnoreCase("false")) { // old clients
    sampledV = false;
  } else {
    Platform.get().log(SAMPLED_MALFORMED, sampled, null);
    return TraceContextOrSamplingFlags.EMPTY; // Restart trace instead of propagating false
  }

  // The only flag we action is 1, but it could be that any integer is present.
  // Here, we leniently parse as debug is not a primary consideration of the trace context.
  boolean debug = "1".equals(getter.get(request, FLAGS));

  String traceIdString = getter.get(request, TRACE_ID);

  // It is ok to go without a trace ID, if sampling or debug is set
  if (traceIdString == null) {
    if (debug) return TraceContextOrSamplingFlags.DEBUG;
    if (sampledV != null) {
      return sampledV
          ? TraceContextOrSamplingFlags.SAMPLED
          : TraceContextOrSamplingFlags.NOT_SAMPLED;
    }
  }

  // Try to parse the trace IDs into the context
  TraceContext.Builder result = TraceContext.newBuilder();
  if (result.parseTraceId(traceIdString, TRACE_ID)
      && result.parseSpanId(getter, request, SPAN_ID)
      && result.parseParentId(getter, request, PARENT_SPAN_ID)) {
    if (sampledV != null) result.sampled(sampledV.booleanValue());
    if (debug) result.debug(true);
    return TraceContextOrSamplingFlags.create(result.build());
  }
  return TraceContextOrSamplingFlags.EMPTY; // trace context is malformed so return empty
}