| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package org.apache.log4j; |
| |
| import junit.framework.TestCase; |
| |
| import java.util.Vector; |
| |
| import org.apache.log4j.spi.LoggingEvent; |
| |
| /** |
| A superficial but general test of log4j. |
| */ |
| public class AsyncAppenderTestCase extends TestCase { |
| |
| public AsyncAppenderTestCase(String name) { |
| super(name); |
| } |
| |
| public void setUp() { |
| } |
| |
| public void tearDown() { |
| LogManager.shutdown(); |
| } |
| |
| // this test checks whether it is possible to write to a closed AsyncAppender |
| public void closeTest() throws Exception { |
| Logger root = Logger.getRootLogger(); |
| VectorAppender vectorAppender = new VectorAppender(); |
| AsyncAppender asyncAppender = new AsyncAppender(); |
| asyncAppender.setName("async-CloseTest"); |
| asyncAppender.addAppender(vectorAppender); |
| root.addAppender(asyncAppender); |
| |
| root.debug("m1"); |
| asyncAppender.close(); |
| root.debug("m2"); |
| |
| Vector v = vectorAppender.getVector(); |
| assertEquals(v.size(), 1); |
| } |
| |
| // this test checks whether appenders embedded within an AsyncAppender are also |
| // closed |
| public void test2() { |
| Logger root = Logger.getRootLogger(); |
| VectorAppender vectorAppender = new VectorAppender(); |
| AsyncAppender asyncAppender = new AsyncAppender(); |
| asyncAppender.setName("async-test2"); |
| asyncAppender.addAppender(vectorAppender); |
| root.addAppender(asyncAppender); |
| |
| root.debug("m1"); |
| asyncAppender.close(); |
| root.debug("m2"); |
| |
| Vector v = vectorAppender.getVector(); |
| assertEquals(v.size(), 1); |
| assertTrue(vectorAppender.isClosed()); |
| } |
| |
| // this test checks whether appenders embedded within an AsyncAppender are also |
| // closed |
| public void test3() { |
| int LEN = 200; |
| Logger root = Logger.getRootLogger(); |
| VectorAppender vectorAppender = new VectorAppender(); |
| AsyncAppender asyncAppender = new AsyncAppender(); |
| asyncAppender.setName("async-test3"); |
| asyncAppender.addAppender(vectorAppender); |
| root.addAppender(asyncAppender); |
| |
| for(int i = 0; i < LEN; i++) { |
| root.debug("message"+i); |
| } |
| |
| asyncAppender.close(); |
| root.debug("m2"); |
| |
| Vector v = vectorAppender.getVector(); |
| assertEquals(v.size(), LEN); |
| assertTrue(vectorAppender.isClosed()); |
| } |
| |
| private static class NullPointerAppender extends AppenderSkeleton { |
| public NullPointerAppender() { |
| } |
| |
| |
| /** |
| This method is called by the {@link org.apache.log4j.AppenderSkeleton#doAppend} |
| method. |
| |
| */ |
| public void append(org.apache.log4j.spi.LoggingEvent event) { |
| throw new NullPointerException(); |
| } |
| |
| public void close() { |
| } |
| |
| public boolean requiresLayout() { |
| return false; |
| } |
| } |
| |
| |
| /** |
| * Tests that a bad appender will switch async back to sync. |
| * See bug 23021 |
| * @since 1.2.12 |
| * @throws Exception thrown if Thread.sleep is interrupted |
| */ |
| public void testBadAppender() throws Exception { |
| Appender nullPointerAppender = new NullPointerAppender(); |
| AsyncAppender asyncAppender = new AsyncAppender(); |
| asyncAppender.addAppender(nullPointerAppender); |
| asyncAppender.setBufferSize(5); |
| asyncAppender.activateOptions(); |
| Logger root = Logger.getRootLogger(); |
| root.addAppender(nullPointerAppender); |
| try { |
| root.info("Message"); |
| Thread.sleep(10); |
| root.info("Message"); |
| fail("Should have thrown exception"); |
| } catch(NullPointerException ex) { |
| |
| } |
| } |
| |
| /** |
| * Tests location processing when buffer is full and locationInfo=true. |
| * See bug 41186. |
| */ |
| public void testLocationInfoTrue() { |
| BlockableVectorAppender blockableAppender = new BlockableVectorAppender(); |
| AsyncAppender async = new AsyncAppender(); |
| async.addAppender(blockableAppender); |
| async.setBufferSize(5); |
| async.setLocationInfo(true); |
| async.setBlocking(false); |
| async.activateOptions(); |
| Logger rootLogger = Logger.getRootLogger(); |
| rootLogger.addAppender(async); |
| Greeter greeter = new Greeter(rootLogger, 100); |
| synchronized(blockableAppender.getMonitor()) { |
| greeter.run(); |
| rootLogger.error("That's all folks."); |
| } |
| async.close(); |
| Vector events = blockableAppender.getVector(); |
| LoggingEvent initialEvent = (LoggingEvent) events.get(0); |
| LoggingEvent discardEvent = (LoggingEvent) events.get(events.size() - 1); |
| PatternLayout layout = new PatternLayout(); |
| layout.setConversionPattern("%C:%L %m%n"); |
| layout.activateOptions(); |
| String initialStr = layout.format(initialEvent); |
| assertEquals(AsyncAppenderTestCase.class.getName(), |
| initialStr.substring(0, AsyncAppenderTestCase.class.getName().length())); |
| String discardStr = layout.format(discardEvent); |
| assertEquals("?:? ", discardStr.substring(0, 4)); |
| } |
| |
| |
| /** |
| * Tests location processing when buffer is full and locationInfo=false. |
| * See bug 41186. |
| */ |
| public void testLocationInfoFalse() { |
| BlockableVectorAppender blockableAppender = new BlockableVectorAppender(); |
| AsyncAppender async = new AsyncAppender(); |
| async.addAppender(blockableAppender); |
| async.setBufferSize(5); |
| async.setLocationInfo(false); |
| async.setBlocking(false); |
| async.activateOptions(); |
| Logger rootLogger = Logger.getRootLogger(); |
| rootLogger.addAppender(async); |
| Greeter greeter = new Greeter(rootLogger, 100); |
| synchronized(blockableAppender.getMonitor()) { |
| greeter.run(); |
| rootLogger.error("That's all folks."); |
| } |
| async.close(); |
| Vector events = blockableAppender.getVector(); |
| LoggingEvent initialEvent = (LoggingEvent) events.get(0); |
| LoggingEvent discardEvent = (LoggingEvent) events.get(events.size() - 1); |
| PatternLayout layout = new PatternLayout(); |
| layout.setConversionPattern("%C:%L %m%n"); |
| layout.activateOptions(); |
| String initialStr = layout.format(initialEvent); |
| assertEquals("?:? ", initialStr.substring(0, 4)); |
| String discardStr = layout.format(discardEvent); |
| assertEquals("?:? ", discardStr.substring(0, 4)); |
| } |
| |
| /** |
| * Logging request runnable. |
| */ |
| private static final class Greeter implements Runnable { |
| /** |
| * Logger. |
| */ |
| private final Logger logger; |
| |
| /** |
| * Repetitions. |
| */ |
| private final int repetitions; |
| |
| /** |
| * Create new instance. |
| * @param logger logger, may not be null. |
| * @param repetitions repetitions. |
| */ |
| public Greeter(final Logger logger, final int repetitions) { |
| if (logger == null) { |
| throw new IllegalArgumentException("logger"); |
| } |
| |
| this.logger = logger; |
| this.repetitions = repetitions; |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void run() { |
| try { |
| for (int i = 0; i < repetitions; i++) { |
| logger.info("Hello, World"); |
| Thread.sleep(1); |
| } |
| } catch (InterruptedException ex) { |
| Thread.currentThread().interrupt(); |
| } |
| } |
| } |
| |
| |
| |
| /** |
| * Vector appender that can be explicitly blocked. |
| */ |
| private static final class BlockableVectorAppender extends VectorAppender { |
| /** |
| * Monitor object used to block appender. |
| */ |
| private final Object monitor = new Object(); |
| |
| |
| /** |
| * Create new instance. |
| */ |
| public BlockableVectorAppender() { |
| super(); |
| } |
| |
| /** |
| * {@inheritDoc} |
| */ |
| public void append(final LoggingEvent event) { |
| synchronized (monitor) { |
| super.append(event); |
| // |
| // if fatal, echo messages for testLoggingInDispatcher |
| // |
| if (event.getLevel() == Level.FATAL) { |
| Logger logger = Logger.getLogger(event.getLoggerName()); |
| logger.error(event.getMessage().toString()); |
| logger.warn(event.getMessage().toString()); |
| logger.info(event.getMessage().toString()); |
| logger.debug(event.getMessage().toString()); |
| } |
| } |
| } |
| |
| /** |
| * Get monitor object. |
| * @return monitor. |
| */ |
| public Object getMonitor() { |
| return monitor; |
| } |
| |
| } |
| |
| |
| /** |
| * Test that a mutable message object is evaluated before |
| * being placed in the async queue. |
| * See bug 43559. |
| */ |
| public void testMutableMessage() { |
| BlockableVectorAppender blockableAppender = new BlockableVectorAppender(); |
| AsyncAppender async = new AsyncAppender(); |
| async.addAppender(blockableAppender); |
| async.setBufferSize(5); |
| async.setLocationInfo(false); |
| async.activateOptions(); |
| Logger rootLogger = Logger.getRootLogger(); |
| rootLogger.addAppender(async); |
| StringBuffer buf = new StringBuffer("Hello"); |
| synchronized(blockableAppender.getMonitor()) { |
| rootLogger.info(buf); |
| buf.append(", World."); |
| } |
| async.close(); |
| Vector events = blockableAppender.getVector(); |
| LoggingEvent event = (LoggingEvent) events.get(0); |
| PatternLayout layout = new PatternLayout(); |
| layout.setConversionPattern("%m"); |
| layout.activateOptions(); |
| String msg = layout.format(event); |
| assertEquals("Hello", msg); |
| } |
| |
| |
| |
| } |