View Javadoc

1   package com.atlassian.logging.log4j.appender;
2   
3   import com.atlassian.logging.log4j.appender.fluentd.FluentdLogQueueSendTask;
4   import com.atlassian.logging.log4j.appender.fluentd.FluentdRetryableException;
5   import com.atlassian.logging.log4j.appender.fluentd.FluentdSender;
6   import com.atlassian.logging.log4j.appender.fluentd.LoggingEventQueue;
7   import com.atlassian.logging.log4j.layout.JsonLayout;
8   import org.apache.log4j.Logger;
9   import org.apache.log4j.MDC;
10  import org.apache.log4j.Priority;
11  import org.apache.log4j.spi.LoggingEvent;
12  import org.junit.Test;
13  
14  import java.util.LinkedList;
15  import java.util.List;
16  
17  import static org.junit.Assert.assertEquals;
18  
19  public class FluentdLogQueueSendTaskTest {
20  
21      final static Logger log = Logger.getLogger(FluentdLogQueueSendTaskTest.class);
22  
23      private static final int MAX_NUM_CHARS = 1000;
24      private static final int MAX_RETRY_PERIOD_MS = 1000 * 60 * 10;
25      private static final int BACKOFF_MULTIPLIER = 10;
26      private static final int MAX_BACKOFF_MINUTES = 1;
27  
28  
29      @Test
30      public void test() {
31          final JsonLayout layout = new JsonLayout();
32          layout.activateOptions();
33  
34          final LoggingEventQueue<LoggingEvent> loggingEventQueue = new LoggingEventQueue<>(MAX_NUM_CHARS);
35  
36          final FluentdMockSender fluentdSender = new FluentdMockSender();
37  
38          final FluentdLogQueueSendTask sendTask = new FluentdLogQueueSendTask<>(
39                  layout::format,
40                  loggingEventQueue,
41                  fluentdSender,
42                  MAX_RETRY_PERIOD_MS,
43                  BACKOFF_MULTIPLIER,
44                  MAX_BACKOFF_MINUTES
45          );
46  
47          sendTask.run();
48          assertEquals("Message sent when not expected", 0, fluentdSender.getPayloadsSent().size());
49  
50          loggingEventQueue.enqueue(createLoggingEvent("Message 1"));
51          sendTask.run();
52          assertEquals("Message not sent when expected", 1, fluentdSender.getPayloadsSent().size());
53  
54          // Both messages should be batched into one request.
55          loggingEventQueue.enqueue(createLoggingEvent("Message 1"));
56          loggingEventQueue.enqueue(createLoggingEvent("Message 2"));
57          fluentdSender.clearPayloads();
58          sendTask.run();
59          assertEquals("Message not sent when expected", 1, fluentdSender.getPayloadsSent().size());
60  
61          loggingEventQueue.enqueue(createLoggingEvent("Pending message"));
62          fluentdSender.clearPayloads();
63          sendTask.clean();
64          assertEquals("Message not sent when expected", 1, fluentdSender.getPayloadsSent().size());
65  
66          final String expectedGoodMessage = "Good message";
67          final String unexpectedBadMessage = "Bad message";
68          loggingEventQueue.enqueue(createLoggingEvent(expectedGoodMessage));
69          loggingEventQueue.enqueue(createLoggingEventWithBadMdcContext(unexpectedBadMessage));
70          fluentdSender.clearPayloads();
71          sendTask.run();
72          assertEquals("Payload not sent", 1, fluentdSender.getPayloadsSent().size());
73          assertEquals("Payload does not contain expected message", true, fluentdSender.getPayloadsSent().get(0).contains(expectedGoodMessage));
74          assertEquals("Payload contains unexpected message", false, fluentdSender.getPayloadsSent().get(0).contains(unexpectedBadMessage));
75          assertEquals("Payload should contain only two lines", 2, fluentdSender.getPayloadsSent().get(0).split("\n").length);
76      }
77  
78      private LoggingEvent createLoggingEvent(final String message) {
79          return new LoggingEvent("test", log, Priority.INFO, message, (Throwable) null);
80      }
81  
82      private LoggingEvent createLoggingEventWithBadMdcContext(final String message) {
83          final String mdcKey = "unserializable";
84  
85          // JsonLayout will not know how to serialise this
86          MDC.put(mdcKey, new Object());
87          final LoggingEvent loggingEvent = createLoggingEvent(message);
88          loggingEvent.getMDCCopy();
89          MDC.remove(mdcKey);
90  
91          return loggingEvent;
92      }
93  
94      private static class FluentdMockSender implements FluentdSender {
95          private List<String> payloadsSent = new LinkedList<>();
96  
97          @Override
98          public void send(final String payload) throws FluentdRetryableException {
99              log.info("Logging: " + payload);
100             payloadsSent.add(payload);
101         }
102 
103         public List<String> getPayloadsSent() {
104             return payloadsSent;
105         }
106 
107         public void clearPayloads() {
108             payloadsSent = new LinkedList<>();
109         }
110     }
111 }