Repository: logging-log4j2
Updated Branches:
  refs/heads/master 183771c87 -> 449219b3e


[LOG4J2-1187] Support use case for
java.sql.DriverManager.setLogStream(PrintStream).

Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/449219b3
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/449219b3
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/449219b3

Branch: refs/heads/master
Commit: 449219b3e809eb19af16690a660a4b8205343125
Parents: 183771c
Author: ggregory <ggreg...@apache.org>
Authored: Sun Nov 1 13:57:01 2015 -0800
Committer: ggregory <ggreg...@apache.org>
Committed: Sun Nov 1 13:57:01 2015 -0800

----------------------------------------------------------------------
 .../core/appender/OutputStreamAppender.java     | 191 +++++++++++++++++++
 .../core/appender/OutputStreamAppenderTest.java | 103 ++++++++++
 src/changes/changes.xml                         |   3 +
 3 files changed, 297 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/449219b3/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..8afb9b8
--- /dev/null
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/OutputStreamAppender.java
@@ -0,0 +1,191 @@
+/*
+ * 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.Filter;
+import org.apache.logging.log4j.core.Layout;
+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", elementType = "appender", 
printObject = true)
+public final class OutputStreamAppender extends 
AbstractOutputStreamAppender<OutputStreamManager> {
+
+    /**
+     * Builds OutputStreamAppender instances.
+     */
+    public static class Builder implements 
org.apache.logging.log4j.core.util.Builder<OutputStreamAppender> {
+
+        private Filter filter;
+
+        private boolean follow = false;
+
+        private boolean ignoreExceptions = true;
+
+        private Layout<? extends Serializable> layout = 
PatternLayout.createDefaultLayout();
+
+        private String name;
+
+        private OutputStream target;
+
+        @Override
+        public OutputStreamAppender build() {
+            return new OutputStreamAppender(name, layout, filter, 
getManager(target, follow, layout), ignoreExceptions);
+        }
+
+        public Builder setFilter(final Filter aFilter) {
+            this.filter = aFilter;
+            return this;
+        }
+
+        public Builder setFollow(final boolean shouldFollow) {
+            this.follow = shouldFollow;
+            return this;
+        }
+
+        public Builder setIgnoreExceptions(final boolean 
shouldIgnoreExceptions) {
+            this.ignoreExceptions = shouldIgnoreExceptions;
+            return this;
+        }
+
+        public Builder setLayout(final Layout<? extends Serializable> aLayout) 
{
+            this.layout = aLayout;
+            return this;
+        }
+
+        public Builder setName(final String aName) {
+            this.name = aName;
+            return this;
+        }
+
+        public Builder setTarget(final OutputStream aTarget) {
+            this.target = aTarget;
+            return this;
+        }
+    }
+    /**
+     * 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();
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 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);
+    }
+
+    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) 
{
+        super(name, layout, filter, ignoreExceptions, true, manager);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/449219b3/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..206e98b
--- /dev/null
+++ 
b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/OutputStreamAppenderTest.java
@@ -0,0 +1,103 @@
+/*
+ * 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.Layout;
+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();
+        final Layout<?> layout = PatternLayout.createDefaultLayout();
+        final Appender appender = FileAppender.createAppender("target/" + 
getClass().getName() + ".log", "false",
+                "false", "File", "true", "false", "false", "4000", layout, 
null, "false", null, config);
+        appender.start();
+        config.addAppender(appender);
+        ConfigurationTestUtils.updateLoggers(appender, config);
+        LogManager.getLogger().error("FOO MSG");
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/449219b3/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 1911c3c..a19805b 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -39,6 +39,9 @@
       <action issue="LOG4J2-1178" dev="ggregory" type="add">
         Support use-case for JDBC's CommonDataSource.setLogWriter(PrintWriter) 
and java.sql.DriverManager.setLogWriter(PrintWriter).
       </action>
+      <action issue="LOG4J2-1187" dev="ggregory" type="add">
+        Support use case for java.sql.DriverManager.setLogStream(PrintStream).
+      </action>
       <action issue="LOG4J2-879" dev="rpopma" type="fix">
         Documentation: fixed minor issues with the site and manual pages.
       </action>

Reply via email to