Index: log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerWriterTest.java =================================================================== --- log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerWriterTest.java (revision 1581623) +++ log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerWriterTest.java (working copy) @@ -1,140 +0,0 @@ -/* - * 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.logging.log4j.spi; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.TestLogger; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.io.IOException; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import static org.hamcrest.core.StringStartsWith.startsWith; -import static org.junit.Assert.*; - -@RunWith(Parameterized.class) -public class LoggerWriterTest { - private List results; - private LoggerWriter writer; - private final Level level; - private final String logMessage; - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList(new Object[][] { { Level.DEBUG, "debug log string test" }, { Level.INFO, "info log string test" }, { Level.WARN, "DANGER ZONE" }, - { Level.ERROR, "MAYDAY! MAYDAY!" }, { Level.FATAL, "ABANDON SHIP!" } }); - } - - public LoggerWriterTest(final Level level, final String logMessage) { - this.level = level; - this.logMessage = logMessage; - } - - @Before - public void setUp() throws Exception { - TestLogger logger = (TestLogger) LogManager.getLogger(); - results = logger.getEntries(); - assertEmpty(); - writer = new LoggerWriter(logger, null, level); - assertEmpty(); - } - - @After - public void tearDown() throws Exception { - results.clear(); - } - - private void assertEmpty() { - assertTrue("There should be no results yet.", results.isEmpty()); - } - - private void assertNumResults(int numResults) { - assertEquals("Unexpected number of results.", numResults, results.size()); - } - - private void assertMessages(final String... messages) { - assertNumResults(messages.length); - for (int i = 0; i < messages.length; i++) { - final String start = ' ' + level.name() + ' ' + messages[i]; - assertThat(results.get(i), startsWith(start)); - } - } - - @Test - public void testWrite_CharArray() throws Exception { - final char[] chars = logMessage.toCharArray(); - writer.write(chars); - assertEmpty(); - writer.write('\n'); - assertMessages(logMessage); - } - - @Test - public void testWrite_CharArray_Offset_Length() throws Exception { - final char[] chars = logMessage.toCharArray(); - int middle = chars.length / 2; - int length = chars.length - middle; - final String right = new String(chars, middle, length); - writer.write(chars, middle, length); - assertEmpty(); - writer.write('\n'); - assertMessages(right); - } - - @Test - public void testWrite_Character() throws Exception { - for (char c : logMessage.toCharArray()) { - writer.write(c); - assertEmpty(); - } - writer.write('\n'); - assertMessages(logMessage); - } - - @Test - public void testWrite_IgnoresWindowsNewline() throws IOException { - writer.write(logMessage + "\r\n"); - assertMessages(logMessage); - } - - @Test - public void testWrite_MultipleLines() throws IOException { - writer.write(logMessage + '\n' + logMessage + '\n'); - assertMessages(logMessage, logMessage); - } - - @Test - public void testClose_NoRemainingData() throws IOException { - writer.close(); - assertEmpty(); - } - - @Test - public void testClose_HasRemainingData() throws IOException { - writer.write(logMessage); - assertEmpty(); - writer.close(); - assertMessages(logMessage); - } -} Index: log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerStreamTest.java =================================================================== --- log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerStreamTest.java (revision 1581623) +++ log4j-api/src/test/java/org/apache/logging/log4j/spi/LoggerStreamTest.java (working copy) @@ -1,184 +0,0 @@ -/* - * 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.logging.log4j.spi; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.TestLogger; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -import java.util.Arrays; -import java.util.Collection; -import java.util.List; - -import static org.hamcrest.core.StringStartsWith.startsWith; -import static org.junit.Assert.*; - -@RunWith(Parameterized.class) -public class LoggerStreamTest { - private List results; - private LoggerStream stream; - private final Level level; - private final String logMessage; - - @Parameterized.Parameters - public static Collection data() { - return Arrays.asList( - new Object[][]{ - { Level.DEBUG, "debug log string test" }, - { Level.INFO, "info log string test" }, - { Level.WARN, "DANGER ZONE" }, - { Level.ERROR, "MAYDAY! MAYDAY!" }, - { Level.FATAL, "ABANDON SHIP!" } - } - ); - } - - public LoggerStreamTest(final Level level, final String logMessage) { - this.level = level; - this.logMessage = logMessage; - } - - @Before - public void setUp() throws Exception { - TestLogger logger = (TestLogger) LogManager.getLogger(); - results = logger.getEntries(); - assertEmpty(); - stream = new LoggerStream(logger, level); - assertEmpty(); - } - - @After - public void tearDown() throws Exception { - results.clear(); - } - - private void assertEmpty() { - assertTrue("There should be no results yet.", results.isEmpty()); - } - - private void assertNumResults(int numResults) { - assertEquals("Unexpected number of results.", numResults, results.size()); - } - - private void assertMessageStartsWith(final String message) { - assertNumResults(1); - final String start = ' ' + level.name() + ' ' + message; - assertThat(results.get(0), startsWith(start)); - } - - @Test - public void testWrite_Int() throws Exception { - for (byte b : logMessage.getBytes()) { - stream.write(b); - assertEmpty(); - } - stream.write('\n'); - assertMessageStartsWith(logMessage); - } - - @Test - public void testWrite_ByteArray() throws Exception { - final byte[] bytes = logMessage.getBytes(); - stream.write(bytes); - assertEmpty(); - stream.write('\n'); - assertMessageStartsWith(logMessage); - } - - @Test - public void testWrite_ByteArray_Offset_Length() throws Exception { - final byte[] bytes = logMessage.getBytes(); - int middle = bytes.length/2; - int length = bytes.length - middle; - final String right = new String(bytes, middle, length); - stream.write(bytes, middle, length); - assertEmpty(); - stream.write('\n'); - assertMessageStartsWith(right); - } - - @Test - public void testPrint_Boolean() throws Exception { - stream.print(true); - assertEmpty(); - stream.println(); - assertMessageStartsWith("true"); - } - - @Test - public void testPrint_Character() throws Exception { - for (char c : logMessage.toCharArray()) { - stream.print(c); - assertEmpty(); - } - stream.println(); - assertMessageStartsWith(logMessage); - } - - @Test - public void testPrint_Integer() throws Exception { - int n = logMessage.codePointAt(0); - stream.print(n); - assertEmpty(); - stream.println(); - assertMessageStartsWith(String.valueOf(n)); - } - - @Test - public void testPrint_CharacterArray() throws Exception { - stream.print(logMessage.toCharArray()); - assertEmpty(); - stream.println(); - assertMessageStartsWith(logMessage); - } - - @Test - public void testPrint_String() throws Exception { - stream.print(logMessage); - assertEmpty(); - stream.println(); - assertMessageStartsWith(logMessage); - } - - @Test - public void testPrint_Object() throws Exception { - final Object o = logMessage; - stream.print(o); - assertEmpty(); - stream.println(); - assertMessageStartsWith(logMessage); - } - - @Test - public void testPrintf() throws Exception { - stream.printf("<<<%s>>>", logMessage); - assertEmpty(); - stream.println(); - assertMessageStartsWith("<<<" + logMessage); - } - - @Test - public void testFormat() throws Exception { - stream.format("[%s]", logMessage).println(); - assertMessageStartsWith("[" + logMessage); - } -} Index: log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerStream.java =================================================================== --- log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerStream.java (revision 1581623) +++ log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerStream.java (working copy) @@ -1,290 +0,0 @@ -/* - * 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.logging.log4j.spi; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.message.Message; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.PrintStream; -import java.util.Locale; - -/** - * Output stream that logs each line written to a pre-defined level. Can also - * be configured with a Marker. This class provides an interface that follows - * the {@link java.io.PrintStream} methods in spirit, but doesn't output to - * any external stream. This class should not be used as a stream for an - * underlying logger unless it's being used as a bridge. Otherwise, infinite - * loops may occur! - */ -public class LoggerStream extends PrintStream { - - final PrintStream stream; - - public LoggerStream(final AbstractLoggerProvider logger, final Level level) { - super(System.out); - stream = new PrintStream(new HelperStream(logger, null, level), true); - } - - public LoggerStream(final AbstractLoggerProvider logger, final Marker marker, final Level level) { - super(System.out); - stream = new PrintStream(new HelperStream(logger, marker, level), true); - } - - @Override - public void write(int b) { - stream.write(b); - } - - @Override - public void write(byte[] b) throws IOException { - stream.write(b); - } - - @Override - public void write(byte[] b, int off, int len) { - stream.write(b, off, len); - } - - @Override - public void flush() { - stream.flush(); - } - - @Override - public void close() { - stream.close(); - } - - @Override - public void print(boolean b) { - stream.print(b); - } - - @Override - public void print(char c) { - stream.print(c); - } - - @Override - public void print(int i) { - stream.print(i); - } - - @Override - public void print(long l) { - stream.print(l); - } - - @Override - public void print(float f) { - stream.print(f); - } - - @Override - public void print(double d) { - stream.print(d); - } - - @Override - public void print(char[] s) { - stream.print(s); - } - - @Override - public void print(String s) { - stream.print(s); - } - - @Override - public void print(Object obj) { - stream.print(obj); - } - - @Override - public void println() { - stream.println(); - } - - @Override - public void println(boolean x) { - stream.println(x); - } - - @Override - public void println(char x) { - stream.println(x); - } - - @Override - public void println(int x) { - stream.println(x); - } - - @Override - public void println(long x) { - stream.println(x); - } - - @Override - public void println(float x) { - stream.println(x); - } - - @Override - public void println(double x) { - stream.println(x); - } - - @Override - public void println(char[] x) { - stream.println(x); - } - - @Override - public void println(String x) { - stream.println(x); - } - - @Override - public void println(Object x) { - stream.println(x); - } - - @Override - public LoggerStream printf(String format, Object... args) { - stream.printf(format, args); - return this; - } - - @Override - public LoggerStream printf(Locale l, String format, Object... args) { - stream.printf(l, format, args); - return this; - } - - @Override - public LoggerStream append(char c) { - stream.append(c); - return this; - } - - @Override - public LoggerStream append(CharSequence csq) { - stream.append(csq); - return this; - } - - @Override - public LoggerStream append(CharSequence csq, int start, int end) { - stream.append(csq, start, end); - return this; - } - - @Override - public LoggerStream format(String format, Object... args) { - stream.format(format, args); - return this; - } - - @Override - public LoggerStream format(Locale l, String format, Object... args) { - stream.format(l, format, args); - return this; - } - - @Override - public boolean checkError() { - return stream.checkError(); - } - - @Override - public String toString() { - return "LoggerStream{" + - "stream=" + stream + - '}'; - } - - @Override - public boolean equals(Object other) { - return this == other - || !(other == null || getClass() != other.getClass()) - && stream.equals(((LoggerStream) other).stream); - } - - @Override - public int hashCode() { - return stream.hashCode(); - } - - private static class HelperStream extends ByteArrayOutputStream { - private static final String FQCN = LoggerStream.class.getName(); - private final AbstractLoggerProvider logger; - private final Level level; - private final Marker marker; - - private HelperStream(AbstractLoggerProvider logger, Marker marker, Level level) { - this.logger = logger; - this.marker = marker; - this.level = level; - } - - private void log(int upTo) { - if (upTo < 0 || upTo >= count) { - throw new IndexOutOfBoundsException(); - } - final Message message = logger.getMessageFactory().newMessage(extractLine(upTo)); - logger.logIfEnabled(FQCN, level, marker, message, null); - } - - private String extractLine(int upTo) { - final String line = new String(buf, 0, upTo); - leftShiftBuffer(upTo + 1); - return line; - } - - private void leftShiftBuffer(int numBytes) { - int remaining = count - numBytes; - if (remaining > 0) { - System.arraycopy(buf, numBytes, buf, 0, remaining); - count = remaining + 1; - } else { - reset(); - } - } - - @Override - public synchronized void write(int b) { - if (b == '\r') { - return; - } - super.write(b); - if (b == '\n') { - log(count - 1); - } - } - - @Override - public synchronized void write(byte[] b, int off, int len) { - for (int i = 0; i < len; ++i) { - write(b[off + i]); - } - } - } -} Index: log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLoggerProvider.java =================================================================== --- log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLoggerProvider.java (revision 1581623) +++ log4j-api/src/main/java/org/apache/logging/log4j/spi/AbstractLoggerProvider.java (working copy) @@ -773,29 +773,6 @@ } /** - * Gets a print stream that logs lines to this logger. - * - * @param level the logging level - * @return print stream that logs printed lines to this logger. - */ - @Override - public PrintWriter printWriter(final Level level) { - return new PrintWriter(new LoggerWriter(this, null, level), true); - } - - /** - * Gets a marked print stream that logs lines to this logger. - * - * @param marker the marker data specific to this log statement - * @param level the logging level - * @return print stream that logs printed lines to this logger. - */ - @Override - public PrintWriter printWriter(Marker marker, Level level) { - return new PrintWriter(new LoggerWriter(this, marker, level), true); - } - - /** * Logs a message with the specific Marker at the INFO level. * * @param marker the marker data specific to this log statement Index: log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerWriter.java =================================================================== --- log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerWriter.java (revision 1581623) +++ log4j-api/src/main/java/org/apache/logging/log4j/spi/LoggerWriter.java (working copy) @@ -1,78 +0,0 @@ -/* - * 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.logging.log4j.spi; - -import java.io.IOException; -import java.io.Writer; - -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.Marker; -import org.apache.logging.log4j.message.Message; - -public class LoggerWriter extends Writer { - private static final String FQCN = LoggerWriter.class.getName(); - private final AbstractLoggerProvider logger; - private final Level level; - private final Marker marker; - private final StringBuilder buf = new StringBuilder(); - - public LoggerWriter(AbstractLoggerProvider logger, Marker marker, Level level) { - this.logger = logger; - this.marker = marker; - this.level = level; - } - - @Override - public void close() throws IOException { - // don't log a blank message if the last character was a newline - if (buf.length() > 0) { - log(); - } - } - - @Override - public void flush() throws IOException { - // flushing automatically happens when a newline is encountered - } - - @Override - public void write(char[] cbuf, int off, int len) throws IOException { - int currOff = off; - synchronized (buf) { - for (int pos = off; pos < off + len; pos++) { - switch (cbuf[pos]) { - case '\r': - buf.append(cbuf, currOff, pos - currOff); - currOff = pos + 1; - break; - case '\n': - buf.append(cbuf, currOff, pos - currOff); - currOff = pos + 1; - log(); - break; - } - } - buf.append(cbuf, currOff, len - (currOff - off)); - } - } - - private void log() { - final Message message = logger.getMessageFactory().newMessage(buf.toString()); - buf.setLength(0); - logger.logIfEnabled(FQCN, level, marker, message, null); - } -} Index: log4j-api/src/main/java/org/apache/logging/log4j/Logger.java =================================================================== --- log4j-api/src/main/java/org/apache/logging/log4j/Logger.java (revision 1581623) +++ log4j-api/src/main/java/org/apache/logging/log4j/Logger.java (working copy) @@ -472,23 +472,6 @@ String getName(); /** - * Gets a print stream that logs lines to this logger. - * - * @param level the logging level - * @return print stream that logs printed lines to this logger. - */ - PrintWriter printWriter(Level level); - - /** - * Gets a marked print stream that logs lines to this logger. - * - * @param marker the marker data specific to this log statement - * @param level the logging level - * @return print stream that logs printed lines to this logger. - */ - PrintWriter printWriter(Marker marker, Level level); - - /** * Logs a message with the specific Marker at the {@link Level#INFO INFO} level. * * @param marker the marker data specific to this log statement