io.grpc.ForwardingClientCallListener.SimpleForwardingClientCallListener#io.opencensus.trace.Status源码实例Demo

下面列出了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());
}
 
源代码5 项目: opencensus-java   文件: Handler.java
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();
  }
}
 
源代码6 项目: opencensus-java   文件: CensusSpringAspectTest.java
@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");
}
 
源代码7 项目: opencensus-java   文件: TraceStrategyImpl.java
@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.
  }
}
 
源代码8 项目: opencensus-java   文件: MetricReader.java
/**
 * 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)));
    }
  }
}
 
源代码10 项目: opencensus-java   文件: JsonConversionUtilsTest.java
@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);
}
 
源代码11 项目: heroic   文件: BigtableMutatorImpl.java
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;
        }
    }
}
 
源代码12 项目: grpc-nebula-java   文件: CensusTracingModule.java
private static EndSpanOptions createEndSpanOptions(
    io.grpc.Status status, boolean sampledToLocalTracing) {
  return EndSpanOptions.builder()
      .setStatus(convertStatus(status))
      .setSampleToLocalSpanStore(sampledToLocalTracing)
      .build();
}
 
源代码13 项目: grpc-nebula-java   文件: CensusTracingModule.java
/**
 * 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));
}
 
源代码14 项目: grpc-nebula-java   文件: CensusTracingModule.java
/**
 * 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));
}
 
源代码15 项目: grpc-nebula-java   文件: CensusTracingModule.java
@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);
    }
  };
}
 
源代码16 项目: meghanada-server   文件: TelemetryUtils.java
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));
}
 
源代码17 项目: opencensus-java   文件: QuickStart.java
/** 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));
}
 
源代码18 项目: opencensus-java   文件: HelloWorldServer.java
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);
  }
}
 
源代码19 项目: opencensus-java   文件: SpanData.java
/**
 * 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 项目: opencensus-java   文件: RecordEventsSpanImpl.java
@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);
    }
  }
}
 
源代码22 项目: grpc-java   文件: CensusTracingModule.java
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();
}
 
源代码27 项目: opencensus-java   文件: PrometheusStatsCollector.java
@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)));
    }
  }
}
 
源代码28 项目: grpc-java   文件: CensusTracingModule.java
/**
 * 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\"}"
              + "}"
              + "]");
}