I will look into it. Gary
On Thu, Aug 15, 2019, 17:03 Ralph Goers <[email protected]> wrote: > I believe you have not read this thread. I am not talking about the bug > you fixed. I am talking the compatibility breakage you created. > > 1. The backward compatibility breakage only occurred on the release-2.x > branch because revapi is essentially disabled on master. Too much has > changed to bother keeping track. > 2. I haven’t seen any commit messages indicating you committed anything to > fix this. > 3. The build is still failing for me. Try running mvn clean install > -DskipTests in log4j-core. It will break for you too. > > Please look at the Jenkins build and fix the problems by either reverting > the breakage or by adding the recommended changes to revapi.json to > document why compatibility was broken. > > Ralph > > > > On Aug 15, 2019, at 4:54 PM, Gary Gregory <[email protected]> > wrote: > > > > I fixed it already in both branches. > > > > Gary > > > > On Thu, Aug 15, 2019, 10:42 Ralph Goers <[email protected]> > wrote: > > > >> Gary, > >> > >> Are you going to look into this? > >> > >> Ralph > >> > >>> On Aug 14, 2019, at 9:17 AM, Ralph Goers <[email protected]> > >> wrote: > >>> > >>> Any update on this? I’d like my builds to work again. > >>> > >>> Ralph > >>> > >>>> On Aug 13, 2019, at 4:29 PM, Ralph Goers <[email protected]> > >> wrote: > >>>> > >>>> Gary, > >>>> > >>>> It seems this change broker compatibility. Please see the Jenkins > >> failure. You either need to resolve the code so compatibility is > maintained > >> or update revapi.json with the recommended changes. > >>>> > >>>> Ralph > >>>> > >>>>> On Aug 13, 2019, at 2:06 PM, [email protected] wrote: > >>>>> > >>>>> This is an automated email from the ASF dual-hosted git repository. > >>>>> > >>>>> ggregory pushed a commit to branch release-2.x > >>>>> in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git > >>>>> > >>>>> > >>>>> The following commit(s) were added to refs/heads/release-2.x by this > >> push: > >>>>> new 4679a08 [LOG4J2-2673] OutputStreamAppender.Builder ignores > >> setFilter(). > >>>>> 4679a08 is described below > >>>>> > >>>>> commit 4679a08d4899350f7ee19d050d2a96783b748066 > >>>>> Author: Gary Gregory <[email protected]> > >>>>> AuthorDate: Tue Aug 13 17:06:48 2019 -0400 > >>>>> > >>>>> [LOG4J2-2673] OutputStreamAppender.Builder ignores setFilter(). > >>>>> > >>>>> Also allow a null output stream for convenience instead of an NPE. > >>>>> --- > >>>>> .../log4j/core/appender/OutputStreamAppender.java | 351 > >> +++++++++++---------- > >>>>> .../core/appender/OutputStreamAppenderTest.java | 230 > +++++++------- > >>>>> src/changes/changes.xml | 3 + > >>>>> 3 files changed, 302 insertions(+), 282 deletions(-) > >>>>> > >>>>> diff --git > >> > a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java > >> > b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java > >>>>> index 7dfd187..dc6f352 100644 > >>>>> --- > >> > a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java > >>>>> +++ > >> > b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java > >>>>> @@ -1,174 +1,177 @@ > >>>>> -/* > >>>>> - * 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.core.appender; > >>>>> - > >>>>> -import java.io.OutputStream; > >>>>> -import java.io.Serializable; > >>>>> - > >>>>> -import org.apache.logging.log4j.core.Appender; > >>>>> -import org.apache.logging.log4j.core.Core; > >>>>> -import org.apache.logging.log4j.core.Filter; > >>>>> -import org.apache.logging.log4j.core.Layout; > >>>>> -import org.apache.logging.log4j.core.config.Property; > >>>>> -import org.apache.logging.log4j.core.config.plugins.Plugin; > >>>>> -import > >> org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; > >>>>> -import org.apache.logging.log4j.core.config.plugins.PluginFactory; > >>>>> -import org.apache.logging.log4j.core.layout.PatternLayout; > >>>>> -import org.apache.logging.log4j.core.util.CloseShieldOutputStream; > >>>>> - > >>>>> -/** > >>>>> - * Appends log events to a given output stream using a layout. > >>>>> - * <p> > >>>>> - * Character encoding is handled within the Layout. > >>>>> - * </p> > >>>>> - */ > >>>>> -@Plugin(name = "OutputStream", category = Core.CATEGORY_NAME, > >> elementType = Appender.ELEMENT_TYPE, printObject = true) > >>>>> -public final class OutputStreamAppender extends > >> AbstractOutputStreamAppender<OutputStreamManager> { > >>>>> - > >>>>> - /** > >>>>> - * Builds OutputStreamAppender instances. > >>>>> - */ > >>>>> - public static class Builder<B extends Builder<B>> extends > >> AbstractOutputStreamAppender.Builder<B> > >>>>> - implements > >> org.apache.logging.log4j.core.util.Builder<OutputStreamAppender> { > >>>>> - > >>>>> - private Filter filter; > >>>>> - > >>>>> - private boolean follow = false; > >>>>> - > >>>>> - private final boolean ignoreExceptions = true; > >>>>> - > >>>>> - private OutputStream target; > >>>>> - > >>>>> - @Override > >>>>> - public OutputStreamAppender build() { > >>>>> - final Layout<? extends Serializable> layout = > getLayout(); > >>>>> - final Layout<? extends Serializable> actualLayout = > >> layout == null ? PatternLayout.createDefaultLayout() > >>>>> - : layout; > >>>>> - return new OutputStreamAppender(getName(), actualLayout, > >> filter, getManager(target, follow, actualLayout), > >>>>> - ignoreExceptions, getPropertyArray()); > >>>>> - } > >>>>> - > >>>>> - public B setFollow(final boolean shouldFollow) { > >>>>> - this.follow = shouldFollow; > >>>>> - return asBuilder(); > >>>>> - } > >>>>> - > >>>>> - public B setTarget(final OutputStream aTarget) { > >>>>> - this.target = aTarget; > >>>>> - return asBuilder(); > >>>>> - } > >>>>> - } > >>>>> - > >>>>> - /** > >>>>> - * Holds data to pass to factory method. > >>>>> - */ > >>>>> - private static class FactoryData { > >>>>> - private final Layout<? extends Serializable> layout; > >>>>> - private final String name; > >>>>> - private final OutputStream os; > >>>>> - > >>>>> - /** > >>>>> - * Builds instances. > >>>>> - * > >>>>> - * @param os > >>>>> - * The OutputStream. > >>>>> - * @param type > >>>>> - * The name of the target. > >>>>> - * @param layout > >>>>> - * A Serializable layout > >>>>> - */ > >>>>> - public FactoryData(final OutputStream os, final String type, > >> final Layout<? extends Serializable> layout) { > >>>>> - this.os = os; > >>>>> - this.name = type; > >>>>> - this.layout = layout; > >>>>> - } > >>>>> - } > >>>>> - > >>>>> - /** > >>>>> - * Creates the manager. > >>>>> - */ > >>>>> - private static class OutputStreamManagerFactory implements > >> ManagerFactory<OutputStreamManager, FactoryData> { > >>>>> - > >>>>> - /** > >>>>> - * Creates an OutputStreamManager. > >>>>> - * > >>>>> - * @param name > >>>>> - * The name of the entity to manage. > >>>>> - * @param data > >>>>> - * The data required to create the entity. > >>>>> - * @return The OutputStreamManager > >>>>> - */ > >>>>> - @Override > >>>>> - public OutputStreamManager createManager(final String name, > >> final FactoryData data) { > >>>>> - return new OutputStreamManager(data.os, data.name, > >> data.layout, true); > >>>>> - } > >>>>> - } > >>>>> - > >>>>> - private static OutputStreamManagerFactory factory = new > >> OutputStreamManagerFactory(); > >>>>> - > >>>>> - /** > >>>>> - * Creates an OutputStream Appender. > >>>>> - * > >>>>> - * @param layout > >>>>> - * The layout to use or null to get the default > layout. > >>>>> - * @param filter > >>>>> - * The Filter or null. > >>>>> - * @param target > >>>>> - * an output stream. > >>>>> - * @param follow > >>>>> - * If true will follow changes to the underlying > >> output stream. > >>>>> - * Use false as the default. > >>>>> - * @param name > >>>>> - * The name of the Appender (required). > >>>>> - * @param ignore > >>>>> - * If {@code "true"} (default) exceptions encountered > >> when > >>>>> - * appending events are logged; otherwise they are > >> propagated to > >>>>> - * the caller. Use true as the default. > >>>>> - * @return The ConsoleAppender. > >>>>> - */ > >>>>> - @PluginFactory > >>>>> - public static OutputStreamAppender createAppender(Layout<? > >> extends Serializable> layout, final Filter filter, > >>>>> - final OutputStream target, final String name, final > >> boolean follow, final boolean ignore) { > >>>>> - if (name == null) { > >>>>> - LOGGER.error("No name provided for > OutputStreamAppender"); > >>>>> - return null; > >>>>> - } > >>>>> - if (layout == null) { > >>>>> - layout = PatternLayout.createDefaultLayout(); > >>>>> - } > >>>>> - return new OutputStreamAppender(name, layout, filter, > >> getManager(target, follow, layout), ignore, null); > >>>>> - } > >>>>> - > >>>>> - private static OutputStreamManager getManager(final OutputStream > >> target, final boolean follow, > >>>>> - final Layout<? extends Serializable> layout) { > >>>>> - final OutputStream os = new CloseShieldOutputStream(target); > >>>>> - final String managerName = target.getClass().getName() + "@" > >> + Integer.toHexString(target.hashCode()) + '.' > >>>>> - + follow; > >>>>> - return OutputStreamManager.getManager(managerName, new > >> FactoryData(os, managerName, layout), factory); > >>>>> - } > >>>>> - > >>>>> - @PluginBuilderFactory > >>>>> - public static Builder newBuilder() { > >>>>> - return new Builder(); > >>>>> - } > >>>>> - > >>>>> - private OutputStreamAppender(final String name, final Layout<? > >> extends Serializable> layout, final Filter filter, > >>>>> - final OutputStreamManager manager, final boolean > >> ignoreExceptions, final Property[] properties) { > >>>>> - super(name, layout, filter, ignoreExceptions, true, > >> properties, manager); > >>>>> - } > >>>>> - > >>>>> -} > >>>>> +/* > >>>>> + * 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.core.appender; > >>>>> + > >>>>> +import java.io.OutputStream; > >>>>> +import java.io.Serializable; > >>>>> + > >>>>> +import org.apache.logging.log4j.core.Appender; > >>>>> +import org.apache.logging.log4j.core.Core; > >>>>> +import org.apache.logging.log4j.core.Filter; > >>>>> +import org.apache.logging.log4j.core.Layout; > >>>>> +import org.apache.logging.log4j.core.config.Property; > >>>>> +import org.apache.logging.log4j.core.config.plugins.Plugin; > >>>>> +import > >> org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory; > >>>>> +import org.apache.logging.log4j.core.config.plugins.PluginFactory; > >>>>> +import org.apache.logging.log4j.core.layout.PatternLayout; > >>>>> +import org.apache.logging.log4j.core.util.CloseShieldOutputStream; > >>>>> +import org.apache.logging.log4j.core.util.NullOutputStream; > >>>>> + > >>>>> +/** > >>>>> + * Appends log events to a given output stream using a layout. > >>>>> + * <p> > >>>>> + * Character encoding is handled within the Layout. > >>>>> + * </p> > >>>>> + */ > >>>>> +@Plugin(name = "OutputStream", category = Core.CATEGORY_NAME, > >> elementType = Appender.ELEMENT_TYPE, printObject = true) > >>>>> +public final class OutputStreamAppender extends > >> AbstractOutputStreamAppender<OutputStreamManager> { > >>>>> + > >>>>> + /** > >>>>> + * Builds OutputStreamAppender instances. > >>>>> + * > >>>>> + * @param <B> > >>>>> + * The type to build. > >>>>> + */ > >>>>> + public static class Builder<B extends Builder<B>> extends > >> AbstractOutputStreamAppender.Builder<B> > >>>>> + implements > >> org.apache.logging.log4j.core.util.Builder<OutputStreamAppender> { > >>>>> + > >>>>> + private boolean follow = false; > >>>>> + > >>>>> + private final boolean ignoreExceptions = true; > >>>>> + > >>>>> + private OutputStream target; > >>>>> + > >>>>> + @Override > >>>>> + public OutputStreamAppender build() { > >>>>> + final Layout<? extends Serializable> layout = > getLayout(); > >>>>> + final Layout<? extends Serializable> actualLayout = > >> layout == null ? PatternLayout.createDefaultLayout() > >>>>> + : layout; > >>>>> + return new OutputStreamAppender(getName(), actualLayout, > >> getFilter(), getManager(target, follow, actualLayout), > >>>>> + ignoreExceptions, getPropertyArray()); > >>>>> + } > >>>>> + > >>>>> + public B setFollow(final boolean shouldFollow) { > >>>>> + this.follow = shouldFollow; > >>>>> + return asBuilder(); > >>>>> + } > >>>>> + > >>>>> + public B setTarget(final OutputStream aTarget) { > >>>>> + this.target = aTarget; > >>>>> + return asBuilder(); > >>>>> + } > >>>>> + } > >>>>> + > >>>>> + /** > >>>>> + * Holds data to pass to factory method. > >>>>> + */ > >>>>> + private static class FactoryData { > >>>>> + private final Layout<? extends Serializable> layout; > >>>>> + private final String name; > >>>>> + private final OutputStream os; > >>>>> + > >>>>> + /** > >>>>> + * Builds instances. > >>>>> + * > >>>>> + * @param os > >>>>> + * The OutputStream. > >>>>> + * @param type > >>>>> + * The name of the target. > >>>>> + * @param layout > >>>>> + * A Serializable layout > >>>>> + */ > >>>>> + public FactoryData(final OutputStream os, final String type, > >> final Layout<? extends Serializable> layout) { > >>>>> + this.os = os; > >>>>> + this.name = type; > >>>>> + this.layout = layout; > >>>>> + } > >>>>> + } > >>>>> + > >>>>> + /** > >>>>> + * Creates the manager. > >>>>> + */ > >>>>> + private static class OutputStreamManagerFactory implements > >> ManagerFactory<OutputStreamManager, FactoryData> { > >>>>> + > >>>>> + /** > >>>>> + * Creates an OutputStreamManager. > >>>>> + * > >>>>> + * @param name > >>>>> + * The name of the entity to manage. > >>>>> + * @param data > >>>>> + * The data required to create the entity. > >>>>> + * @return The OutputStreamManager > >>>>> + */ > >>>>> + @Override > >>>>> + public OutputStreamManager createManager(final String name, > >> final FactoryData data) { > >>>>> + return new OutputStreamManager(data.os, data.name, > >> data.layout, true); > >>>>> + } > >>>>> + } > >>>>> + > >>>>> + private static OutputStreamManagerFactory factory = new > >> OutputStreamManagerFactory(); > >>>>> + > >>>>> + /** > >>>>> + * Creates an OutputStream Appender. > >>>>> + * > >>>>> + * @param layout > >>>>> + * The layout to use or null to get the default > layout. > >>>>> + * @param filter > >>>>> + * The Filter or null. > >>>>> + * @param target > >>>>> + * an output stream. > >>>>> + * @param follow > >>>>> + * If true will follow changes to the underlying > >> output stream. > >>>>> + * Use false as the default. > >>>>> + * @param name > >>>>> + * The name of the Appender (required). > >>>>> + * @param ignore > >>>>> + * If {@code "true"} (default) exceptions encountered > >> when > >>>>> + * appending events are logged; otherwise they are > >> propagated to > >>>>> + * the caller. Use true as the default. > >>>>> + * @return The ConsoleAppender. > >>>>> + */ > >>>>> + @PluginFactory > >>>>> + public static OutputStreamAppender createAppender(Layout<? > >> extends Serializable> layout, final Filter filter, > >>>>> + final OutputStream target, final String name, final > >> boolean follow, final boolean ignore) { > >>>>> + if (name == null) { > >>>>> + LOGGER.error("No name provided for > OutputStreamAppender"); > >>>>> + return null; > >>>>> + } > >>>>> + if (layout == null) { > >>>>> + layout = PatternLayout.createDefaultLayout(); > >>>>> + } > >>>>> + return new OutputStreamAppender(name, layout, filter, > >> getManager(target, follow, layout), ignore, null); > >>>>> + } > >>>>> + > >>>>> + private static OutputStreamManager getManager(final OutputStream > >> target, final boolean follow, > >>>>> + final Layout<? extends Serializable> layout) { > >>>>> + final OutputStream os = target == null ? > >> NullOutputStream.getInstance() : new CloseShieldOutputStream(target); > >>>>> + final OutputStream targetRef = target == null ? os : target; > >>>>> + final String managerName = targetRef.getClass().getName() + > >> "@" + Integer.toHexString(targetRef.hashCode()) > >>>>> + + '.' + follow; > >>>>> + return OutputStreamManager.getManager(managerName, new > >> FactoryData(os, managerName, layout), factory); > >>>>> + } > >>>>> + > >>>>> + @PluginBuilderFactory > >>>>> + public static <B extends Builder<B>> B newBuilder() { > >>>>> + return new Builder<B>().asBuilder(); > >>>>> + } > >>>>> + > >>>>> + private OutputStreamAppender(final String name, final Layout<? > >> extends Serializable> layout, final Filter filter, > >>>>> + final OutputStreamManager manager, final boolean > >> ignoreExceptions, final Property[] properties) { > >>>>> + super(name, layout, filter, ignoreExceptions, true, > >> properties, manager); > >>>>> + } > >>>>> + > >>>>> +} > >>>>> diff --git > >> > a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java > >> > b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java > >>>>> index 00af014..c1448bf 100644 > >>>>> --- > >> > a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java > >>>>> +++ > >> > b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java > >>>>> @@ -1,108 +1,122 @@ > >>>>> -/* > >>>>> - * 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.core.appender; > >>>>> - > >>>>> -import java.io.BufferedOutputStream; > >>>>> -import java.io.ByteArrayOutputStream; > >>>>> -import java.io.OutputStream; > >>>>> -import java.sql.SQLException; > >>>>> - > >>>>> -import org.apache.logging.log4j.LogManager; > >>>>> -import org.apache.logging.log4j.Logger; > >>>>> -import org.apache.logging.log4j.core.Appender; > >>>>> -import org.apache.logging.log4j.core.LoggerContext; > >>>>> -import org.apache.logging.log4j.core.config.Configuration; > >>>>> -import org.apache.logging.log4j.core.layout.PatternLayout; > >>>>> -import org.junit.Assert; > >>>>> -import org.junit.Rule; > >>>>> -import org.junit.Test; > >>>>> -import org.junit.rules.TestName; > >>>>> - > >>>>> -/** > >>>>> - * Tests {@link OutputStreamAppender}. > >>>>> - */ > >>>>> -public class OutputStreamAppenderTest { > >>>>> - > >>>>> - private static final String TEST_MSG = "FOO ERROR"; > >>>>> - > >>>>> - @Rule > >>>>> - public TestName testName = new TestName(); > >>>>> - > >>>>> - private String getName(final OutputStream out) { > >>>>> - return out.getClass().getSimpleName() + "." + > >> testName.getMethodName(); > >>>>> - } > >>>>> - > >>>>> - /** > >>>>> - * Tests that you can add an output stream appender dynamically. > >>>>> - */ > >>>>> - private void addAppender(final OutputStream outputStream, final > >> String outputStreamName) { > >>>>> - final LoggerContext context = > LoggerContext.getContext(false); > >>>>> - final Configuration config = context.getConfiguration(); > >>>>> - final PatternLayout layout = > >> PatternLayout.createDefaultLayout(config); > >>>>> - final Appender appender = > >> OutputStreamAppender.createAppender(layout, null, outputStream, > >> outputStreamName, false, true); > >>>>> - appender.start(); > >>>>> - config.addAppender(appender); > >>>>> - ConfigurationTestUtils.updateLoggers(appender, config); > >>>>> - } > >>>>> - > >>>>> - @Test > >>>>> - public void testOutputStreamAppenderToBufferedOutputStream() > >> throws SQLException { > >>>>> - final ByteArrayOutputStream out = new > ByteArrayOutputStream(); > >>>>> - final OutputStream os = new BufferedOutputStream(out); > >>>>> - final String name = getName(out); > >>>>> - final Logger logger = LogManager.getLogger(name); > >>>>> - addAppender(os, name); > >>>>> - logger.error(TEST_MSG); > >>>>> - final String actual = out.toString(); > >>>>> - Assert.assertTrue(actual, actual.contains(TEST_MSG)); > >>>>> - } > >>>>> - > >>>>> - @Test > >>>>> - public void testOutputStreamAppenderToByteArrayOutputStream() > >> throws SQLException { > >>>>> - final OutputStream out = new ByteArrayOutputStream(); > >>>>> - final String name = getName(out); > >>>>> - final Logger logger = LogManager.getLogger(name); > >>>>> - addAppender(out, name); > >>>>> - logger.error(TEST_MSG); > >>>>> - final String actual = out.toString(); > >>>>> - Assert.assertTrue(actual, actual.contains(TEST_MSG)); > >>>>> - } > >>>>> - > >>>>> - /** > >>>>> - * Validates that the code pattern we use to add an appender on > >> the fly > >>>>> - * works with a basic appender that is not the new OutputStream > >> appender or > >>>>> - * new Writer appender. > >>>>> - */ > >>>>> - @Test > >>>>> - public void testUpdatePatternWithFileAppender() { > >>>>> - final LoggerContext ctx = (LoggerContext) > >> LogManager.getContext(false); > >>>>> - final Configuration config = ctx.getConfiguration(); > >>>>> - // @formatter:off > >>>>> - final Appender appender = FileAppender.newBuilder() > >>>>> - .withFileName("target/" + getClass().getName() + ".log") > >>>>> - > .withAppend(false).setName("File").setIgnoreExceptions(false) > >>>>> - .withBufferedIo(false) > >>>>> - .withBufferSize(4000) > >>>>> - .setConfiguration(config) > >>>>> - .build(); > >>>>> - // @formatter:on > >>>>> - appender.start(); > >>>>> - config.addAppender(appender); > >>>>> - ConfigurationTestUtils.updateLoggers(appender, config); > >>>>> - LogManager.getLogger().error("FOO MSG"); > >>>>> - } > >>>>> -} > >>>>> +/* > >>>>> + * 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.core.appender; > >>>>> + > >>>>> +import java.io.BufferedOutputStream; > >>>>> +import java.io.ByteArrayOutputStream; > >>>>> +import java.io.OutputStream; > >>>>> +import java.sql.SQLException; > >>>>> + > >>>>> +import org.apache.logging.log4j.LogManager; > >>>>> +import org.apache.logging.log4j.Logger; > >>>>> +import org.apache.logging.log4j.core.Appender; > >>>>> +import org.apache.logging.log4j.core.LoggerContext; > >>>>> +import org.apache.logging.log4j.core.config.Configuration; > >>>>> +import org.apache.logging.log4j.core.filter.NoMarkerFilter; > >>>>> +import org.apache.logging.log4j.core.layout.PatternLayout; > >>>>> +import org.junit.Assert; > >>>>> +import org.junit.Rule; > >>>>> +import org.junit.Test; > >>>>> +import org.junit.rules.TestName; > >>>>> + > >>>>> +/** > >>>>> + * Tests {@link OutputStreamAppender}. > >>>>> + */ > >>>>> +public class OutputStreamAppenderTest { > >>>>> + > >>>>> + private static final String TEST_MSG = "FOO ERROR"; > >>>>> + > >>>>> + @Rule > >>>>> + public TestName testName = new TestName(); > >>>>> + > >>>>> + private String getName(final OutputStream out) { > >>>>> + return out.getClass().getSimpleName() + "." + > >> testName.getMethodName(); > >>>>> + } > >>>>> + > >>>>> + /** > >>>>> + * Tests that you can add an output stream appender dynamically. > >>>>> + */ > >>>>> + private void addAppender(final OutputStream outputStream, final > >> String outputStreamName) { > >>>>> + final LoggerContext context = > LoggerContext.getContext(false); > >>>>> + final Configuration config = context.getConfiguration(); > >>>>> + final PatternLayout layout = > >> PatternLayout.createDefaultLayout(config); > >>>>> + final Appender appender = > >> OutputStreamAppender.createAppender(layout, null, outputStream, > >> outputStreamName, false, true); > >>>>> + appender.start(); > >>>>> + config.addAppender(appender); > >>>>> + ConfigurationTestUtils.updateLoggers(appender, config); > >>>>> + } > >>>>> + > >>>>> + @Test > >>>>> + public void testBuildFilter() { > >>>>> + final NoMarkerFilter filter = > >> NoMarkerFilter.newBuilder().build(); > >>>>> + // @formatter:off > >>>>> + final OutputStreamAppender.Builder builder = > >> OutputStreamAppender.newBuilder() > >>>>> + .setName("test") > >>>>> + .setFilter(filter); > >>>>> + // @formatter:on > >>>>> + Assert.assertEquals(filter, builder.getFilter()); > >>>>> + final OutputStreamAppender appender = builder.build(); > >>>>> + Assert.assertEquals(filter, appender.getFilter()); > >>>>> + } > >>>>> + > >>>>> + @Test > >>>>> + public void testOutputStreamAppenderToBufferedOutputStream() > >> throws SQLException { > >>>>> + final ByteArrayOutputStream out = new > ByteArrayOutputStream(); > >>>>> + final OutputStream os = new BufferedOutputStream(out); > >>>>> + final String name = getName(out); > >>>>> + final Logger logger = LogManager.getLogger(name); > >>>>> + addAppender(os, name); > >>>>> + logger.error(TEST_MSG); > >>>>> + final String actual = out.toString(); > >>>>> + Assert.assertTrue(actual, actual.contains(TEST_MSG)); > >>>>> + } > >>>>> + > >>>>> + @Test > >>>>> + public void testOutputStreamAppenderToByteArrayOutputStream() > >> throws SQLException { > >>>>> + final OutputStream out = new ByteArrayOutputStream(); > >>>>> + final String name = getName(out); > >>>>> + final Logger logger = LogManager.getLogger(name); > >>>>> + addAppender(out, name); > >>>>> + logger.error(TEST_MSG); > >>>>> + final String actual = out.toString(); > >>>>> + Assert.assertTrue(actual, actual.contains(TEST_MSG)); > >>>>> + } > >>>>> + > >>>>> + /** > >>>>> + * Validates that the code pattern we use to add an appender on > >> the fly > >>>>> + * works with a basic appender that is not the new OutputStream > >> appender or > >>>>> + * new Writer appender. > >>>>> + */ > >>>>> + @Test > >>>>> + public void testUpdatePatternWithFileAppender() { > >>>>> + final LoggerContext ctx = (LoggerContext) > >> LogManager.getContext(false); > >>>>> + final Configuration config = ctx.getConfiguration(); > >>>>> + // @formatter:off > >>>>> + final Appender appender = FileAppender.newBuilder() > >>>>> + .withFileName("target/" + getClass().getName() + ".log") > >>>>> + > .withAppend(false).setName("File").setIgnoreExceptions(false) > >>>>> + .withBufferedIo(false) > >>>>> + .withBufferSize(4000) > >>>>> + .setConfiguration(config) > >>>>> + .build(); > >>>>> + // @formatter:on > >>>>> + appender.start(); > >>>>> + config.addAppender(appender); > >>>>> + ConfigurationTestUtils.updateLoggers(appender, config); > >>>>> + LogManager.getLogger().error("FOO MSG"); > >>>>> + } > >>>>> +} > >>>>> diff --git a/src/changes/changes.xml b/src/changes/changes.xml > >>>>> index c3483bd..a9ec160 100644 > >>>>> --- a/src/changes/changes.xml > >>>>> +++ b/src/changes/changes.xml > >>>>> @@ -33,6 +33,9 @@ > >>>>> <action issue="LOG4J2-2639" dev="rgoers" type="add"> > >>>>> Add builder pattern to Logger interface. > >>>>> </action> > >>>>> + <action issue="LOG4J2-2673" dev="ggregory" type="fix" > >> due-to="Yuichi Sugimura, Gary Gregory"> > >>>>> + OutputStreamAppender.Builder ignores setFilter(). > >>>>> + </action> > >>>>> </release> > >>>>> <release version="2.12.1" date="2019-08-06" description="GA Release > >> 2.12.1"> > >>>>> <action issue="LOG4J2-1946" dev="rgoers" type="fix" due-to="Igor > >> Perelyotov"> > >>>>> > >>>>> > >>>> > >>>> > >>>> > >>> > >>> > >>> > >> > >> > >> > > >
