Codebase list libslf4j-java / 825ef95
Imported Upstream version 1.7.21 Emmanuel Bourg 7 years ago
30 changed file(s) with 409 addition(s) and 453 deletion(s). Raw diff Collapse all Expand all
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>integration</artifactId>
44 <parent>
55 <groupId>org.slf4j</groupId>
66 <artifactId>slf4j-parent</artifactId>
7 <version>1.7.20</version>
7 <version>1.7.21</version>
88 </parent>
99
1010 <modelVersion>4.0.0</modelVersion>
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>jul-to-slf4j</artifactId>
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>osgi-over-slf4j</artifactId>
55
66 <groupId>org.slf4j</groupId>
77 <artifactId>slf4j-parent</artifactId>
8 <version>1.7.20</version>
8 <version>1.7.21</version>
99
1010 <packaging>pom</packaging>
1111 <name>SLF4J</name>
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-android</artifactId>
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-api</artifactId>
5353 * <p/>
5454 * <p/>
5555 * Please note that all methods in <code>LoggerFactory</code> are static.
56 *
57 *
56 *
57 *
5858 * @author Alexander Dorokhine
5959 * @author Robert Elliot
6060 * @author Ceki G&uuml;lc&uuml;
61 *
61 *
6262 */
6363 public final class LoggerFactory {
6464
139139 private final static void bind() {
140140 try {
141141 Set<URL> staticLoggerBinderPathSet = null;
142 // skip check under android, see also http://jira.qos.ch/browse/SLF4J-328
142 // skip check under android, see also
143 // http://jira.qos.ch/browse/SLF4J-328
143144 if (!isAndroid()) {
144145 staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
145146 reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
148149 StaticLoggerBinder.getSingleton();
149150 INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
150151 reportActualBinding(staticLoggerBinderPathSet);
152 fixSubstituteLoggers();
151153 replayEvents();
154 // release all resources in SUBST_FACTORY
155 SUBST_FACTORY.clear();
152156 } catch (NoClassDefFoundError ncde) {
153157 String msg = ncde.getMessage();
154158 if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
173177 failedBinding(e);
174178 throw new IllegalStateException("Unexpected initialization failure", e);
175179 }
180 }
181
182 private static void fixSubstituteLoggers() {
183 synchronized (SUBST_FACTORY) {
184 SUBST_FACTORY.postInitialization();
185 for (SubstituteLogger substLogger : SUBST_FACTORY.getLoggers()) {
186 Logger logger = getLogger(substLogger.getName());
187 substLogger.setDelegate(logger);
188 }
189 }
190
176191 }
177192
178193 static void failedBinding(Throwable t) {
216231 SubstituteLogger substLogger = event.getLogger();
217232 String loggerName = substLogger.getName();
218233 if (substLogger.isDelegateNull()) {
219 Logger logger = getLogger(loggerName);
220 substLogger.setDelegate(logger);
234 throw new IllegalStateException("Delegate logger cannot be null at this state.");
221235 }
222236
223237 if (substLogger.isDelegateNOP()) {
269283 }
270284 }
271285
272 // We need to use the name of the StaticLoggerBinder class, but we can't reference
286 // We need to use the name of the StaticLoggerBinder class, but we can't
287 // reference
273288 // the class itself.
274289 private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
275290
276291 static Set<URL> findPossibleStaticLoggerBinderPathSet() {
277292 // use Set instead of list in order to deal with bug #138
278 // LinkedHashSet appropriate here because it preserves insertion order during iteration
293 // LinkedHashSet appropriate here because it preserves insertion order
294 // during iteration
279295 Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
280296 try {
281297 ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
300316 }
301317
302318 /**
303 * Prints a warning message on the console if multiple bindings were found on the class path.
304 * No reporting is done otherwise.
305 *
319 * Prints a warning message on the console if multiple bindings were found
320 * on the class path. No reporting is done otherwise.
321 *
306322 */
307323 private static void reportMultipleBindingAmbiguity(Set<URL> binderPathSet) {
308324 if (isAmbiguousStaticLoggerBinderPathSet(binderPathSet)) {
329345 }
330346
331347 /**
332 * Return a logger named according to the name parameter using the statically
333 * bound {@link ILoggerFactory} instance.
334 *
335 * @param name The name of the logger.
348 * Return a logger named according to the name parameter using the
349 * statically bound {@link ILoggerFactory} instance.
350 *
351 * @param name
352 * The name of the logger.
336353 * @return logger
337354 */
338355 public static Logger getLogger(String name) {
341358 }
342359
343360 /**
344 * Return a logger named corresponding to the class passed as parameter, using
345 * the statically bound {@link ILoggerFactory} instance.
346 *
347 * <p>In case the the <code>clazz</code> parameter differs from the name of
348 * the caller as computed internally by SLF4J, a logger name mismatch warning will be
349 * printed but only if the <code>slf4j.detectLoggerNameMismatch</code> system property is
350 * set to true. By default, this property is not set and no warnings will be printed
351 * even in case of a logger name mismatch.
352 *
353 * @param clazz the returned logger will be named after clazz
361 * Return a logger named corresponding to the class passed as parameter,
362 * using the statically bound {@link ILoggerFactory} instance.
363 *
364 * <p>
365 * In case the the <code>clazz</code> parameter differs from the name of the
366 * caller as computed internally by SLF4J, a logger name mismatch warning
367 * will be printed but only if the
368 * <code>slf4j.detectLoggerNameMismatch</code> system property is set to
369 * true. By default, this property is not set and no warnings will be
370 * printed even in case of a logger name mismatch.
371 *
372 * @param clazz
373 * the returned logger will be named after clazz
354374 * @return logger
355 *
356 *
357 * @see <a href="http://www.slf4j.org/codes.html#loggerNameMismatch">Detected logger name mismatch</a>
375 *
376 *
377 * @see <a
378 * href="http://www.slf4j.org/codes.html#loggerNameMismatch">Detected
379 * logger name mismatch</a>
358380 */
359381 public static Logger getLogger(Class<?> clazz) {
360382 Logger logger = getLogger(clazz.getName());
378400 * <p/>
379401 * <p/>
380402 * ILoggerFactory instance is bound with this class at compile time.
381 *
403 *
382404 * @return the ILoggerFactory instance in use
383405 */
384406 public static ILoggerFactory getILoggerFactory() {
5252 private EventRecodingLogger eventRecodingLogger;
5353 private Queue<SubstituteLoggingEvent> eventQueue;
5454
55 public SubstituteLogger(String name, Queue<SubstituteLoggingEvent> eventQueue) {
55 private final boolean createdPostInitialization;
56
57 public SubstituteLogger(String name, Queue<SubstituteLoggingEvent> eventQueue, boolean createdPostInitialization) {
5658 this.name = name;
5759 this.eventQueue = eventQueue;
60 this.createdPostInitialization = createdPostInitialization;
5861 }
5962
6063 public String getName() {
326329 * instance.
327330 */
328331 Logger delegate() {
329 return _delegate != null ? _delegate : getEventRecordingLogger();
332 if(_delegate != null) {
333 return _delegate;
334 }
335 if(createdPostInitialization) {
336 return NOPLogger.NOP_LOGGER;
337 } else {
338 return getEventRecordingLogger();
339 }
330340 }
331341
332342 private Logger getEventRecordingLogger() {
2424 package org.slf4j.helpers;
2525
2626 import java.util.ArrayList;
27 import java.util.HashMap;
2728 import java.util.List;
28 import java.util.concurrent.ConcurrentHashMap;
29 import java.util.concurrent.ConcurrentMap;
29 import java.util.Map;
3030 import java.util.concurrent.LinkedBlockingQueue;
3131
3232 import org.slf4j.ILoggerFactory;
4141 */
4242 public class SubstituteLoggerFactory implements ILoggerFactory {
4343
44 final ConcurrentMap<String, SubstituteLogger> loggers = new ConcurrentHashMap<String, SubstituteLogger>();
44 boolean postInitialization = false;
45
46 final Map<String, SubstituteLogger> loggers = new HashMap<String, SubstituteLogger>();
4547
4648 final LinkedBlockingQueue<SubstituteLoggingEvent> eventQueue = new LinkedBlockingQueue<SubstituteLoggingEvent>();
4749
48 public Logger getLogger(String name) {
50 synchronized public Logger getLogger(String name) {
4951 SubstituteLogger logger = loggers.get(name);
5052 if (logger == null) {
51 logger = new SubstituteLogger(name, eventQueue);
52 SubstituteLogger oldLogger = loggers.putIfAbsent(name, logger);
53 if (oldLogger != null)
54 logger = oldLogger;
53 logger = new SubstituteLogger(name, eventQueue, postInitialization);
54 loggers.put(name, logger);
5555 }
5656 return logger;
5757 }
6868 return eventQueue;
6969 }
7070
71 public void postInitialization() {
72 postInitialization = true;
73 }
74
7175 public void clear() {
7276 loggers.clear();
7377 eventQueue.clear();
+0
-55
slf4j-api/src/test/java/org/slf4j/FindStaticLoggerBinderPathsPerfTest.hava less more
0 package org.slf4j;
1
2 import org.junit.Ignore;
3 import org.junit.Test;
4
5 public class FindStaticLoggerBinderPathsPerfTest {
6
7 @Test
8 @Ignore
9 public void test() {
10 long duration = timeFindBindingSetCall();
11 System.out.println(duration / (1000) + " microseconds");
12
13 int count = 10;
14 long sum = 0;
15 for (int i = 0; i < count; i++) {
16 sum += timeFindBindingSetCall();
17 }
18 System.out.println(sum / (count * 1000) + " microseconds in average");
19 }
20
21 @Test
22 public void testAsync() throws InterruptedException {
23 long start = System.nanoTime();
24 FindPathSetThread thread = new FindPathSetThread();
25 thread.start();
26 long end = System.nanoTime();
27
28 long duration = end - start;
29 System.out.println(duration / (1000) + " microseconds");
30
31 thread.join();
32 }
33
34 long timeFindBindingSetCall() {
35 long start = System.nanoTime();
36
37 LoggerFactory.findPossibleStaticLoggerBinderPathSet();
38 long end = System.nanoTime();
39 return end - start;
40
41 }
42
43 static class FindPathSetThread extends Thread {
44
45 public void run() {
46 long start = System.nanoTime();
47 LoggerFactory.findPossibleStaticLoggerBinderPathSet();
48 long end = System.nanoTime();
49
50 System.out.println("Found set in " + (end - start)/1000 + " microseconds");
51
52 }
53 }
54 }
2323 */
2424 package org.slf4j;
2525
26 import java.util.List;
2627 import java.util.concurrent.CyclicBarrier;
2728 import java.util.concurrent.atomic.AtomicLong;
2829
3233 final CyclicBarrier barrier;
3334 final int count;
3435 final AtomicLong eventCount;
35
36 public LoggerAccessingThread(final CyclicBarrier barrier, final int count, final AtomicLong eventCount) {
36 List<Logger> loggerList;
37
38 public LoggerAccessingThread(final CyclicBarrier barrier, List<Logger> loggerList, final int count, final AtomicLong eventCount) {
3739 this.barrier = barrier;
40 this.loggerList = loggerList;
3841 this.count = count;
3942 this.eventCount = eventCount;
4043 }
4952 String loggerNamePrefix = this.getClass().getName();
5053 for (int i = 0; i < LOOP_LEN; i++) {
5154 Logger logger = LoggerFactory.getLogger(loggerNamePrefix + "-" + count + "-" + i);
55 loggerList.add(logger);
56 Thread.yield();
5257 logger.info("in run method");
5358 eventCount.getAndIncrement();
5459 }
0 package org.slf4j.helpers;
1
2 import static org.junit.Assert.assertTrue;
3 import static org.junit.Assert.fail;
4
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.List;
8 import java.util.Random;
9 import java.util.concurrent.BrokenBarrierException;
10 import java.util.concurrent.CyclicBarrier;
11 import java.util.concurrent.atomic.AtomicLong;
12
13 import org.junit.Test;
14 import org.slf4j.Logger;
15 import org.slf4j.LoggerAccessingThread;
16 import org.slf4j.LoggerFactory;
17 import org.slf4j.event.EventRecodingLogger;
18
19 abstract public class MultithreadedInitializationTest {
20 final protected static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
21
22 private final List<Logger> createdLoggers = Collections.synchronizedList(new ArrayList<Logger>());
23
24 final private AtomicLong eventCount = new AtomicLong(0);
25 final private CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
26
27 int diff = new Random().nextInt(10000);
28
29 @Test
30 public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException {
31 @SuppressWarnings("unused")
32 LoggerAccessingThread[] accessors = harness();
33
34 Logger logger = LoggerFactory.getLogger(getClass().getName());
35 logger.info("hello");
36 eventCount.getAndIncrement();
37
38 assertAllSubstLoggersAreFixed();
39 long recordedEventCount = getRecordedEventCount();
40 int LENIENCY_COUNT = 16;
41
42 long expectedEventCount = eventCount.get() + extraLogEvents();
43
44 assertTrue(expectedEventCount + " >= " + recordedEventCount, expectedEventCount >= recordedEventCount);
45 assertTrue(expectedEventCount + " < " + recordedEventCount + "+" + LENIENCY_COUNT, expectedEventCount < recordedEventCount + LENIENCY_COUNT);
46 }
47
48 abstract protected long getRecordedEventCount();
49
50 protected int extraLogEvents() {
51 return 0;
52 }
53
54 private void assertAllSubstLoggersAreFixed() {
55 for (Logger logger : createdLoggers) {
56 if (logger instanceof SubstituteLogger) {
57 SubstituteLogger substLogger = (SubstituteLogger) logger;
58 if (substLogger.delegate() instanceof EventRecodingLogger)
59 fail("substLogger " + substLogger.getName() + " has a delegate of type EventRecodingLogger");
60 }
61 }
62 }
63
64 private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
65 LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT];
66 for (int i = 0; i < THREAD_COUNT; i++) {
67 threads[i] = new LoggerAccessingThread(barrier, createdLoggers, i, eventCount);
68 threads[i].start();
69 }
70
71 // trigger barrier
72 barrier.await();
73
74 for (int i = 0; i < THREAD_COUNT; i++) {
75 threads[i].join();
76 }
77
78 return threads;
79 }
80 }
3939 import org.junit.Test;
4040 import org.slf4j.Logger;
4141 import org.slf4j.event.EventRecodingLogger;
42 import org.slf4j.helpers.SubstituteLogger;
4243
4344 /**
4445 * @author Chetan Mehrotra
4849
4950 @Test
5051 public void testDelegate() throws Exception {
51 SubstituteLogger log = new SubstituteLogger("foo", null);
52 SubstituteLogger log = new SubstituteLogger("foo", null, false);
5253 assertTrue(log.delegate() instanceof EventRecodingLogger);
5354
5455 Set<String> expectedMethodSignatures = determineMethodSignatures(Logger.class);
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-ext</artifactId>
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-jcl</artifactId>
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-jdk14</artifactId>
0 package org.slf4j.helpers;
1
2 import java.util.concurrent.atomic.AtomicLong;
3 import java.util.logging.Handler;
4 import java.util.logging.LogRecord;
5
6 public class CountingHandler extends Handler {
7
8 final AtomicLong eventCount = new AtomicLong(0);
9
10 @Override
11 public void publish(LogRecord record) {
12 eventCount.getAndIncrement();
13 }
14
15 @Override
16 public void flush() {
17 }
18
19 @Override
20 public void close() throws SecurityException {
21 }
22
23 }
0 /**
1 * Copyright (c) 2004-2016 QOS.ch
2 * All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24 package org.slf4j.helpers;
25
26 import static org.junit.Assert.fail;
27
28 import java.util.logging.Handler;
29
30 import org.junit.After;
31 import org.junit.Before;
32
33 public class JDK14MultithreadedInitializationTest extends MultithreadedInitializationTest {
34
35 java.util.logging.Logger julRootLogger = java.util.logging.Logger.getLogger("");
36 java.util.logging.Logger julOrgLogger = java.util.logging.Logger.getLogger("org");
37
38 @Before
39 public void addRecordingHandler() {
40 System.out.println("THREAD_COUNT=" + THREAD_COUNT);
41 removeAllHandlers(julRootLogger);
42 removeAllHandlers(julOrgLogger);
43 julOrgLogger.addHandler(new CountingHandler());
44 }
45
46 private void removeAllHandlers(java.util.logging.Logger logger) {
47 Handler[] handlers = logger.getHandlers();
48 for (int i = 0; i < handlers.length; i++) {
49 logger.removeHandler(handlers[i]);
50 }
51 }
52
53 @After
54 public void tearDown() throws Exception {
55 removeAllHandlers(julOrgLogger);
56 }
57
58 protected long getRecordedEventCount() {
59 CountingHandler ra = findRecordingHandler();
60 if (ra == null) {
61 fail("failed to fing RecordingHandler");
62 }
63 return ra.eventCount.get();
64 }
65
66 private CountingHandler findRecordingHandler() {
67 Handler[] handlers = julOrgLogger.getHandlers();
68 for (Handler h : handlers) {
69 if (h instanceof CountingHandler)
70 return (CountingHandler) h;
71 }
72 return null;
73 }
74
75 }
+0
-24
slf4j-jdk14/src/test/java/org/slf4j/impl/CountingHandler.java less more
0 package org.slf4j.impl;
1
2 import java.util.concurrent.atomic.AtomicLong;
3 import java.util.logging.Handler;
4 import java.util.logging.LogRecord;
5
6 public class CountingHandler extends Handler {
7
8 final AtomicLong eventCount = new AtomicLong(0);
9
10 @Override
11 public void publish(LogRecord record) {
12 eventCount.getAndIncrement();
13 }
14
15 @Override
16 public void flush() {
17 }
18
19 @Override
20 public void close() throws SecurityException {
21 }
22
23 }
+0
-123
slf4j-jdk14/src/test/java/org/slf4j/impl/JDK14MultithreadedInitializationTest.java less more
0 /**
1 * Copyright (c) 2004-2016 QOS.ch
2 * All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24 package org.slf4j.impl;
25
26 import static org.junit.Assert.assertTrue;
27 import static org.junit.Assert.fail;
28
29 import java.util.Random;
30 import java.util.concurrent.BrokenBarrierException;
31 import java.util.concurrent.CyclicBarrier;
32 import java.util.concurrent.atomic.AtomicLong;
33 import java.util.logging.Handler;
34
35 import org.junit.After;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.slf4j.Logger;
39 import org.slf4j.LoggerAccessingThread;
40 import org.slf4j.LoggerFactory;
41
42 public class JDK14MultithreadedInitializationTest {
43
44 final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
45
46 final private AtomicLong eventCount = new AtomicLong(0);
47 final private CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
48
49 int diff = new Random().nextInt(10000);
50
51 java.util.logging.Logger julRootLogger = java.util.logging.Logger.getLogger("");
52 java.util.logging.Logger julOrgLogger = java.util.logging.Logger.getLogger("org");
53
54 @Before
55 public void addRecordingHandler() {
56 System.out.println("THREAD_COUNT=" + THREAD_COUNT);
57 removeAllHandlers(julRootLogger);
58 removeAllHandlers(julOrgLogger);
59 julOrgLogger.addHandler(new CountingHandler());
60 }
61
62 private void removeAllHandlers(java.util.logging.Logger logger) {
63 Handler[] handlers = logger.getHandlers();
64 for (int i = 0; i < handlers.length; i++) {
65 logger.removeHandler(handlers[i]);
66 }
67 }
68
69 @After
70 public void tearDown() throws Exception {
71 removeAllHandlers(julOrgLogger);
72 }
73
74 @Test
75 public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException {
76 @SuppressWarnings("unused")
77 LoggerAccessingThread[] accessors = harness();
78
79 Logger logger = LoggerFactory.getLogger(getClass().getName());
80 logger.info("hello");
81 eventCount.getAndIncrement();
82
83 long recordedEventCount = getRecordedEventCount();
84 assertTrue(eventCount.get() + " >= " + recordedEventCount, eventCount.get() >= recordedEventCount);
85 assertTrue(eventCount.get() + " < " + recordedEventCount + "+10", eventCount.get() < recordedEventCount + 10);
86 }
87
88 private long getRecordedEventCount() {
89 CountingHandler ra = findRecordingHandler();
90 if (ra == null) {
91 fail("failed to fing RecordingHandler");
92 }
93 return ra.eventCount.get();
94 }
95
96 private CountingHandler findRecordingHandler() {
97 Handler[] handlers = julOrgLogger.getHandlers();
98 for (Handler h : handlers) {
99 if (h instanceof CountingHandler)
100 return (CountingHandler) h;
101 }
102 return null;
103 }
104
105 private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
106 LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT];
107 for (int i = 0; i < THREAD_COUNT; i++) {
108 threads[i] = new LoggerAccessingThread(barrier, i, eventCount);
109 threads[i].start();
110 }
111
112 // trigger barrier
113 barrier.await();
114
115 for (int i = 0; i < THREAD_COUNT; i++) {
116 threads[i].join();
117 }
118
119 return threads;
120 }
121
122 }
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-log4j12</artifactId>
2323 */
2424 package org.slf4j.impl;
2525
26 import static org.junit.Assert.assertEquals;
27
2826 import java.util.List;
29 import java.util.Random;
30 import java.util.concurrent.BrokenBarrierException;
31 import java.util.concurrent.CyclicBarrier;
32 import java.util.concurrent.atomic.AtomicLong;
3327
3428 import org.apache.log4j.LogManager;
3529 import org.apache.log4j.spi.LoggingEvent;
3630 import org.junit.After;
3731 import org.junit.Before;
38 import org.junit.Test;
39 import org.slf4j.Logger;
40 import org.slf4j.LoggerAccessingThread;
41 import org.slf4j.LoggerFactory;
32 import static org.junit.Assert.assertNotNull;
4233
43 public class Log4j12MultithreadedInitializationTest {
34 import org.slf4j.helpers.MultithreadedInitializationTest;
4435
36 public class Log4j12MultithreadedInitializationTest extends MultithreadedInitializationTest {
37 static int NUM_LINES_BY_RECURSIVE_APPENDER = 3;
38
4539 // value of LogManager.DEFAULT_CONFIGURATION_KEY;
4640 static String CONFIG_FILE_KEY = "log4j.configuration";
47
48 final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
49
50 private final AtomicLong eventCount = new AtomicLong(0);
51
52 private final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
53
54 final int diff = new Random().nextInt(10000);
5541 final String loggerName = this.getClass().getName();
5642
5743 @Before
5844 public void setup() {
59 System.out.println("THREAD_COUNT=" + THREAD_COUNT);
45 System.setProperty(CONFIG_FILE_KEY, "recursiveInitWithActivationDelay.properties");
46 System.out.println("THREAD_COUNT=" + THREAD_COUNT);
6047 }
6148
6249 @After
6451 System.clearProperty(CONFIG_FILE_KEY);
6552 }
6653
67 @Test
68 public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException {
69
70 System.setProperty(CONFIG_FILE_KEY, "recursiveInitWithActivationDelay.properties");
71
72 @SuppressWarnings("unused")
73 LoggerAccessingThread[] accessors = harness();
74
75 Logger logger = LoggerFactory.getLogger(loggerName + ".slowInitialization-" + diff);
76 logger.info("hello");
77 eventCount.getAndIncrement();
78
79 List<LoggingEvent> events = getRecordedEvents();
80 int NUM_LINES_BY_RECURSIVE_APPENDER = 3;
81 assertEquals(eventCount.get() + NUM_LINES_BY_RECURSIVE_APPENDER, events.size());
54 protected long getRecordedEventCount() {
55 List<LoggingEvent> eventList = getRecordedEvents();
56 assertNotNull(eventList);
57 return eventList.size();
8258 }
8359
60 protected int extraLogEvents() {
61 return NUM_LINES_BY_RECURSIVE_APPENDER;
62 }
63
8464 private List<LoggingEvent> getRecordedEvents() {
8565 org.apache.log4j.Logger root = LogManager.getRootLogger();
8666
8767 RecursiveAppender ra = (RecursiveAppender) root.getAppender("RECURSIVE");
68 assertNotNull(ra);
8869 return ra.events;
8970 }
9071
91 private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
92 LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT];
93 for (int i = 0; i < THREAD_COUNT; i++) {
94 threads[i] = new LoggerAccessingThread(barrier, i, eventCount);
95 threads[i].start();
96 }
97
98 barrier.await();
99 for (int i = 0; i < THREAD_COUNT; i++) {
100 threads[i].join();
101 }
102 return threads;
103 }
104
10572 }
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-migrator</artifactId>
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-nop</artifactId>
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-simple</artifactId>
0 /**
1 * Copyright (c) 2004-2016 QOS.ch
2 * All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24 package org.slf4j.helpers;
25
26 import java.io.PrintStream;
27 import java.util.ArrayList;
28 import java.util.Collections;
29 import java.util.List;
30
31 import org.junit.After;
32 import org.junit.Before;
33 import org.slf4j.LoggerFactoryFriend;
34 import org.slf4j.impl.SimpleLogger;
35
36 public class SimpleLoggerMultithreadedInitializationTest extends MultithreadedInitializationTest {
37 // final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
38 // private final List<Logger> createdLoggers = Collections.synchronizedList(new ArrayList<Logger>());
39 // private final AtomicLong eventCount = new AtomicLong(0);
40 //
41 // private final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
42 //
43 // final int diff = new Random().nextInt(10000);
44 static int NUM_LINES_IN_SLF4J_REPLAY_WARNING = 3;
45 private final PrintStream oldErr = System.err;
46 final String loggerName = this.getClass().getName();
47 StringPrintStream sps = new StringPrintStream(oldErr, true);
48
49 @Before
50 public void setup() {
51 System.out.println("THREAD_COUNT=" + THREAD_COUNT);
52 System.setErr(sps);
53 System.setProperty(SimpleLogger.LOG_FILE_KEY, "System.err");
54 LoggerFactoryFriend.reset();
55 }
56
57 @After
58 public void tearDown() throws Exception {
59 LoggerFactoryFriend.reset();
60 System.clearProperty(SimpleLogger.LOG_FILE_KEY);
61 System.setErr(oldErr);
62 }
63
64 @Override
65 protected long getRecordedEventCount() {
66 return sps.stringList.size();
67 };
68
69 @Override
70 protected int extraLogEvents() {
71 return NUM_LINES_IN_SLF4J_REPLAY_WARNING;
72 }
73
74 static class StringPrintStream extends PrintStream {
75
76 public static final String LINE_SEP = System.getProperty("line.separator");
77 PrintStream other;
78 boolean duplicate = false;
79
80 List<String> stringList = Collections.synchronizedList(new ArrayList<String>());
81
82 public StringPrintStream(PrintStream ps, boolean duplicate) {
83 super(ps);
84 other = ps;
85 this.duplicate = duplicate;
86 }
87
88 public StringPrintStream(PrintStream ps) {
89 this(ps, false);
90 }
91
92 public void print(String s) {
93 if (duplicate)
94 other.print(s);
95 stringList.add(s);
96 }
97
98 public void println(String s) {
99 if (duplicate)
100 other.println(s);
101 stringList.add(s);
102 }
103
104 public void println(Object o) {
105 if (duplicate)
106 other.println(o);
107 stringList.add(o.toString());
108 }
109 }
110
111 }
+0
-144
slf4j-simple/src/test/java/org/slf4j/impl/SimpleLoggerMultithreadedInitializationTest.java less more
0 /**
1 * Copyright (c) 2004-2016 QOS.ch
2 * All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 *
23 */
24 package org.slf4j.impl;
25
26 import static org.junit.Assert.assertTrue;
27
28 import java.io.PrintStream;
29 import java.util.ArrayList;
30 import java.util.Collections;
31 import java.util.List;
32 import java.util.Random;
33 import java.util.concurrent.BrokenBarrierException;
34 import java.util.concurrent.CyclicBarrier;
35 import java.util.concurrent.atomic.AtomicLong;
36
37 import org.junit.After;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.slf4j.Logger;
41 import org.slf4j.LoggerAccessingThread;
42 import org.slf4j.LoggerFactory;
43 import org.slf4j.LoggerFactoryFriend;
44
45 public class SimpleLoggerMultithreadedInitializationTest {
46
47 final static int THREAD_COUNT = 4 + Runtime.getRuntime().availableProcessors() * 2;
48
49 private final AtomicLong eventCount = new AtomicLong(0);
50 private final PrintStream oldErr = System.err;
51 private final CyclicBarrier barrier = new CyclicBarrier(THREAD_COUNT + 1);
52
53 final int diff = new Random().nextInt(10000);
54 final String loggerName = this.getClass().getName();
55 StringPrintStream sps = new StringPrintStream(oldErr, true);
56
57 @Before
58 public void setup() {
59 System.out.println("THREAD_COUNT=" + THREAD_COUNT);
60 System.setErr(sps);
61 System.setProperty(SimpleLogger.LOG_FILE_KEY, "System.err");
62 LoggerFactoryFriend.reset();
63 }
64
65 @After
66 public void tearDown() throws Exception {
67 LoggerFactoryFriend.reset();
68 System.clearProperty(SimpleLogger.LOG_FILE_KEY);
69 System.setErr(oldErr);
70 }
71
72 @Test
73 public void multiThreadedInitialization() throws InterruptedException, BrokenBarrierException {
74
75 @SuppressWarnings("unused")
76 LoggerAccessingThread[] accessors = harness();
77
78 Logger logger = LoggerFactory.getLogger(loggerName + diff);
79 logger.info("hello");
80 eventCount.getAndIncrement();
81
82 int NUM_LINES_IN_SLF4J_REPLAY_WARNING = 3;
83
84 long expected = eventCount.get() + NUM_LINES_IN_SLF4J_REPLAY_WARNING;
85 int actual = sps.stringList.size();
86 assertTrue(expected + " >= " + actual, expected >= actual);
87 assertTrue(expected + " < " + actual + " + 16", expected < actual + 16);
88 }
89
90 private LoggerAccessingThread[] harness() throws InterruptedException, BrokenBarrierException {
91 final LoggerAccessingThread[] threads = new LoggerAccessingThread[THREAD_COUNT];
92 for (int i = 0; i < THREAD_COUNT; i++) {
93 LoggerAccessingThread simpleLoggerThread = new LoggerAccessingThread(barrier, i, eventCount);
94 threads[i] = simpleLoggerThread;
95 simpleLoggerThread.start();
96 }
97
98 barrier.await();
99 for (int i = 0; i < THREAD_COUNT; i++) {
100 threads[i].join();
101 }
102 return threads;
103 }
104
105
106 static class StringPrintStream extends PrintStream {
107
108 public static final String LINE_SEP = System.getProperty("line.separator");
109 PrintStream other;
110 boolean duplicate = false;
111
112 List<String> stringList = Collections.synchronizedList(new ArrayList<String>());
113
114 public StringPrintStream(PrintStream ps, boolean duplicate) {
115 super(ps);
116 other = ps;
117 this.duplicate = duplicate;
118 }
119
120 public StringPrintStream(PrintStream ps) {
121 this(ps, false);
122 }
123
124 public void print(String s) {
125 if (duplicate)
126 other.print(s);
127 stringList.add(s);
128 }
129
130 public void println(String s) {
131 if (duplicate)
132 other.println(s);
133 stringList.add(s);
134 }
135
136 public void println(Object o) {
137 if (duplicate)
138 other.println(o);
139 stringList.add(o.toString());
140 }
141 };
142
143 }
66 <parent>
77 <groupId>org.slf4j</groupId>
88 <artifactId>slf4j-parent</artifactId>
9 <version>1.7.20</version>
9 <version>1.7.21</version>
1010 </parent>
1111
1212 <artifactId>slf4j-site</artifactId>