/** Builds an async reporter that encodes arbitrary spans as they are reported. */ public <S> AsyncReporter<S> build(Encoder<S> encoder) { if (encoder == null) throw new NullPointerException("encoder == null"); if (encoder.encoding() != sender.encoding()) { throw new IllegalArgumentException(String.format( "Encoder doesn't match Sender: %s %s", encoder.encoding(), sender.encoding())); } final BoundedAsyncReporter<S> result = new BoundedAsyncReporter<>(this, encoder); if (messageTimeoutNanos > 0) { // Start a thread that flushes the queue in a loop. final BufferNextMessage consumer = new BufferNextMessage(sender, messageMaxBytes, messageTimeoutNanos); final Thread flushThread = new Thread(() -> { try { while (!result.closed.get()) { result.flush(consumer); } } finally { for (byte[] next : consumer.drain()) result.pending.offer(next); result.close.countDown(); } }, "AsyncReporter(" + sender + ")"); flushThread.setDaemon(true); flushThread.start(); } return result; } }
/** Returns true if the was encoded and accepted onto the queue. */ @Override public void report(S span) { if (span == null) throw new NullPointerException("span == null"); metrics.incrementSpans(1); byte[] next = encoder.encode(span); int messageSizeOfNextSpan = sender.messageSizeInBytes(Collections.singletonList(next)); metrics.incrementSpanBytes(next.length); if (closed.get() || // don't enqueue something larger than we can drain messageSizeOfNextSpan > messageMaxBytes || !pending.offer(next)) { metrics.incrementSpansDropped(1); } }