下面列出了io.grpc.ForwardingClientCallListener.SimpleForwardingClientCallListener#io.opencensus.trace.Status 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
private static void doWork(int iteration, int jobs, LongGauge gauge) {
String childSpanName = "iteration-" + iteration;
LabelValue value = LabelValue.create(childSpanName);
LongPoint point = gauge.getOrCreateTimeSeries(Collections.singletonList(value));
try (Scope scope = tracer.spanBuilder(childSpanName).startScopedSpan()) {
for (int i = 0; i < jobs; i++) {
String grandChildSpanName = childSpanName + "-job-" + i;
try (Scope childScope = tracer.spanBuilder(grandChildSpanName).startScopedSpan()) {
point.set(jobs - i);
String line = generateRandom(random.nextInt(128));
processLine(line);
recordStat(M_LINES_IN, 1L);
recordStat(M_LINE_LENGTHS, (long) line.length());
} catch (Exception e) {
tracer.getCurrentSpan().setStatus(Status.INTERNAL.withDescription(e.toString()));
}
}
}
}
@Test
public void status_ViaSetStatus() {
RecordEventsSpanImpl span =
RecordEventsSpanImpl.startSpan(
spanContext,
SPAN_NAME,
null,
parentSpanId,
false,
TraceParams.DEFAULT,
startEndHandler,
timestampConverter,
testClock);
Mockito.verify(startEndHandler, Mockito.times(1)).onStart(span);
testClock.advanceTime(Duration.create(0, 100));
assertThat(span.getStatus()).isEqualTo(Status.OK);
span.setStatus(Status.CANCELLED);
assertThat(span.getStatus()).isEqualTo(Status.CANCELLED);
span.end();
assertThat(span.getStatus()).isEqualTo(Status.CANCELLED);
}
@Test
public void status_ViaEndSpanOptions() {
RecordEventsSpanImpl span =
RecordEventsSpanImpl.startSpan(
spanContext,
SPAN_NAME,
null,
parentSpanId,
false,
TraceParams.DEFAULT,
startEndHandler,
timestampConverter,
testClock);
Mockito.verify(startEndHandler, Mockito.times(1)).onStart(span);
testClock.advanceTime(Duration.create(0, 100));
assertThat(span.getStatus()).isEqualTo(Status.OK);
span.setStatus(Status.CANCELLED);
assertThat(span.getStatus()).isEqualTo(Status.CANCELLED);
span.end(EndSpanOptions.builder().setStatus(Status.ABORTED).build());
assertThat(span.getStatus()).isEqualTo(Status.ABORTED);
}
@Test
public void getErrorSampledSpans_MaxSpansToReturn() {
RecordEventsSpanImpl span1 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span1.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
// Advance time to allow other spans to be sampled.
testClock.advanceTime(Duration.create(5, 0));
RecordEventsSpanImpl span2 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span2.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
Collection<SpanData> samples =
sampleStore.getErrorSampledSpans(
ErrorFilter.create(REGISTERED_SPAN_NAME, CanonicalCode.CANCELLED, 1));
assertThat(samples.size()).isEqualTo(1);
// No order guaranteed so one of the spans should be in the list.
assertThat(samples).containsAnyOf(span1.toSpanData(), span2.toSpanData());
}
static Object proceed(
ProceedingJoinPoint call, Tracer tracer, String spanName, String... annotations)
throws Throwable {
Scope scope = tracer.spanBuilder(spanName).startScopedSpan();
try {
for (String annotation : annotations) {
tracer.getCurrentSpan().addAnnotation(annotation);
}
return call.proceed();
} catch (Throwable t) {
Map<String, AttributeValue> attributes = new HashMap<String, AttributeValue>();
String message = t.getMessage();
attributes.put(
"message", AttributeValue.stringAttributeValue(message == null ? "null" : message));
attributes.put("type", AttributeValue.stringAttributeValue(t.getClass().toString()));
Span span = tracer.getCurrentSpan();
span.addAnnotation("error", attributes);
span.setStatus(Status.UNKNOWN);
throw t;
} finally {
scope.close();
}
}
@Test
public void handlesException() {
// When
Sample sample = (Sample) context.getBean("sample");
try {
sample.boom();
} catch (Exception ignored) {
// ok
}
// Then
List<SpanData> spanList = handler.waitForExport(1);
assertThat(spanList).isNotNull();
assertThat(spanList.size()).isEqualTo(1);
SpanData spanData = spanList.get(0);
assertThat(spanData.getName()).isEqualTo("boom");
assertThat(spanData.getStatus()).isEqualTo(Status.UNKNOWN);
SpanData.TimedEvents<Annotation> annotations = spanData.getAnnotations();
assertThat(annotations).isNotNull();
List<SpanData.TimedEvent<Annotation>> events = annotations.getEvents();
assertThat(events.size()).isEqualTo(1);
assertThat(events.get(0).getEvent().getDescription()).isEqualTo("error");
}
@Override
public void endScope(Closeable scope, @Nullable Throwable throwable) {
checkNotNull(scope, "scope");
if (throwable != null) {
Tracing.getTracer()
.getCurrentSpan()
.setStatus(
Status.UNKNOWN.withDescription(
throwable.getMessage() == null
? throwable.getClass().getSimpleName()
: throwable.getMessage()));
}
try {
scope.close();
} catch (IOException ex) {
// Ignore.
}
}
/**
* Reads the metrics from the {@link MetricProducerManager} and exports them to the {@code
* metricExporter}.
*
* @param metricExporter the exporter called to export the metrics read.
* @since 0.19
*/
public void readAndExport(MetricExporter metricExporter) {
Span span =
tracer
.spanBuilder(spanName)
.setRecordEvents(true)
.setSampler(probabilitySampler)
.startSpan();
Scope scope = tracer.withSpan(span);
try {
ArrayList<Metric> metricsList = new ArrayList<>();
for (MetricProducer metricProducer : metricProducerManager.getAllMetricProducer()) {
metricsList.addAll(metricProducer.getMetrics());
}
metricExporter.export(metricsList);
} catch (Throwable e) {
logger.log(Level.WARNING, "Exception thrown by the metrics exporter.", e);
span.setStatus(
Status.UNKNOWN.withDescription("Exception when export metrics: " + exceptionMessage(e)));
} finally {
scope.close();
span.end();
}
}
@Override
public void export(Collection<Metric> metrics) {
samples.ensureCapacity(metrics.size());
for (Metric metric : metrics) {
try {
samples.add(
PrometheusExportUtils.createDescribableMetricFamilySamples(
metric.getMetricDescriptor(), namespace));
} catch (Throwable e) {
logger.log(Level.WARNING, "Exception thrown when describing metrics.", e);
tracer
.getCurrentSpan()
.setStatus(
Status.UNKNOWN.withDescription(
"Exception thrown when describing Prometheus Metrics: "
+ exceptionMessage(e)));
}
}
}
@Before
public void setUp() {
SpanData spanData =
SpanData.create(
SpanContext.create(
TraceId.fromLowerBase16(SAMPLE_TRACE_ID),
SpanId.fromLowerBase16(SAMPLE_SPAN_ID),
SAMPLE_TRACE_OPTION,
SAMPLE_TRACE_STATE),
SpanId.fromLowerBase16(SAMPLE_PARENT_SPAN_ID),
true,
"SpanName",
null,
Timestamp.create(155196336, 194009601),
Attributes.create(attributes, 0),
TimedEvents.create(annotations, 0),
TimedEvents.create(messageEvents, 0),
Links.create(Collections.<Link>emptyList(), 0),
null,
Status.OK,
Timestamp.create(155296336, 465726528));
spanDataList = new ArrayList<SpanData>();
spanDataList.add(spanData);
}
private BulkMutation getOrAddBulkMutation(String tableName) {
final Span span = tracer.spanBuilder("BigtableMutator.getOrAddBulkMutation").startSpan();
try (Scope ws = tracer.withSpan(span)) {
span.addAnnotation("Acquiring lock");
synchronized (tableAccessLock) {
span.addAnnotation("Lock acquired");
if (tableToBulkMutation.containsKey(tableName)) {
span.setStatus(Status.ALREADY_EXISTS.withDescription("Mutation exists in map"));
span.end();
return tableToBulkMutation.get(tableName);
}
final BulkMutation bulkMutation = session.createBulkMutation(
session
.getOptions()
.getInstanceName()
.toTableName(tableName));
tableToBulkMutation.put(tableName, bulkMutation);
span.end();
return bulkMutation;
}
}
}
private static EndSpanOptions createEndSpanOptions(
io.grpc.Status status, boolean sampledToLocalTracing) {
return EndSpanOptions.builder()
.setStatus(convertStatus(status))
.setSampleToLocalSpanStore(sampledToLocalTracing)
.build();
}
/**
* Record a finished call and mark the current time as the end time.
*
* <p>Can be called from any thread without synchronization. Calling it the second time or more
* is a no-op.
*/
void callEnded(io.grpc.Status status) {
if (callEndedUpdater != null) {
if (callEndedUpdater.getAndSet(this, 1) != 0) {
return;
}
} else {
if (callEnded != 0) {
return;
}
callEnded = 1;
}
span.end(createEndSpanOptions(status, isSampledToLocalTracing));
}
/**
* Record a finished stream and mark the current time as the end time.
*
* <p>Can be called from any thread without synchronization. Calling it the second time or more
* is a no-op.
*/
@Override
public void streamClosed(io.grpc.Status status) {
if (streamClosedUpdater != null) {
if (streamClosedUpdater.getAndSet(this, 1) != 0) {
return;
}
} else {
if (streamClosed != 0) {
return;
}
streamClosed = 1;
}
span.end(createEndSpanOptions(status, isSampledToLocalTracing));
}
@Override
public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
// New RPCs on client-side inherit the tracing context from the current Context.
// Safe usage of the unsafe trace API because CONTEXT_SPAN_KEY.get() returns the same value
// as Tracer.getCurrentSpan() except when no value available when the return value is null
// for the direct access and BlankSpan when Tracer API is used.
final ClientCallTracer tracerFactory = newClientCallTracer(CONTEXT_SPAN_KEY.get(), method);
ClientCall<ReqT, RespT> call =
next.newCall(
method,
callOptions.withStreamTracerFactory(tracerFactory));
return new SimpleForwardingClientCall<ReqT, RespT>(call) {
@Override
public void start(Listener<RespT> responseListener, Metadata headers) {
delegate().start(
new SimpleForwardingClientCallListener<RespT>(responseListener) {
@Override
public void onClose(io.grpc.Status status, Metadata trailers) {
tracerFactory.callEnded(status);
super.onClose(status, trailers);
}
},
headers);
}
};
}
public static void setStatusINTERNAL(String message) {
// add error info annotation
Span current = tracer.getCurrentSpan();
current.addAnnotation(getBaseAnnotation());
HashMap<String, AttributeValue> newMap = new HashMap<>(javaAttributeMap);
newMap.put("java.vm.memory", AttributeValue.stringAttributeValue(Config.getMemoryString()));
Annotation vmAnno = Annotation.fromDescriptionAndAttributes("java.vm properties", newMap);
current.addAnnotation(vmAnno);
Annotation osAnno = Annotation.fromDescriptionAndAttributes("os properties", osAttributeMap);
current.addAnnotation(osAnno);
TelemetryUtils.setStatus(Status.INTERNAL.withDescription(message));
}
/** Main launcher for the QuickStart example. */
public static void main(String[] args) throws InterruptedException {
TagContextBuilder tagContextBuilder =
tagger.currentBuilder().put(FRONTEND_KEY, TagValue.create("mobile-ios9.3.5"));
SpanBuilder spanBuilder =
tracer
.spanBuilder("my.org/ProcessVideo")
.setRecordEvents(true)
.setSampler(Samplers.alwaysSample());
viewManager.registerView(VIDEO_SIZE_VIEW);
LoggingTraceExporter.register();
// Process video.
// Record the processed video size.
try (Scope scopedTags = tagContextBuilder.buildScoped();
Scope scopedSpan = spanBuilder.startScopedSpan()) {
tracer.getCurrentSpan().addAnnotation("Start processing video.");
// Sleep for [0,10] milliseconds to fake work.
Thread.sleep(new Random().nextInt(10) + 1);
statsRecorder.newMeasureMap().put(VIDEO_SIZE, 25 * MiB).record();
tracer.getCurrentSpan().addAnnotation("Finished processing video.");
} catch (Exception e) {
tracer.getCurrentSpan().addAnnotation("Exception thrown when processing video.");
tracer.getCurrentSpan().setStatus(Status.UNKNOWN);
logger.severe(e.getMessage());
}
logger.info("Wait longer than the reporting duration...");
// Wait for a duration longer than reporting duration (5s) to ensure spans are exported.
// TODO(songya): remove the gap once we add a shutdown hook for exporting unflushed spans.
Thread.sleep(5100);
ViewData viewData = viewManager.getView(VIDEO_SIZE_VIEW_NAME);
logger.info(
String.format("Recorded stats for %s:\n %s", VIDEO_SIZE_VIEW_NAME.asString(), viewData));
}
private static void sleepFor(int milliseconds) {
try {
Thread.sleep(milliseconds);
} catch (InterruptedException e) {
Span span = tracer.getCurrentSpan();
span.addAnnotation("Exception thrown when performing work " + e.getMessage());
span.setStatus(Status.UNKNOWN);
}
}
/**
* 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);
}
@Override
public void setStatus(Status status) {
Preconditions.checkNotNull(status, "status");
synchronized (this) {
if (hasBeenEnded) {
logger.log(Level.FINE, "Calling setStatus() on an ended Span.");
return;
}
this.status = status;
}
}
private void considerForSampling(RecordEventsSpanImpl span) {
Status status = span.getStatus();
// Null status means running Span, this should not happen in production, but the library
// should not crash because of this.
if (status != null) {
Bucket bucket =
status.isOk()
? getLatencyBucket(span.getLatencyNs())
: getErrorBucket(status.getCanonicalCode());
// If unable to find the bucket, ignore this Span.
if (bucket != null) {
bucket.considerForSampling(span);
}
}
}
private static EndSpanOptions createEndSpanOptions(
io.grpc.Status status, boolean sampledToLocalTracing) {
return EndSpanOptions.builder()
.setStatus(convertStatus(status))
.setSampleToLocalSpanStore(sampledToLocalTracing)
.build();
}
@Test
public void getErrorSampledSpans() {
RecordEventsSpanImpl span = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
Collection<SpanData> samples =
sampleStore.getErrorSampledSpans(
ErrorFilter.create(REGISTERED_SPAN_NAME, CanonicalCode.CANCELLED, 0));
assertThat(samples.size()).isEqualTo(1);
assertThat(samples.contains(span.toSpanData())).isTrue();
}
@Test
public void getErrorSampledSpans_NullCode() {
RecordEventsSpanImpl span1 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span1.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
RecordEventsSpanImpl span2 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span2.end(EndSpanOptions.builder().setStatus(Status.UNKNOWN).build());
Collection<SpanData> samples =
sampleStore.getErrorSampledSpans(ErrorFilter.create(REGISTERED_SPAN_NAME, null, 0));
assertThat(samples.size()).isEqualTo(2);
assertThat(samples).containsExactly(span1.toSpanData(), span2.toSpanData());
}
@Test
public void getErrorSampledSpans_NullCode_MaxSpansToReturn() {
RecordEventsSpanImpl span1 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span1.end(EndSpanOptions.builder().setStatus(Status.CANCELLED).build());
RecordEventsSpanImpl span2 = createSampledSpan(REGISTERED_SPAN_NAME);
testClock.advanceTime(Duration.create(0, 1000));
span2.end(EndSpanOptions.builder().setStatus(Status.UNKNOWN).build());
Collection<SpanData> samples =
sampleStore.getErrorSampledSpans(ErrorFilter.create(REGISTERED_SPAN_NAME, null, 1));
assertThat(samples.size()).isEqualTo(1);
assertThat(samples).containsAnyOf(span1.toSpanData(), span2.toSpanData());
}
@Test
public void doNotCrash() {
Map<String, AttributeValue> attributes = new HashMap<String, AttributeValue>();
attributes.put(
"MyStringAttributeKey", AttributeValue.stringAttributeValue("MyStringAttributeValue"));
Map<String, AttributeValue> multipleAttributes = new HashMap<String, AttributeValue>();
multipleAttributes.put(
"MyStringAttributeKey", AttributeValue.stringAttributeValue("MyStringAttributeValue"));
multipleAttributes.put("MyBooleanAttributeKey", AttributeValue.booleanAttributeValue(true));
multipleAttributes.put("MyLongAttributeKey", AttributeValue.longAttributeValue(123));
// Tests only that all the methods are not crashing/throwing errors.
noRecordEventsSpan.putAttribute(
"MyStringAttributeKey2", AttributeValue.stringAttributeValue("MyStringAttributeValue2"));
noRecordEventsSpan.addAttributes(attributes);
noRecordEventsSpan.addAttributes(multipleAttributes);
noRecordEventsSpan.addAnnotation("MyAnnotation");
noRecordEventsSpan.addAnnotation("MyAnnotation", attributes);
noRecordEventsSpan.addAnnotation("MyAnnotation", multipleAttributes);
noRecordEventsSpan.addAnnotation(Annotation.fromDescription("MyAnnotation"));
noRecordEventsSpan.addNetworkEvent(NetworkEvent.builder(NetworkEvent.Type.SENT, 1L).build());
noRecordEventsSpan.addMessageEvent(MessageEvent.builder(MessageEvent.Type.SENT, 1L).build());
noRecordEventsSpan.addLink(
Link.fromSpanContext(SpanContext.INVALID, Link.Type.CHILD_LINKED_SPAN));
noRecordEventsSpan.setStatus(Status.OK);
noRecordEventsSpan.end(EndSpanOptions.DEFAULT);
noRecordEventsSpan.end();
}
@Override
public void export(Collection<Metric> metrics) {
samples.ensureCapacity(metrics.size());
for (Metric metric : metrics) {
MetricDescriptor metricDescriptor = metric.getMetricDescriptor();
if (containsDisallowedLeLabelForHistogram(
convertToLabelNames(metricDescriptor.getLabelKeys()),
getType(metricDescriptor.getType()))
|| containsDisallowedQuantileLabelForSummary(
convertToLabelNames(metricDescriptor.getLabelKeys()),
getType(metricDescriptor.getType()))) {
// silently skip Distribution metricdescriptor with "le" label key and Summary
// metricdescriptor with "quantile" label key
continue;
}
try {
samples.add(PrometheusExportUtils.createMetricFamilySamples(metric, namespace));
} catch (Throwable e) {
logger.log(Level.WARNING, "Exception thrown when collecting metric samples.", e);
tracer
.getCurrentSpan()
.setStatus(
Status.UNKNOWN.withDescription(
"Exception thrown when collecting Prometheus Metric Samples: "
+ exceptionMessage(e)));
}
}
}
/**
* Record a finished stream and mark the current time as the end time.
*
* <p>Can be called from any thread without synchronization. Calling it the second time or more
* is a no-op.
*/
@Override
public void streamClosed(io.grpc.Status status) {
if (streamClosedUpdater != null) {
if (streamClosedUpdater.getAndSet(this, 1) != 0) {
return;
}
} else {
if (streamClosed != 0) {
return;
}
streamClosed = 1;
}
span.end(createEndSpanOptions(status, isSampledToLocalTracing));
}
@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\"}"
+ "}"
+ "]");
}
@Test
public void generateSpan_ServerKind() {
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.SERVER, /* 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\"}"
+ "}"
+ "]");
}