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"> > >
