View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.classic.net;
15  
16  import java.util.ArrayList;
17  import java.util.List;
18  import java.util.concurrent.CountDownLatch;
19  import java.util.concurrent.TimeUnit;
20  
21  import ch.qos.logback.classic.util.LogbackMDCAdapter;
22  import org.junit.jupiter.api.Test;
23  
24  import ch.qos.logback.classic.Logger;
25  import ch.qos.logback.classic.LoggerContext;
26  import ch.qos.logback.classic.spi.ILoggingEvent;
27  import ch.qos.logback.core.AppenderBase;
28  import ch.qos.logback.core.testUtil.RandomUtil;
29  import ch.qos.logback.core.util.Duration;
30  import org.junit.jupiter.api.Timeout;
31  
32  import static org.junit.jupiter.api.Assertions.assertTrue;
33  
34  public class SocketAppenderMessageLossTest {
35      int runLen = 100;
36      Duration reconnectionDelay = new Duration(1000);
37  
38      static final int TIMEOUT = 3000;
39  
40      @Test // (timeout = TIMEOUT)
41      public void synchronousSocketAppender() throws Exception {
42  
43          SocketAppender socketAppender = new SocketAppender();
44          socketAppender.setReconnectionDelay(reconnectionDelay);
45          socketAppender.setIncludeCallerData(true);
46  
47          runTest(socketAppender);
48      }
49  
50      @Test
51      @Timeout(value = TIMEOUT, unit= TimeUnit.MILLISECONDS)
52      public void smallQueueSocketAppender() throws Exception {
53  
54          SocketAppender socketAppender = new SocketAppender();
55          socketAppender.setReconnectionDelay(reconnectionDelay);
56          socketAppender.setQueueSize(runLen / 10);
57  
58          runTest(socketAppender);
59      }
60  
61      @Test
62      @Timeout(value = TIMEOUT, unit= TimeUnit.MILLISECONDS)
63      public void largeQueueSocketAppender() throws Exception {
64          SocketAppender socketAppender = new SocketAppender();
65          socketAppender.setReconnectionDelay(reconnectionDelay);
66          socketAppender.setQueueSize(runLen * 5);
67  
68          runTest(socketAppender);
69      }
70  
71      // appender used to signal when the N'th event (as set in the latch) is received
72      // by the server
73      // this allows us to have test which are both more robust and quicker.
74      static public class ListAppenderWithLatch extends AppenderBase<ILoggingEvent> {
75          public List<ILoggingEvent> list = new ArrayList<ILoggingEvent>();
76          CountDownLatch latch;
77  
78          ListAppenderWithLatch(CountDownLatch latch) {
79              this.latch = latch;
80          }
81  
82          protected void append(ILoggingEvent e) {
83              list.add(e);
84              latch.countDown();
85          }
86      }
87  
88      public void runTest(SocketAppender socketAppender) throws Exception {
89          final int port = RandomUtil.getRandomServerPort();
90  
91          LoggerContext serverLoggerContext = new LoggerContext();
92          LogbackMDCAdapter serverLogbackMDCAdapter = new LogbackMDCAdapter();
93          serverLoggerContext.setMDCAdapter(serverLogbackMDCAdapter);
94          serverLoggerContext.setName("serverLoggerContext");
95  
96          CountDownLatch allMessagesReceivedLatch = new CountDownLatch(runLen);
97          ListAppenderWithLatch listAppender = new ListAppenderWithLatch(allMessagesReceivedLatch);
98          listAppender.setContext(serverLoggerContext);
99          listAppender.start();
100 
101         Logger serverRootLogger = serverLoggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
102         serverRootLogger.setAdditive(false);
103         serverRootLogger.addAppender(listAppender);
104 
105         LoggerContext loggerContext = new LoggerContext();
106         LogbackMDCAdapter logbackMDCAdapter = new LogbackMDCAdapter();
107         loggerContext.setMDCAdapter(logbackMDCAdapter);
108 
109         loggerContext.setName("clientLoggerContext");
110         socketAppender.setContext(loggerContext);
111 
112         CountDownLatch latch = new CountDownLatch(1);
113         SimpleSocketServer simpleSocketServer = new SimpleSocketServer(serverLoggerContext, port);
114         simpleSocketServer.start();
115         simpleSocketServer.setLatch(latch);
116 
117         latch.await();
118 
119         socketAppender.setPort(port);
120         socketAppender.setRemoteHost("localhost");
121         socketAppender.setReconnectionDelay(reconnectionDelay);
122         socketAppender.start();
123         assertTrue(socketAppender.isStarted());
124 
125         Logger logger = loggerContext.getLogger(getClass());
126         logger.setAdditive(false);
127         logger.addAppender(socketAppender);
128 
129         for (int i = 0; i < runLen; ++i) {
130             logger.info("hello");
131         }
132 
133         allMessagesReceivedLatch.await();
134         loggerContext.stop();
135         simpleSocketServer.close();
136 
137     }
138 }