Java源码示例:io.opencensus.trace.SpanContext
示例1
private static String logWithSpanAndLog4jConfiguration(
String log4jPattern, SpanContext spanContext, Function<Logger, Void> loggingFunction) {
StringWriter output = new StringWriter();
StringLayout layout = PatternLayout.newBuilder().withPattern(log4jPattern).build();
Appender appender =
WriterAppender.newBuilder()
.setTarget(output)
.setLayout(layout)
.setName("TestAppender")
.build();
((LoggerContext) LogManager.getContext(false)).updateLoggers();
appender.start();
logger.addAppender(appender);
logger.setLevel(Level.ALL);
try {
logWithSpan(spanContext, loggingFunction, logger);
return output.toString();
} finally {
logger.removeAppender(appender);
}
}
示例2
/**
* Instrument a request for tracing and stats before it is sent.
*
* <p>This method will create a span in current context to represent the HTTP call. The created
* span will be serialized and propagated to the server.
*
* <p>The generated span will NOT be set as current context. User can control when to enter the
* scope of this span. Use {@link AbstractHttpHandler#getSpanFromContext} to retrieve the span.
*
* @param parent the parent {@link Span}. {@code null} indicates using current span.
* @param carrier the entity that holds the HTTP information.
* @param request the request entity.
* @return the {@link HttpRequestContext} that contains stats and trace data associated with the
* request.
* @since 0.19
*/
public HttpRequestContext handleStart(@Nullable Span parent, C carrier, Q request) {
checkNotNull(carrier, "carrier");
checkNotNull(request, "request");
if (parent == null) {
parent = tracer.getCurrentSpan();
}
String spanName = getSpanName(request, extractor);
SpanBuilder builder = tracer.spanBuilderWithExplicitParent(spanName, parent);
Span span = builder.setSpanKind(Kind.CLIENT).startSpan();
if (span.getOptions().contains(Options.RECORD_EVENTS)) {
addSpanRequestAttributes(span, request, extractor);
}
// inject propagation header
SpanContext spanContext = span.getContext();
if (!spanContext.equals(SpanContext.INVALID)) {
textFormat.inject(spanContext, carrier, setter);
}
return getNewContext(span, tagger.getCurrentTagContext());
}
示例3
@Override
public <C /*>>> extends @NonNull Object*/> void inject(
SpanContext spanContext, C carrier, Setter<C> setter) {
checkNotNull(spanContext, "spanContext");
checkNotNull(setter, "setter");
checkNotNull(carrier, "carrier");
StringBuilder builder =
new StringBuilder()
.append(spanContext.getTraceId().toLowerBase16())
.append(SPAN_ID_DELIMITER)
.append(UnsignedLongs.toString(spanIdToLong(spanContext.getSpanId())))
.append(TRACE_OPTION_DELIMITER)
.append(spanContext.getTraceOptions().isSampled() ? SAMPLED : NOT_SAMPLED);
setter.put(carrier, HEADER_NAME, builder.toString());
}
示例4
@Test
public void enhanceLogEntry_AddNonSampledSpanToLogEntry() {
LogEntry logEntry =
getEnhancedLogEntry(
new OpenCensusTraceLoggingEnhancer("my-test-project-6"),
new TestSpan(
SpanContext.create(
TraceId.fromLowerBase16("72c905c76f99e99974afd84dc053a480"),
SpanId.fromLowerBase16("731e102335b7a5a0"),
TraceOptions.builder().setIsSampled(false).build(),
EMPTY_TRACESTATE)));
assertFalse(logEntry.getTraceSampled());
assertThat(logEntry.getTrace())
.isEqualTo("projects/my-test-project-6/traces/72c905c76f99e99974afd84dc053a480");
assertThat(logEntry.getSpanId()).isEqualTo("731e102335b7a5a0");
}
示例5
@Test
public void testResponseFilter() throws Exception {
Span span = new FakeSpan(SpanContext.INVALID, null);
TagContext tagContext = mock(TagContext.class);
HttpRequestContext context = JaxrsClientFilterTest.createHttpRequestContext(span, tagContext);
UriInfo uriInfo = mock(UriInfo.class);
when(uriInfo.getMatchedURIs()).thenReturn(Collections.singletonList("/resource/{route}"));
ContainerRequestContext requestContext = mock(ContainerRequestContext.class);
when(requestContext.getProperty("opencensus.context")).thenReturn(context);
when(requestContext.getUriInfo()).thenReturn(uriInfo);
ContainerResponseContext responseContext = mock(ContainerResponseContext.class);
filter.filter(requestContext, responseContext);
verify(requestContext).getProperty("opencensus.context");
verify(responseContext, times(1)).getStatus();
}
示例6
private RecordEventsSpanImpl(
SpanContext context,
String name,
@Nullable Kind kind,
@Nullable SpanId parentSpanId,
@Nullable Boolean hasRemoteParent,
TraceParams traceParams,
StartEndHandler startEndHandler,
@Nullable TimestampConverter timestampConverter,
Clock clock) {
super(context, RECORD_EVENTS_SPAN_OPTIONS);
this.parentSpanId = parentSpanId;
this.hasRemoteParent = hasRemoteParent;
this.name = name;
this.kind = kind;
this.traceParams = traceParams;
this.startEndHandler = startEndHandler;
this.clock = clock;
this.hasBeenEnded = false;
this.sampleToLocalSpanStore = false;
this.numberOfChildren = 0;
this.timestampConverter =
timestampConverter != null ? timestampConverter : TimestampConverter.now(clock);
startNanoTime = clock.nowNanos();
}
示例7
@Test
public void generateSpan_NullStatus() {
SpanData data =
SpanData.create(
SpanContext.create(
TraceId.fromLowerBase16(TRACE_ID),
SpanId.fromLowerBase16(SPAN_ID),
TraceOptions.builder().setIsSampled(true).build()),
SpanId.fromLowerBase16(PARENT_SPAN_ID),
true, /* hasRemoteParent */
"SpanName", /* name */
null, /* kind */
Timestamp.create(1505855794, 194009601) /* startTimestamp */,
Attributes.create(attributes, 0 /* droppedAttributesCount */),
TimedEvents.create(annotations, 0 /* droppedEventsCount */),
TimedEvents.create(messageEvents, 0 /* droppedEventsCount */),
Links.create(Collections.<Link>emptyList(), 0 /* droppedLinksCount */),
null, /* childSpanCount */
null, /* status */
Timestamp.create(1505855799, 465726528) /* endTimestamp */);
assertThat(InstanaExporterHandler.convertToJson(Collections.singletonList(data)))
.isEqualTo("[]");
}
示例8
private static boolean makeSamplingDecision(
@Nullable SpanContext parent,
@Nullable Boolean hasRemoteParent,
String name,
@Nullable Sampler sampler,
List<Span> parentLinks,
TraceId traceId,
SpanId spanId,
TraceParams activeTraceParams) {
// If users set a specific sampler in the SpanBuilder, use it.
if (sampler != null) {
return sampler.shouldSample(parent, hasRemoteParent, traceId, spanId, name, parentLinks);
}
// Use the default sampler if this is a root Span or this is an entry point Span (has remote
// parent).
if (Boolean.TRUE.equals(hasRemoteParent) || parent == null || !parent.isValid()) {
return activeTraceParams
.getSampler()
.shouldSample(parent, hasRemoteParent, traceId, spanId, name, parentLinks);
}
// Parent is always different than null because otherwise we use the default sampler.
return parent.getTraceOptions().isSampled() || isAnyParentLinkSampled(parentLinks);
}
示例9
@Test
public void testResponseFilter() throws Exception {
Span span = new FakeSpan(SpanContext.INVALID, null);
TagContext tagContext = mock(TagContext.class);
HttpRequestContext context = createHttpRequestContext(span, tagContext);
ClientRequestContext requestContext = mock(ClientRequestContext.class);
when(requestContext.getProperty("opencensus.context")).thenReturn(context);
ClientResponseContext responseContext = mock(ClientResponseContext.class);
filter.filter(requestContext, responseContext);
verify(requestContext).getProperty("opencensus.context");
verify(responseContext, times(1)).getStatus();
}
示例10
CensusTracingModule(
Tracer censusTracer, final BinaryFormat censusPropagationBinaryFormat) {
this.censusTracer = checkNotNull(censusTracer, "censusTracer");
checkNotNull(censusPropagationBinaryFormat, "censusPropagationBinaryFormat");
this.tracingHeader =
Metadata.Key.of("grpc-trace-bin", new Metadata.BinaryMarshaller<SpanContext>() {
@Override
public byte[] toBytes(SpanContext context) {
return censusPropagationBinaryFormat.toByteArray(context);
}
@Override
public SpanContext parseBytes(byte[] serialized) {
try {
return censusPropagationBinaryFormat.fromByteArray(serialized);
} catch (Exception e) {
logger.log(Level.FINE, "Failed to parse tracing header", e);
return SpanContext.INVALID;
}
}
});
}
示例11
@Test
public void enhanceLogEntry_AddSampledSpanToLogEntry() {
LogEntry logEntry =
getEnhancedLogEntry(
new OpenCensusTraceLoggingEnhancer("my-test-project-3"),
new TestSpan(
SpanContext.create(
TraceId.fromLowerBase16("4c6af40c499951eb7de2777ba1e4fefa"),
SpanId.fromLowerBase16("de52e84d13dd232d"),
TraceOptions.builder().setIsSampled(true).build(),
EMPTY_TRACESTATE)));
assertTrue(logEntry.getTraceSampled());
assertThat(logEntry.getTrace())
.isEqualTo("projects/my-test-project-3/traces/4c6af40c499951eb7de2777ba1e4fefa");
assertThat(logEntry.getSpanId()).isEqualTo("de52e84d13dd232d");
}
示例12
@Test
public void addNonSampledSpanToLogEntryWithAllSpans() {
String log =
logWithSpanAndLog4jConfiguration(
TEST_PATTERN,
SpanContext.create(
TraceId.fromLowerBase16("cd7061dfa9d312cdcc42edab3feab51b"),
SpanId.fromLowerBase16("117d42d4c7acd066"),
TraceOptions.builder().setIsSampled(false).build(),
EMPTY_TRACESTATE),
new Function<Logger, Void>() {
@Override
public Void apply(Logger logger) {
logger.info("message #2");
return null;
}
});
assertThat(log)
.isEqualTo(
"traceId=cd7061dfa9d312cdcc42edab3feab51b spanId=117d42d4c7acd066 sampled=false INFO "
+ "- message #2");
}
示例13
@Test(timeout = 10000)
public void censusContextsPropagated() {
Assume.assumeTrue("Skip the test because server is not in the same process.", server != null);
Span clientParentSpan = Tracing.getTracer().spanBuilder("Test.interopTest").startSpan();
// A valid ID is guaranteed to be unique, so we can verify it is actually propagated.
assertTrue(clientParentSpan.getContext().getTraceId().isValid());
Context ctx =
Context.ROOT.withValues(
TAG_CONTEXT_KEY,
tagger.emptyBuilder().put(
StatsTestUtils.EXTRA_TAG, TagValue.create("extra value")).build(),
ContextUtils.CONTEXT_SPAN_KEY,
clientParentSpan);
Context origCtx = ctx.attach();
try {
blockingStub.unaryCall(SimpleRequest.getDefaultInstance());
Context serverCtx = contextCapture.get();
assertNotNull(serverCtx);
FakeTagContext statsCtx = (FakeTagContext) TAG_CONTEXT_KEY.get(serverCtx);
assertNotNull(statsCtx);
Map<TagKey, TagValue> tags = statsCtx.getTags();
boolean tagFound = false;
for (Map.Entry<TagKey, TagValue> tag : tags.entrySet()) {
if (tag.getKey().equals(StatsTestUtils.EXTRA_TAG)) {
assertEquals(TagValue.create("extra value"), tag.getValue());
tagFound = true;
}
}
assertTrue("tag not found", tagFound);
Span span = CONTEXT_SPAN_KEY.get(serverCtx);
assertNotNull(span);
SpanContext spanContext = span.getContext();
assertEquals(clientParentSpan.getContext().getTraceId(), spanContext.getTraceId());
} finally {
ctx.detach(origCtx);
}
}
示例14
private static void logWithSpan(
SpanContext spanContext, Function<Logger, Void> loggingFunction, Logger logger) {
Scope scope = tracer.withSpan(new TestSpan(spanContext));
try {
loggingFunction.apply(logger);
} finally {
scope.close();
}
}
示例15
@Test
public void generateSpan_ClientKind() {
SpanData data =
SpanData.create(
SpanContext.create(
TraceId.fromLowerBase16(TRACE_ID),
SpanId.fromLowerBase16(SPAN_ID),
TraceOptions.builder().setIsSampled(true).build()),
// TODO SpanId.fromLowerBase16
SpanId.fromLowerBase16(PARENT_SPAN_ID),
true, /* hasRemoteParent */
"Sent.helloworld.Greeter.SayHello", /* name */
Kind.CLIENT, /* kind */
Timestamp.create(1505855794, 194009601) /* startTimestamp */,
Attributes.create(attributes, 0 /* droppedAttributesCount */),
TimedEvents.create(annotations, 0 /* droppedEventsCount */),
TimedEvents.create(messageEvents, 0 /* droppedEventsCount */),
Links.create(Collections.<Link>emptyList(), 0 /* droppedLinksCount */),
null, /* childSpanCount */
Status.OK,
Timestamp.create(1505855799, 465726528) /* endTimestamp */);
assertThat(ZipkinExporterHandler.generateSpan(data, localEndpoint))
.isEqualTo(
Span.newBuilder()
.traceId(TRACE_ID)
.parentId(PARENT_SPAN_ID)
.id(SPAN_ID)
.kind(Span.Kind.CLIENT)
.name(data.getName())
.timestamp(1505855794000000L + 194009601L / 1000)
.duration(
(1505855799000000L + 465726528L / 1000)
- (1505855794000000L + 194009601L / 1000))
.localEndpoint(localEndpoint)
.addAnnotation(1505855799000000L + 433901068L / 1000, "RECEIVED")
.addAnnotation(1505855799000000L + 459486280L / 1000, "SENT")
.putTag(ZipkinExporterHandler.STATUS_CODE, "OK")
.build());
}
示例16
/**
* Creates a MockableSpan with a random trace ID and span ID.
*/
@SuppressWarnings("deprecation")
public static MockableSpan generateRandomSpan(Random random) {
return new MockableSpan(
SpanContext.create(
TraceId.generateRandomId(random),
SpanId.generateRandomId(random),
TraceOptions.DEFAULT),
null);
}
示例17
@Override
public boolean shouldSample(
@Nullable SpanContext parentContext,
@Nullable Boolean hasRemoteParent,
TraceId traceId,
SpanId spanId,
String name,
List<Span> parentLinks) {
return true;
}
示例18
@Override
public final boolean shouldSample(
@Nullable SpanContext parentContext,
@Nullable Boolean hasRemoteParent,
TraceId traceId,
SpanId spanId,
String name,
@Nullable List<Span> parentLinks) {
// If the parent is sampled keep the sampling decision.
if (parentContext != null && parentContext.getTraceOptions().isSampled()) {
return true;
}
if (parentLinks != null) {
// If any parent link is sampled keep the sampling decision.
for (Span parentLink : parentLinks) {
if (parentLink.getContext().getTraceOptions().isSampled()) {
return true;
}
}
}
// Always sample if we are within probability range. This is true even for child spans (that
// may have had a different sampling decision made) to allow for different sampling policies,
// and dynamic increases to sampling probabilities for debugging purposes.
// Note use of '<' for comparison. This ensures that we never sample for probability == 0.0,
// while allowing for a (very) small chance of *not* sampling if the id == Long.MAX_VALUE.
// This is considered a reasonable tradeoff for the simplicity/performance requirements (this
// code is executed in-line for every Span creation).
return Math.abs(traceId.getLowerLong()) < getIdUpperBound();
}
示例19
/**
* Returns a new immutable {@code SpanData}.
*
* @deprecated Use {@link #create(SpanContext, SpanId, Boolean, String, Kind, Timestamp,
* Attributes, TimedEvents, TimedEvents, Links, Integer, Status, Timestamp)}.
*/
@Deprecated
public static SpanData create(
SpanContext context,
@Nullable SpanId parentSpanId,
@Nullable Boolean hasRemoteParent,
String name,
Timestamp startTimestamp,
Attributes attributes,
TimedEvents<Annotation> annotations,
TimedEvents<? extends io.opencensus.trace.BaseMessageEvent> messageOrNetworkEvents,
Links links,
@Nullable Integer childSpanCount,
@Nullable Status status,
@Nullable Timestamp endTimestamp) {
return create(
context,
parentSpanId,
hasRemoteParent,
name,
null,
startTimestamp,
attributes,
annotations,
messageOrNetworkEvents,
links,
childSpanCount,
status,
endTimestamp);
}
示例20
@Test
public void parseFlag() throws SpanContextParseException {
Map<String, String> headersFlagSampled = new HashMap<String, String>();
headersFlagSampled.put(X_B3_TRACE_ID, TRACE_ID_BASE16);
headersFlagSampled.put(X_B3_SPAN_ID, SPAN_ID_BASE16);
headersFlagSampled.put(X_B3_FLAGS, "1");
assertThat(b3Format.extract(headersFlagSampled, getter))
.isEqualTo(SpanContext.create(TRACE_ID, SPAN_ID, TRACE_OPTIONS));
}
示例21
@Test
public void rawContextDataWithTracingData() {
OpenCensusTraceContextDataInjector plugin = new OpenCensusTraceContextDataInjector();
SpanContext spanContext =
SpanContext.create(
TraceId.fromLowerBase16("e17944156660f55b8cae5ce3f45d4a40"),
SpanId.fromLowerBase16("fc3d2ba0d283b66a"),
TraceOptions.builder().setIsSampled(true).build(),
EMPTY_TRACESTATE);
Scope scope = tracer.withSpan(new TestSpan(spanContext));
try {
String key = "myTestKey";
ThreadContext.put(key, "myTestValue");
try {
assertThat(plugin.rawContextData().toMap())
.containsExactly(
"myTestKey",
"myTestValue",
"traceId",
"e17944156660f55b8cae5ce3f45d4a40",
"spanId",
"fc3d2ba0d283b66a",
"traceSampled",
"true");
} finally {
ThreadContext.remove(key);
}
} finally {
scope.close();
}
}
示例22
@Test
public void generateSpan_NoKindAndRemoteParent() {
SpanData data =
SpanData.create(
SpanContext.create(
TraceId.fromLowerBase16(TRACE_ID),
SpanId.fromLowerBase16(SPAN_ID),
TraceOptions.builder().setIsSampled(true).build()),
SpanId.fromLowerBase16(PARENT_SPAN_ID),
true, /* hasRemoteParent */
"SpanName", /* name */
null, /* kind */
Timestamp.create(1505855794, 194009601) /* startTimestamp */,
Attributes.create(attributes, 0 /* droppedAttributesCount */),
TimedEvents.create(annotations, 0 /* droppedEventsCount */),
TimedEvents.create(messageEvents, 0 /* droppedEventsCount */),
Links.create(Collections.<Link>emptyList(), 0 /* droppedLinksCount */),
null, /* childSpanCount */
Status.OK,
Timestamp.create(1505855799, 465726528) /* endTimestamp */);
assertThat(InstanaExporterHandler.convertToJson(Collections.singletonList(data)))
.isEqualTo(
"["
+ "{"
+ "\"spanId\":\"9cc1e3049173be09\","
+ "\"traceId\":\"d239036e7d5cec11\","
+ "\"parentId\":\"8b03ab423da481c5\","
+ "\"timestamp\":1505855794194,"
+ "\"duration\":5271,"
+ "\"name\":\"SpanName\","
+ "\"type\":\"ENTRY\","
+ "\"data\":"
+ "{\"http.url\":\"http://localhost/foo\"}"
+ "}"
+ "]");
}
示例23
/** Decode a span using binary format. */
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public SpanContext decodeSpanBinary(Data data) throws SpanContextParseException {
return data.propagation.getBinaryFormat().fromByteArray(data.spanToDecodeBinary);
}
示例24
/** Decode a span using text format. */
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public SpanContext decodeSpanText(Data data) throws SpanContextParseException {
return data.propagation.getTraceContextFormat().extract(data.spanToDecodeText, textGetter);
}
示例25
@Override
public <C /*>>> extends @NonNull Object*/> void inject(
SpanContext spanContext, C carrier, Setter<C> setter) {
checkNotNull(spanContext, "spanContext");
checkNotNull(setter, "setter");
checkNotNull(carrier, "carrier");
char[] chars = new char[TRACEPARENT_HEADER_SIZE];
chars[0] = VERSION.charAt(0);
chars[1] = VERSION.charAt(1);
chars[2] = TRACEPARENT_DELIMITER;
spanContext.getTraceId().copyLowerBase16To(chars, TRACE_ID_OFFSET);
chars[SPAN_ID_OFFSET - 1] = TRACEPARENT_DELIMITER;
spanContext.getSpanId().copyLowerBase16To(chars, SPAN_ID_OFFSET);
chars[TRACE_OPTION_OFFSET - 1] = TRACEPARENT_DELIMITER;
spanContext.getTraceOptions().copyLowerBase16To(chars, TRACE_OPTION_OFFSET);
setter.put(carrier, TRACEPARENT, new String(chars));
List<Tracestate.Entry> entries = spanContext.getTracestate().getEntries();
if (entries.isEmpty()) {
// No need to add an empty "tracestate" header.
return;
}
StringBuilder stringBuilder = new StringBuilder(TRACESTATE_MAX_SIZE);
for (Tracestate.Entry entry : entries) {
if (stringBuilder.length() != 0) {
stringBuilder.append(TRACESTATE_ENTRY_DELIMITER);
}
stringBuilder
.append(entry.getKey())
.append(TRACESTATE_KEY_VALUE_DELIMITER)
.append(entry.getValue());
}
setter.put(carrier, TRACESTATE, stringBuilder.toString());
}
示例26
@Test
public void generateSpan_ClientKind() {
SpanData data =
SpanData.create(
SpanContext.create(
TraceId.fromLowerBase16(TRACE_ID),
SpanId.fromLowerBase16(SPAN_ID),
TraceOptions.builder().setIsSampled(true).build()),
SpanId.fromLowerBase16(PARENT_SPAN_ID),
true, /* hasRemoteParent */
"SpanName", /* name */
Kind.CLIENT, /* kind */
Timestamp.create(1505855794, 194009601) /* startTimestamp */,
Attributes.create(attributes, 0 /* droppedAttributesCount */),
TimedEvents.create(annotations, 0 /* droppedEventsCount */),
TimedEvents.create(messageEvents, 0 /* droppedEventsCount */),
Links.create(Collections.<Link>emptyList(), 0 /* droppedLinksCount */),
null, /* childSpanCount */
Status.OK,
Timestamp.create(1505855799, 465726528) /* endTimestamp */);
assertThat(InstanaExporterHandler.convertToJson(Collections.singletonList(data)))
.isEqualTo(
"["
+ "{"
+ "\"spanId\":\"9cc1e3049173be09\","
+ "\"traceId\":\"d239036e7d5cec11\","
+ "\"parentId\":\"8b03ab423da481c5\","
+ "\"timestamp\":1505855794194,"
+ "\"duration\":5271,"
+ "\"name\":\"SpanName\","
+ "\"type\":\"EXIT\","
+ "\"data\":"
+ "{\"http.url\":\"http://localhost/foo\"}"
+ "}"
+ "]");
}
示例27
@Override
public SpanContext fromByteArray(byte[] bytes) throws SpanContextParseException {
checkNotNull(bytes, "bytes");
if (bytes.length == 0 || bytes[0] != VERSION_ID) {
throw new SpanContextParseException("Unsupported version.");
}
if (bytes.length < REQUIRED_FORMAT_LENGTH) {
throw new SpanContextParseException("Invalid input: truncated");
}
// TODO: the following logic assumes that fields are written in ID order. The spec does not say
// that. If it decides not to, this logic would need to be more like a loop
TraceId traceId;
SpanId spanId;
TraceOptions traceOptions = TraceOptions.DEFAULT;
int pos = 1;
if (bytes[pos] == TRACE_ID_FIELD_ID) {
traceId = TraceId.fromBytes(bytes, pos + ID_SIZE);
pos += ID_SIZE + TraceId.SIZE;
} else {
// TODO: update the spec to suggest that the trace ID is not actually optional
throw new SpanContextParseException("Invalid input: expected trace ID at offset " + pos);
}
if (bytes[pos] == SPAN_ID_FIELD_ID) {
spanId = SpanId.fromBytes(bytes, pos + ID_SIZE);
pos += ID_SIZE + SpanId.SIZE;
} else {
// TODO: update the spec to suggest that the span ID is not actually optional.
throw new SpanContextParseException("Invalid input: expected span ID at offset " + pos);
}
// Check to see if we are long enough to include an options field, and also that the next field
// is an options field. Per spec we simply stop parsing at first unknown field instead of
// failing.
if (bytes.length > pos && bytes[pos] == TRACE_OPTION_FIELD_ID) {
if (bytes.length < ALL_FORMAT_LENGTH) {
throw new SpanContextParseException("Invalid input: truncated");
}
traceOptions = TraceOptions.fromByte(bytes[pos + ID_SIZE]);
}
return SpanContext.create(traceId, spanId, traceOptions, TRACESTATE_DEFAULT);
}
示例28
/**
* Creates and starts a span with the given configuration.
*
* @param context supplies the trace_id and span_id for the newly started span.
* @param name the displayed name for the new span.
* @param parentSpanId the span_id of the parent span, or null if the new span is a root span.
* @param hasRemoteParent {@code true} if the parentContext is remote. {@code null} if this is a
* root span.
* @param traceParams trace parameters like sampler and probability.
* @param startEndHandler handler called when the span starts and ends.
* @param timestampConverter null if the span is a root span or the parent is not sampled. If the
* parent is sampled, we should use the same converter to ensure ordering between tracing
* events.
* @param clock the clock used to get the time.
* @return a new and started span.
*/
@VisibleForTesting
public static RecordEventsSpanImpl startSpan(
SpanContext context,
String name,
@Nullable Kind kind,
@Nullable SpanId parentSpanId,
@Nullable Boolean hasRemoteParent,
TraceParams traceParams,
StartEndHandler startEndHandler,
@Nullable TimestampConverter timestampConverter,
Clock clock) {
RecordEventsSpanImpl span =
new RecordEventsSpanImpl(
context,
name,
kind,
parentSpanId,
hasRemoteParent,
traceParams,
startEndHandler,
timestampConverter,
clock);
// Call onStart here instead of calling in the constructor to make sure the span is completely
// initialized.
startEndHandler.onStart(span);
return span;
}
示例29
@Test
public void startRemoteSpanInvalidParent() {
RecordEventsSpanImpl span =
(RecordEventsSpanImpl)
SpanBuilderImpl.createWithRemoteParent(
SPAN_NAME, SpanContext.INVALID, spanBuilderOptions)
.startSpan();
assertThat(span.getContext().isValid()).isTrue();
assertThat(span.getOptions().contains(Options.RECORD_EVENTS)).isTrue();
assertThat(span.getContext().getTraceOptions().isSampled()).isTrue();
SpanData spanData = span.toSpanData();
assertThat(spanData.getParentSpanId()).isNull();
assertThat(spanData.getHasRemoteParent()).isNull();
}
示例30
private SpanBuilderImpl(
String name,
@Nullable SpanContext remoteParentSpanContext,
@Nullable Span parent,
Options options) {
this.name = checkNotNull(name, "name");
this.parent = parent;
this.remoteParentSpanContext = remoteParentSpanContext;
this.options = options;
}