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;
15  
16  import ch.qos.logback.classic.spi.ILoggingEvent;
17  import ch.qos.logback.classic.turbo.MDCFilter;
18  import ch.qos.logback.classic.turbo.MarkerFilter;
19  import ch.qos.logback.classic.turbo.TurboFilter;
20  import ch.qos.logback.core.read.ListAppender;
21  import ch.qos.logback.core.spi.FilterReply;
22  import ch.qos.logback.core.testUtil.RandomUtil;
23  import org.junit.jupiter.api.BeforeEach;
24  import org.junit.jupiter.api.Test;
25  import org.slf4j.MDC;
26  import org.slf4j.Marker;
27  import org.slf4j.MarkerFactory;
28  
29  import static org.junit.jupiter.api.Assertions.assertEquals;
30  import static org.junit.jupiter.api.Assertions.assertFalse;
31  import static org.junit.jupiter.api.Assertions.assertNotNull;
32  import static org.junit.jupiter.api.Assertions.assertTrue;
33  
34  public class TurboFilteringInLoggerTest {
35  
36      static final String BLUE = "BLUE";
37      LoggerContext loggerContext;
38      Logger logger;
39      Marker blueMarker = MarkerFactory.getMarker(BLUE);
40  
41      int diff = RandomUtil.getPositiveInt();
42      String key = "tfiolKey" + diff;
43      String value = "val" + diff;
44  
45      ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
46  
47  
48      @BeforeEach
49      public void setUp() throws Exception {
50          loggerContext = new LoggerContext();
51          loggerContext.setName("test");
52          loggerContext.start();
53          logger = loggerContext.getLogger(TurboFilteringInLoggerTest.class);
54  
55          Logger root = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
56          root.setLevel(Level.ERROR);
57          listAppender.start();
58          root.addAppender(listAppender);
59  
60      }
61  
62      private CountingMDCFilter addMDCFilter() {
63          CountingMDCFilter countingMDCFilter = new CountingMDCFilter();
64          countingMDCFilter.setOnMatch("ACCEPT");
65          countingMDCFilter.setOnMismatch("DENY");
66          countingMDCFilter.setMDCKey(key);
67          countingMDCFilter.setValue(value);
68          countingMDCFilter.start();
69          loggerContext.addTurboFilter(countingMDCFilter);
70          return  countingMDCFilter;
71      }
72      private YesFilter addYesFilter() {
73          YesFilter filter = new YesFilter();
74          filter.start();
75          loggerContext.addTurboFilter(filter);
76          return filter;
77      }
78  
79      private NoFilter addNoFilter() {
80          NoFilter filter = new NoFilter();
81          filter.start();
82          loggerContext.addTurboFilter(filter);
83          return filter;
84      }
85  
86      private void addAcceptBLUEFilter() {
87          MarkerFilter filter = new MarkerFilter();
88          filter.setMarker(BLUE);
89          filter.setOnMatch("ACCEPT");
90          filter.start();
91          loggerContext.addTurboFilter(filter);
92      }
93  
94      private void addDenyBLUEFilter() {
95          MarkerFilter filter = new MarkerFilter();
96          filter.setMarker(BLUE);
97          filter.setOnMatch("DENY");
98          filter.start();
99          loggerContext.addTurboFilter(filter);
100     }
101 
102     @Test
103     public void testIsDebugEnabledWithYesFilter() {
104         addYesFilter();
105         logger.setLevel(Level.INFO);
106         assertTrue(logger.isDebugEnabled());
107     }
108 
109     @Test
110     public void testIsInfoEnabledWithYesFilter() {
111         YesFilter filter = addYesFilter();
112         logger.setLevel(Level.WARN);
113         assertTrue(logger.isInfoEnabled()); // count+=1
114         logger.info("testIsInfoEnabledWithYesFilter1"); // count+=1
115         logger.atInfo().log("testIsInfoEnabledWithYesFilter2"); // count+=2
116         assertEquals(2, listAppender.list.size());
117         assertEquals(4, filter.count);
118     }
119 
120     @Test
121     public void testIsWarnEnabledWithYesFilter() {
122         YesFilter filter = addYesFilter();
123         logger.setLevel(Level.ERROR);
124         assertTrue(logger.isWarnEnabled());  // count+=1
125         assertEquals(1, filter.count);
126 
127     }
128 
129     @Test
130     public void testIsErrorEnabledWithYesFilter() {
131         addYesFilter();
132         logger.setLevel(Level.OFF);
133         assertTrue(logger.isErrorEnabled());
134     }
135 
136     @Test
137     public void testIsEnabledForWithYesFilter() {
138         addYesFilter();
139         logger.setLevel(Level.ERROR);
140         assertTrue(logger.isEnabledFor(Level.INFO));
141     }
142 
143     @Test
144     public void testIsEnabledForWithNoFilter() {
145         addNoFilter();
146         logger.setLevel(Level.DEBUG);
147         assertFalse(logger.isEnabledFor(Level.INFO));
148     }
149 
150     @Test
151     public void testIsDebugEnabledWithNoFilter() {
152         addNoFilter();
153         logger.setLevel(Level.DEBUG);
154         assertFalse(logger.isDebugEnabled());
155     }
156 
157     @Test
158     public void testIsInfoEnabledWithNoFilter() {
159         addNoFilter();
160         logger.setLevel(Level.DEBUG);
161         assertFalse(logger.isInfoEnabled());
162     }
163 
164     @Test
165     public void testIsWarnEnabledWithNoFilter() {
166         addNoFilter();
167         logger.setLevel(Level.DEBUG);
168         assertFalse(logger.isWarnEnabled());
169     }
170 
171     @Test
172     public void testIsErrorEnabledWithNoFilter() {
173         addNoFilter();
174         logger.setLevel(Level.DEBUG);
175         assertFalse(logger.isErrorEnabled());
176     }
177 
178     @Test
179     public void testIsErrorEnabledWithAcceptBlueFilter() {
180         addAcceptBLUEFilter();
181         logger.setLevel(Level.ERROR);
182         assertTrue(logger.isDebugEnabled(blueMarker));
183     }
184 
185     @Test
186     public void testIsErrorEnabledWithDenyBlueFilter() {
187         addDenyBLUEFilter();
188         logger.setLevel(Level.ALL);
189         assertFalse(logger.isDebugEnabled(blueMarker));
190     }
191 
192     @Test
193     public void testLoggingContextReset() {
194         addYesFilter();
195         assertNotNull(loggerContext.getTurboFilterList().get(0));
196         loggerContext.reset();
197         assertEquals(0, loggerContext.getTurboFilterList().size());
198     }
199 
200     @Test
201     public void fluentAPI() {
202         CountingMDCFilter countingMDCFilter = addMDCFilter();
203         Logger logger = loggerContext.getLogger(this.getClass());
204         logger.atDebug().log("hello 1"); // count+=1
205         assertEquals(0, listAppender.list.size());
206         MDC.put(key, value);
207         logger.atDebug().log("hello 2");  // count+=2
208         assertEquals(1, listAppender.list.size());
209         assertEquals(3, countingMDCFilter.count);
210     }
211 }
212 
213 class YesFilter extends TurboFilter {
214     int count = 0;
215     @Override
216     public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
217         count++;
218         return FilterReply.ACCEPT;
219     }
220 }
221 
222 class NoFilter extends TurboFilter {
223     int count = 0;
224     @Override
225     public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
226         count++;
227         return FilterReply.DENY;
228     }
229 }
230 
231 
232 class CountingMDCFilter extends MDCFilter {
233     int count = 0;
234     @Override
235     public FilterReply decide(Marker marker, Logger logger, Level level, String format, Object[] params, Throwable t) {
236         count++;
237         return super.decide(marker, logger, level, format, params, t);
238     }
239 }