001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.classic.boolex; 015 016import static org.junit.Assert.assertEquals; 017import static org.junit.Assert.assertFalse; 018import static org.junit.Assert.assertTrue; 019import static org.junit.Assert.fail; 020 021import java.io.IOException; 022 023import org.junit.Test; 024import org.slf4j.MDC; 025import org.slf4j.MarkerFactory; 026 027import ch.qos.logback.classic.Level; 028import ch.qos.logback.classic.Logger; 029import ch.qos.logback.classic.LoggerContext; 030import ch.qos.logback.classic.pattern.ConverterTest; 031import ch.qos.logback.classic.spi.ILoggingEvent; 032import ch.qos.logback.classic.spi.LoggingEvent; 033import ch.qos.logback.core.boolex.EvaluationException; 034import ch.qos.logback.core.boolex.JaninoEventEvaluatorBase; 035import ch.qos.logback.core.boolex.Matcher; 036import ch.qos.logback.core.filter.EvaluatorFilter; 037import ch.qos.logback.core.spi.FilterReply; 038import ch.qos.logback.core.testUtil.RandomUtil; 039import ch.qos.logback.core.util.StatusPrinter; 040 041public class JaninoEventEvaluatorTest { 042 043 LoggerContext loggerContext = new LoggerContext(); 044 Logger logger = loggerContext.getLogger(ConverterTest.class); 045 046 Matcher matcherX = new Matcher(); 047 048 JaninoEventEvaluator jee = new JaninoEventEvaluator(); 049 050 int diff = RandomUtil.getPositiveInt(); 051 052 public JaninoEventEvaluatorTest() { 053 jee.setContext(loggerContext); 054 055 matcherX.setName("x"); 056 matcherX.setRegex("^Some\\s.*"); 057 matcherX.start(); 058 059 } 060 061 LoggingEvent makeLoggingEvent(Exception ex) { 062 return new LoggingEvent(ch.qos.logback.core.pattern.FormattingConverter.class.getName(), logger, Level.INFO, "Some message", ex, null); 063 } 064 065 @Test 066 public void testBasic() throws Exception { 067 jee.setExpression("message.equals(\"Some message\")"); 068 jee.start(); 069 070 StatusPrinter.print(loggerContext); 071 ILoggingEvent event = makeLoggingEvent(null); 072 assertTrue(jee.evaluate(event)); 073 } 074 075 @Test 076 public void testLevel() throws Exception { 077 jee.setExpression("level > DEBUG"); 078 jee.start(); 079 080 ILoggingEvent event = makeLoggingEvent(null); 081 assertTrue(jee.evaluate(event)); 082 } 083 084 @Test 085 public void testtimeStamp() throws Exception { 086 jee.setExpression("timeStamp > 10"); 087 jee.start(); 088 089 ILoggingEvent event = makeLoggingEvent(null); 090 assertTrue(jee.evaluate(event)); 091 } 092 093 @Test 094 public void testWithMatcher() throws Exception { 095 jee.setExpression("x.matches(message)"); 096 jee.addMatcher(matcherX); 097 jee.start(); 098 099 ILoggingEvent event = makeLoggingEvent(null); 100 assertTrue(jee.evaluate(event)); 101 } 102 103 @Test 104 public void mdcAsString() throws Exception { 105 String k = "key" + diff; 106 107 MDC.put("key" + diff, "value" + diff); 108 jee.setExpression("((String) mdc.get(\"" + k + "\")).contains(\"alue\")"); 109 jee.start(); 110 StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext); 111 112 LoggingEvent event = makeLoggingEvent(null); 113 assertTrue(jee.evaluate(event)); 114 MDC.remove(k); 115 } 116 117 @Test 118 public void marker() throws Exception { 119 jee.setExpression("marker.contains(\"BLUE\")"); 120 jee.start(); 121 122 LoggingEvent event = makeLoggingEvent(null); 123 event.setMarker(MarkerFactory.getMarker("BLUE")); 124 assertTrue(jee.evaluate(event)); 125 } 126 127 @Test 128 public void withNullMarker_LBCORE_118() throws Exception { 129 jee.setExpression("marker.contains(\"BLUE\")"); 130 jee.start(); 131 132 ILoggingEvent event = makeLoggingEvent(null); 133 try { 134 jee.evaluate(event); 135 fail("We should not reach this point"); 136 } catch (EvaluationException ee) { 137 // received an exception as expected 138 } 139 } 140 141 @Test 142 public void evaluatorFilterWithNullMarker_LBCORE_118() throws Exception { 143 EvaluatorFilter<ILoggingEvent> ef = new EvaluatorFilter<ILoggingEvent>(); 144 ef.setContext(loggerContext); 145 146 ef.setOnMatch(FilterReply.ACCEPT); 147 ef.setOnMismatch(FilterReply.DENY); 148 149 jee.setExpression("marker.contains(\"BLUE\")"); 150 jee.start(); 151 152 ef.setEvaluator(jee); 153 ef.start(); 154 ILoggingEvent event = makeLoggingEvent(null); 155 assertEquals(FilterReply.NEUTRAL, ef.decide(event)); 156 157 } 158 159 @Test 160 public void testComplex() throws Exception { 161 jee.setExpression("level >= INFO && x.matches(message) && marker.contains(\"BLUE\")"); 162 jee.addMatcher(matcherX); 163 jee.start(); 164 165 LoggingEvent event = makeLoggingEvent(null); 166 event.setMarker(MarkerFactory.getMarker("BLUE")); 167 assertTrue(jee.evaluate(event)); 168 } 169 170 /** 171 * check that evaluator with bogus exp does not start 172 * 173 * @throws Exception 174 */ 175 @Test 176 public void testBogusExp1() { 177 jee.setExpression("mzzzz.get(\"key\").equals(null)"); 178 jee.setName("bogus"); 179 jee.start(); 180 181 assertFalse(jee.isStarted()); 182 } 183 184 // check that eval stops after errors 185 @Test 186 public void testBogusExp2() { 187 jee.setExpression("mdc.get(\"keyXN89\").equals(null)"); 188 jee.setName("bogus"); 189 jee.start(); 190 191 assertTrue(jee.isStarted()); 192 193 ILoggingEvent event = makeLoggingEvent(null); 194 195 for (int i = 0; i < JaninoEventEvaluatorBase.ERROR_THRESHOLD; i++) { 196 try { 197 jee.evaluate(event); 198 fail("should throw an exception"); 199 } catch (EvaluationException e) { 200 } 201 } 202 // after a few attempts the evaluator should processPriorToRemoval 203 assertFalse(jee.isStarted()); 204 205 } 206 207 static final long LEN = 10 * 1000; 208 209 // with 6 parameters 400 nanos 210 // with 7 parameters 460 nanos (all levels + selected fields from 211 // LoggingEvent) 212 // with 10 parameters 510 nanos (all levels + fields) 213 void loop(JaninoEventEvaluator jee, String msg) throws Exception { 214 ILoggingEvent event = makeLoggingEvent(null); 215 // final long start = System.nanoTime(); 216 for (int i = 0; i < LEN; i++) { 217 jee.evaluate(event); 218 } 219 // final long end = System.nanoTime(); 220 // System.out.println(msg + (end - start) / LEN + " nanos"); 221 } 222 223 @Test 224 public void testLoop1() throws Exception { 225 jee.setExpression("timeStamp > 10"); 226 jee.start(); 227 228 loop(jee, "timestamp > 10]: "); 229 } 230 231 @Test 232 public void testLoop2() throws Exception { 233 jee.setExpression("x.matches(message)"); 234 jee.addMatcher(matcherX); 235 jee.start(); 236 237 loop(jee, "x.matches(message): "); 238 } 239 240 @Test 241 public void throwable_LBCLASSIC_155_I() throws EvaluationException { 242 jee.setExpression("throwable instanceof java.io.IOException"); 243 jee.start(); 244 245 LoggingEvent event = makeLoggingEvent(new IOException("")); 246 assertTrue(jee.evaluate(event)); 247 } 248 249 @Test 250 public void throwable_LBCLASSIC_155_II() throws EvaluationException { 251 jee.setExpression("throwableProxy.getClassName().contains(\"IO\")"); 252 jee.start(); 253 254 LoggingEvent event = makeLoggingEvent(new IOException("")); 255 assertTrue(jee.evaluate(event)); 256 } 257 258 @Test 259 public void nullMDC() throws EvaluationException { 260 MDC.clear(); 261 jee.setExpression("mdc.isEmpty()"); 262 jee.start(); 263 264 LoggingEvent event = makeLoggingEvent(null); 265 assertTrue(jee.evaluate(event)); 266 } 267}