use of com.newrelic.trace.v1.V1 in project newrelic-java-agent by newrelic.
the class ChannelManager method getSpanObserver.
/**
* Obtain a span observer. Creates a channel if one is not open. Creates a span observer if one
* does not exist. If the channel has been shutdown and is backing off via
* {@link #shutdownChannelAndBackoff(int)}, awaits the backoff period before recreating the channel.
*
* @return a span observer
*/
ClientCallStreamObserver<V1.Span> getSpanObserver() {
// Obtain the lock, and await the backoff if in progress
CountDownLatch latch;
synchronized (lock) {
latch = backoffLatch;
}
if (latch != null) {
try {
logger.log(Level.FINE, "Awaiting backoff.");
latch.await();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Thread interrupted while awaiting backoff.");
}
}
// Obtain the lock, and possibly recreate the channel or the span observer
synchronized (lock) {
if (isShutdownForever) {
throw new RuntimeException("No longer accepting connections to gRPC.");
}
if (managedChannel == null) {
logger.log(Level.FINE, "Creating gRPC channel.");
managedChannel = buildChannel();
}
if (recreateSpanObserver) {
if (spanObserver != null) {
logger.log(Level.FINE, "Cancelling and recreating gRPC span observer.");
spanObserver.cancel("CLOSING_CONNECTION", new ChannelClosingException());
}
IngestServiceStub ingestServiceStub = buildStub(managedChannel);
ResponseObserver responseObserver = buildResponseObserver();
spanObserver = (ClientCallStreamObserver<V1.Span>) ingestServiceStub.recordSpan(responseObserver);
aggregator.incrementCounter("Supportability/InfiniteTracing/Connect");
recreateSpanObserver = false;
}
return spanObserver;
}
}
use of com.newrelic.trace.v1.V1 in project newrelic-java-agent by newrelic.
the class SpanEventSenderTest method writeToObserver_RethrowsException.
@Test
void writeToObserver_RethrowsException() {
doThrow(new RuntimeException("Error!")).when(observer).onNext(ArgumentMatchers.<V1.Span>any());
assertThrows(RuntimeException.class, new Executable() {
@Override
public void execute() {
target.writeToObserver(observer, V1.Span.newBuilder().build());
}
});
verify(aggregator, never()).incrementCounter(anyString());
}
use of com.newrelic.trace.v1.V1 in project newrelic-java-agent by newrelic.
the class SpanEventSender method pollAndWrite.
@VisibleForTesting
void pollAndWrite() {
// Get stream observer
ClientCallStreamObserver<V1.Span> observer = channelManager.getSpanObserver();
// Confirm the observer is ready
if (!awaitReadyObserver(observer)) {
return;
}
// Poll queue for span
SpanEvent span = pollSafely();
if (span == null) {
return;
}
// Convert span and write to observer
V1.Span convertedSpan = SpanConverter.convert(span);
writeToObserver(observer, convertedSpan);
}
use of com.newrelic.trace.v1.V1 in project newrelic-java-agent by newrelic.
the class ChannelManagerTest method getSpanObserver_AwaitsBackoff.
@Test
@Timeout(15)
void getSpanObserver_AwaitsBackoff() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(2);
// Submit a task to initiate a backoff
final AtomicLong backoffCompletedAt = new AtomicLong();
Future<?> backoffFuture = executorService.submit(new Runnable() {
@Override
public void run() {
target.shutdownChannelAndBackoff(5);
backoffCompletedAt.set(System.currentTimeMillis());
}
});
// Obtain a span observer in another thread, confirming it waits for the backoff to complete
final AtomicLong getSpanObserverCompletedAt = new AtomicLong();
Future<ClientCallStreamObserver<V1.Span>> futureSpanObserver = executorService.submit(new Callable<ClientCallStreamObserver<V1.Span>>() {
@Override
public ClientCallStreamObserver<V1.Span> call() {
try {
// Wait for the backoff task to have initiated backoff
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException("Thread interrupted while sleeping.");
}
ClientCallStreamObserver<V1.Span> response = target.getSpanObserver();
getSpanObserverCompletedAt.set(System.currentTimeMillis());
return response;
}
});
backoffFuture.get();
assertEquals(spanObserver, futureSpanObserver.get());
assertTrue(backoffCompletedAt.get() > 0);
assertTrue(getSpanObserverCompletedAt.get() > 0);
assertTrue(getSpanObserverCompletedAt.get() >= backoffCompletedAt.get());
}
use of com.newrelic.trace.v1.V1 in project newrelic-java-agent by newrelic.
the class SpanConverterTest method convert_Valid.
@Test
void convert_Valid() throws IOException {
SpanEvent spanEvent = buildSpanEvent();
V1.Span result = SpanConverter.convert(spanEvent);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
result.writeTo(baos);
V1.Span deserialized = V1.Span.parseFrom(baos.toByteArray());
assertEquals("abc123", deserialized.getTraceId());
assertEquals("abc123", deserialized.getIntrinsicsOrThrow("traceId").getStringValue());
assertEquals("my app", deserialized.getIntrinsicsOrThrow("appName").getStringValue());
assertEquals("value", deserialized.getIntrinsicsOrThrow("intrStr").getStringValue());
assertEquals(12345, deserialized.getIntrinsicsOrThrow("intrInt").getIntValue());
assertEquals(3.14, deserialized.getIntrinsicsOrThrow("intrFloat").getDoubleValue(), 0.00001);
assertTrue(deserialized.getIntrinsicsOrThrow("intrBool").getBoolValue());
assertFalse(deserialized.containsIntrinsics("intrOther"));
}
Aggregations