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 static org.junit.Assert.assertEquals;
17  import static org.junit.Assert.assertTrue;
18  
19  import org.junit.After;
20  import org.junit.Before;
21  import org.junit.Ignore;
22  import org.junit.Test;
23  import org.slf4j.LoggerFactory;
24  
25  import ch.qos.logback.classic.ClassicTestConstants;
26  import ch.qos.logback.classic.Logger;
27  import ch.qos.logback.classic.LoggerContext;
28  import ch.qos.logback.classic.joran.JoranConfigurator;
29  import ch.qos.logback.classic.net.mock.MockSyslogServer;
30  import ch.qos.logback.core.CoreConstants;
31  import ch.qos.logback.core.joran.spi.JoranException;
32  import ch.qos.logback.core.net.SyslogConstants;
33  import ch.qos.logback.core.recovery.RecoveryCoordinator;
34  import ch.qos.logback.core.testUtil.RandomUtil;
35  import ch.qos.logback.core.util.StatusPrinter;
36  
37  import java.nio.charset.Charset;
38  @Ignore
39  public class SyslogAppenderTest {
40  
41      private static final String SYSLOG_PREFIX_REGEX = "<\\d{2}>\\w{3} [\\d ]\\d \\d{2}(:\\d{2}){2} [\\w.-]* ";
42  
43      LoggerContext lc = new LoggerContext();
44      SyslogAppender sa = new SyslogAppender();
45      MockSyslogServer mockServer;
46      String loggerName = this.getClass().getName();
47      Logger logger = lc.getLogger(loggerName);
48  
49      @Before
50      public void setUp() throws Exception {
51          lc.setName("test");
52          sa.setContext(lc);
53      }
54  
55      @After
56      public void tearDown() throws Exception {
57      }
58  
59      public void setMockServerAndConfigure(int expectedCount, String suffixPattern) throws InterruptedException {
60          int port = RandomUtil.getRandomServerPort();
61  
62          mockServer = new MockSyslogServer(expectedCount, port);
63          mockServer.start();
64          // give MockSyslogServer head start
65  
66          Thread.sleep(100);
67  
68          sa.setSyslogHost("localhost");
69          sa.setFacility("MAIL");
70          sa.setPort(port);
71          sa.setSuffixPattern(suffixPattern);
72          sa.setStackTracePattern("[%thread] foo " + CoreConstants.TAB);
73          sa.start();
74          assertTrue(sa.isStarted());
75  
76          String loggerName = this.getClass().getName();
77          Logger logger = lc.getLogger(loggerName);
78          logger.addAppender(sa);
79  
80      }
81  
82      public void setMockServerAndConfigure(int expectedCount) throws InterruptedException {
83          this.setMockServerAndConfigure(expectedCount, "[%thread] %logger %msg");
84      }
85  
86      @Test
87      public void basic() throws InterruptedException {
88  
89          setMockServerAndConfigure(1);
90          String logMsg = "hello";
91          logger.debug(logMsg);
92  
93          // wait max 2 seconds for mock server to finish. However, it should
94          // much sooner than that.
95          mockServer.join(8000);
96  
97          assertTrue(mockServer.isFinished());
98          assertEquals(1, mockServer.getMessageList().size());
99          String msg = new String(mockServer.getMessageList().get(0));
100 
101         String threadName = Thread.currentThread().getName();
102 
103         String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
104         assertTrue(msg.startsWith(expected));
105 
106         checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg);
107 
108     }
109 
110     @Test
111     public void suffixPatternWithTag() throws InterruptedException {
112         setMockServerAndConfigure(1, "test/something [%thread] %logger %msg");
113         String logMsg = "hello";
114         logger.debug(logMsg);
115 
116         // wait max 2 seconds for mock server to finish. However, it should
117         // much sooner than that.
118         mockServer.join(8000);
119 
120         assertTrue(mockServer.isFinished());
121         assertEquals(1, mockServer.getMessageList().size());
122         String msg = new String(mockServer.getMessageList().get(0));
123 
124         String threadName = Thread.currentThread().getName();
125 
126         String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
127         assertTrue(msg.startsWith(expected));
128 
129         checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "test/something \\[" + threadName + "\\] " + loggerName + " " + logMsg);
130 
131     }
132 
133     @Test
134     public void tException() throws InterruptedException {
135         setMockServerAndConfigure(21);
136 
137         String logMsg = "hello";
138         String exMsg = "just testing";
139         Exception ex = new Exception(exMsg);
140         logger.debug(logMsg, ex);
141         StatusPrinter.print(lc);
142 
143         // wait max 2 seconds for mock server to finish. However, it should
144         // much sooner than that.
145         mockServer.join(8000);
146         assertTrue(mockServer.isFinished());
147 
148         // message + 20 lines of stacktrace
149         assertEquals(21, mockServer.getMessageList().size());
150         // int i = 0;
151         // for (String line: mockServer.msgList) {
152         // System.out.println(i++ + ": " + line);
153         // }
154 
155         String msg = new String(mockServer.getMessageList().get(0));
156         String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
157         assertTrue(msg.startsWith(expected));
158 
159         String threadName = Thread.currentThread().getName();
160         String regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg;
161         checkRegexMatch(msg, regex);
162 
163         msg = new String(mockServer.getMessageList().get(1));
164         assertTrue(msg.contains(ex.getClass().getName()));
165         assertTrue(msg.contains(ex.getMessage()));
166 
167         msg = new String(mockServer.getMessageList().get(2));
168         assertTrue(msg.startsWith(expected));
169         regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + "foo " + CoreConstants.TAB + "at ch\\.qos.*";
170         checkRegexMatch(msg, regex);
171     }
172 
173     private void checkRegexMatch(String s, String regex) {
174         assertTrue("The string [" + s + "] did not match regex [" + regex + "]", s.matches(regex));
175     }
176 
177     @Test
178     public void large() throws Exception {
179         setMockServerAndConfigure(2);
180         StringBuilder largeBuf = new StringBuilder();
181         for (int i = 0; i < 2 * 1024 * 1024; i++) {
182             largeBuf.append('a');
183         }
184         logger.debug(largeBuf.toString());
185 
186         String logMsg = "hello";
187         logger.debug(logMsg);
188         Thread.sleep(RecoveryCoordinator.BACKOFF_COEFFICIENT_MIN + 10);
189         logger.debug(logMsg);
190 
191         mockServer.join(8000);
192         assertTrue(mockServer.isFinished());
193 
194         // both messages received
195         assertEquals(2, mockServer.getMessageList().size());
196 
197         String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
198         String threadName = Thread.currentThread().getName();
199 
200         // large message is truncated
201         final int maxMessageSize = sa.getMaxMessageSize();
202         String largeMsg = new String(mockServer.getMessageList().get(0));
203         assertTrue(largeMsg.startsWith(expected));
204         String largeRegex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + "a{" + (maxMessageSize - 2000) + "," + maxMessageSize + "}";
205         checkRegexMatch(largeMsg, largeRegex);
206 
207         String msg = new String(mockServer.getMessageList().get(1));
208         assertTrue(msg.startsWith(expected));
209         String regex = SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg;
210         checkRegexMatch(msg, regex);
211     }
212 
213     @Test
214     public void LBCLASSIC_50() throws JoranException {
215 
216         LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
217 
218         JoranConfigurator configurator = new JoranConfigurator();
219         configurator.setContext(lc);
220         lc.reset();
221         configurator.doConfigure(ClassicTestConstants.JORAN_INPUT_PREFIX + "syslog_LBCLASSIC_50.xml");
222 
223         org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
224         logger.info("hello");
225     }
226 
227     @Test
228     public void unknownHostShouldNotCauseStopToFail() {
229         // See LOGBACK-960
230         sa.setSyslogHost("unknown.host");
231         sa.setFacility("MAIL");
232         sa.start();
233         sa.stop();
234     }
235 
236     @Test
237     public void nonAsciiMessageEncoding() throws Exception {
238         // See LOGBACK-732
239         setMockServerAndConfigure(1);
240 
241         // Use a string that can be encoded in a somewhat odd encoding (ISO-8859-4) to minimize
242         // the probability of the encoding test to work by accident
243         String logMsg = "R\u0129ga"; // Riga spelled with the i having a tilda on top
244 
245         Charset ISO_8859_4 = Charset.forName("ISO-8859-4");
246         sa.setCharset(ISO_8859_4);
247         logger.debug(logMsg);
248 
249         // wait max 8 seconds for mock server to finish. However, it should
250         // be done much sooner than that.
251         mockServer.join(8000);
252 
253         assertTrue(mockServer.isFinished());
254         assertEquals(1, mockServer.getMessageList().size());
255         String msg = new String(mockServer.getMessageList().get(0), ISO_8859_4);
256         String threadName = Thread.currentThread().getName();
257 
258         String expected = "<" + (SyslogConstants.LOG_MAIL + SyslogConstants.DEBUG_SEVERITY) + ">";
259         assertTrue(msg.startsWith(expected));
260 
261         System.out.println(logMsg);
262         checkRegexMatch(msg, SYSLOG_PREFIX_REGEX + "\\[" + threadName + "\\] " + loggerName + " " + logMsg);
263 
264     }
265 }