Skip to content
This repository was archived by the owner on Jul 1, 2022. It is now read-only.

Commit e1f8037

Browse files
authored
Log SenderExceptions the first time they occur in a row (#729)
Closes #728 Signed-off-by: Phillip Schichtel <[email protected]>
1 parent 27059eb commit e1f8037

File tree

2 files changed

+109
-9
lines changed

2 files changed

+109
-9
lines changed

jaeger-core/src/main/java/io/jaegertracing/internal/reporters/RemoteReporter.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import io.jaegertracing.internal.senders.SenderResolver;
2222
import io.jaegertracing.spi.Reporter;
2323
import io.jaegertracing.spi.Sender;
24+
import java.util.HashSet;
25+
import java.util.Set;
2426
import java.util.Timer;
2527
import java.util.TimerTask;
2628
import java.util.concurrent.ArrayBlockingQueue;
@@ -166,17 +168,29 @@ public void execute() throws SenderException {
166168
@ToString
167169
class QueueProcessor implements Runnable {
168170
private boolean open = true;
171+
private final Set<Class<?>> commandFailedBefore = new HashSet<Class<?>>();
169172

170173
@Override
171174
public void run() {
172175
while (open) {
173176
try {
174177
RemoteReporter.Command command = commandQueue.take();
178+
Class<? extends Command> commandClass = command.getClass();
179+
boolean failedBefore = commandFailedBefore.contains(commandClass);
175180

176181
try {
177182
command.execute();
183+
if (failedBefore) {
184+
log.info(commandClass.getSimpleName() + " is working again!");
185+
commandFailedBefore.remove(commandClass);
186+
}
178187
} catch (SenderException e) {
179188
metrics.reporterFailure.inc(e.getDroppedSpanCount());
189+
if (!failedBefore) {
190+
log.warn(commandClass.getSimpleName()
191+
+ " execution failed! Repeated errors of this command will not be logged.", e);
192+
commandFailedBefore.add(commandClass);
193+
}
180194
}
181195
} catch (Exception e) {
182196
log.error("QueueProcessor error:", e);

jaeger-core/src/test/java/io/jaegertracing/internal/reporters/RemoteReporterTest.java

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import static org.junit.Assert.assertThat;
2323
import static org.junit.Assert.assertTrue;
2424
import static org.mockito.ArgumentMatchers.argThat;
25+
import static org.mockito.ArgumentMatchers.nullable;
26+
import static org.mockito.Mockito.doAnswer;
2527
import static org.mockito.Mockito.mock;
2628
import static org.mockito.Mockito.verify;
2729
import static org.mockito.Mockito.when;
@@ -39,15 +41,21 @@
3941
import io.jaegertracing.spi.Reporter;
4042
import io.jaegertracing.spi.Sender;
4143
import java.util.ArrayList;
44+
import java.util.Collections;
4245
import java.util.List;
4346
import java.util.concurrent.CountDownLatch;
4447
import java.util.concurrent.CyclicBarrier;
4548
import java.util.concurrent.TimeUnit;
4649
import java.util.concurrent.atomic.AtomicBoolean;
50+
import java.util.concurrent.atomic.AtomicInteger;
51+
import java.util.concurrent.atomic.AtomicReference;
52+
import java.util.function.Consumer;
53+
4754
import org.junit.Before;
4855
import org.junit.Ignore;
4956
import org.junit.Test;
5057
import org.mockito.ArgumentMatcher;
58+
import org.mockito.ArgumentMatchers;
5159
import org.slf4j.LoggerFactory;
5260

5361
public class RemoteReporterTest {
@@ -215,15 +223,8 @@ public void testCloseWhenQueueFull() {
215223
@Test
216224
public void testCloseLogSenderException() throws SenderException {
217225

218-
// set up mocking
219-
ch.qos.logback.classic.Logger root =
220-
(ch.qos.logback.classic.Logger) LoggerFactory
221-
.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
222-
223-
@SuppressWarnings("unchecked") final Appender<ILoggingEvent> mockAppender =
224-
mock(Appender.class);
225-
when(mockAppender.getName()).thenReturn("MOCK");
226-
root.addAppender(mockAppender);
226+
Appender<ILoggingEvent> mockAppender = mockLogger(e -> {
227+
});
227228

228229
final Sender mockedSender = mock(Sender.class);
229230
when(mockedSender.close()).thenThrow(SenderException.class);
@@ -322,6 +323,74 @@ public int flush() throws SenderException {
322323
assertEquals("mySpan", (sender.getReceived().get(0)).getOperationName());
323324
}
324325

326+
@Test
327+
public void testFlushErrorsLoggedJustOnce() throws InterruptedException {
328+
329+
Object logMonitor = new Object();
330+
AtomicReference<String> logMsg = new AtomicReference<>(null);
331+
mockLogger(e -> {
332+
synchronized (logMonitor) {
333+
logMsg.set(e.getFormattedMessage());
334+
logMonitor.notifyAll();
335+
}
336+
});
337+
338+
class FailingSender extends InMemorySender {
339+
private final AtomicInteger flushCounter = new AtomicInteger(0);
340+
341+
@Override
342+
public int flush() throws SenderException {
343+
int i = super.flush();
344+
switch (flushCounter.getAndIncrement()) {
345+
case 1:
346+
case 2:
347+
case 3:
348+
throw new SenderException("test1", super.flush());
349+
default:
350+
return i;
351+
}
352+
}
353+
354+
private String awaitMessage(AtomicReference<String> ref) throws InterruptedException {
355+
synchronized (logMonitor) {
356+
while (ref.get() == null) {
357+
logMonitor.wait();
358+
}
359+
return ref.getAndSet(null);
360+
}
361+
}
362+
}
363+
364+
FailingSender sender = new FailingSender();
365+
366+
RemoteReporter remoteReporter = new Builder()
367+
.withSender(sender)
368+
.withFlushInterval(Integer.MAX_VALUE)
369+
.withMaxQueueSize(maxQueueSize)
370+
.withMetrics(metrics)
371+
.build();
372+
tracer = new JaegerTracer.Builder("test-remote-reporter")
373+
.withReporter(remoteReporter)
374+
.withSampler(new ConstSampler(true))
375+
.withMetrics(metrics)
376+
.build();
377+
378+
tracer.buildSpan("mySpan").start().finish();
379+
remoteReporter.flush();
380+
381+
tracer.buildSpan("mySpan").start().finish();
382+
remoteReporter.flush();
383+
384+
assertEquals("FlushCommand execution failed! Repeated errors of this command will not be logged.",
385+
sender.awaitMessage(logMsg));
386+
387+
remoteReporter.flush();
388+
remoteReporter.flush();
389+
remoteReporter.flush();
390+
assertEquals("FlushCommand is working again!", sender.awaitMessage(logMsg));
391+
392+
}
393+
325394
@Test
326395
public void testUpdateSuccessMetricWhenAppendFlushed() throws InterruptedException {
327396
int totalSpans = 3;
@@ -396,4 +465,21 @@ public int append(JaegerSpan span) throws SenderException {
396465
private JaegerSpan newSpan() {
397466
return tracer.buildSpan("x").start();
398467
}
468+
469+
private static Appender<ILoggingEvent> mockLogger(Consumer<ILoggingEvent> append) {
470+
ch.qos.logback.classic.Logger root =
471+
(ch.qos.logback.classic.Logger) LoggerFactory
472+
.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
473+
474+
@SuppressWarnings("unchecked")
475+
final Appender<ILoggingEvent> mockAppender = mock(Appender.class);
476+
when(mockAppender.getName()).thenReturn("MOCK");
477+
doAnswer(i -> {
478+
append.accept(i.getArgument(0));
479+
return null;
480+
}).when(mockAppender).doAppend(ArgumentMatchers.any(ILoggingEvent.class));
481+
root.addAppender(mockAppender);
482+
483+
return mockAppender;
484+
}
399485
}

0 commit comments

Comments
 (0)