You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by gg...@apache.org on 2018/10/30 02:16:46 UTC

[2/2] logging-log4j2 git commit: [LOG4J2-2491] Allow all Appenders to optionally carry a Property array.

[LOG4J2-2491] Allow all Appenders to optionally carry a Property array.

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

Branch: refs/heads/release-2.x
Commit: 61b77dfb6ec5f69117f7892ccb940e34b5223954
Parents: d39546d
Author: Gary Gregory <ga...@gmail.com>
Authored: Mon Oct 29 20:16:41 2018 -0600
Committer: Gary Gregory <ga...@gmail.com>
Committed: Mon Oct 29 20:16:41 2018 -0600

----------------------------------------------------------------------
 .../test/java/org/apache/log4j/LoggerTest.java  |   3 +-
 .../log4j/cassandra/CassandraAppender.java      |   7 +-
 .../log4j/core/appender/AbstractAppender.java   | 114 +++++---
 .../core/appender/AbstractFileAppender.java     |   5 +-
 .../appender/AbstractOutputStreamAppender.java  |  22 +-
 .../core/appender/AbstractWriterAppender.java   | 274 ++++++++++---------
 .../log4j/core/appender/AsyncAppender.java      |  14 +-
 .../log4j/core/appender/ConsoleAppender.java    |  14 +-
 .../core/appender/CountingNoOpAppender.java     |   9 +-
 .../log4j/core/appender/FailoverAppender.java   |   9 +-
 .../log4j/core/appender/FileAppender.java       |  17 +-
 .../log4j/core/appender/HttpAppender.java       |  12 +-
 .../core/appender/MemoryMappedFileAppender.java |  15 +-
 .../log4j/core/appender/NullAppender.java       |   4 +-
 .../core/appender/OutputStreamAppender.java     |  50 ++--
 .../core/appender/RandomAccessFileAppender.java |  15 +-
 .../core/appender/RollingFileAppender.java      |  18 +-
 .../RollingRandomAccessFileAppender.java        |  21 +-
 .../core/appender/ScriptAppenderSelector.java   |   6 +-
 .../log4j/core/appender/SmtpAppender.java       |   9 +-
 .../log4j/core/appender/SocketAppender.java     |  25 +-
 .../log4j/core/appender/SyslogAppender.java     |  25 +-
 .../log4j/core/appender/WriterAppender.java     |  54 ++--
 .../appender/db/AbstractDatabaseAppender.java   |  26 +-
 .../core/appender/db/jdbc/JdbcAppender.java     |  12 +-
 .../log4j/core/appender/mom/JmsAppender.java    |  70 ++---
 .../appender/mom/jeromq/JeroMqAppender.java     |   6 +-
 .../core/appender/mom/kafka/KafkaAppender.java  |  14 +-
 .../core/appender/nosql/NoSqlAppender.java      |   9 +-
 .../core/appender/rewrite/RewriteAppender.java  |   7 +-
 .../core/appender/routing/RoutingAppender.java  |   9 +-
 .../core/config/AbstractConfiguration.java      |   8 +-
 .../logging/log4j/core/config/Property.java     |   5 +
 .../log4j/core/filter/AbstractFilterable.java   |  32 ++-
 .../appender/ConsoleAppenderBuilderTest.java    |   4 +-
 .../core/appender/ConsoleAppenderTest.java      |   6 +-
 .../appender/FileAppenderPermissionsTest.java   |  18 +-
 .../log4j/core/appender/FileAppenderTest.java   |  27 +-
 .../log4j/core/appender/HangingAppender.java    |   8 +-
 .../log4j/core/appender/HttpAppenderTest.java   |  36 +--
 .../core/appender/OutputStreamAppenderTest.java |   6 +-
 .../log4j/core/appender/SocketAppenderTest.java |  51 ++--
 .../SyslogAppenderCustomLayoutTest.java         |   5 +-
 .../log4j/core/appender/SyslogAppenderTest.java |   8 +-
 .../rolling/CronTriggeringPolicyTest.java       |   6 +-
 .../rolling/RollingFileAppenderAccessTest.java  |   5 +-
 .../rolling/RollingFileAppenderLayoutTest.java  |   3 +-
 .../log4j/core/async/BlockingAppender.java      |   3 +-
 .../core/config/CustomConfigurationTest.java    |   9 +-
 .../log4j/core/config/JiraLog4j2_2134Test.java  |   8 +-
 .../log4j/test/appender/AlwaysFailAppender.java |   3 +-
 .../log4j/test/appender/BlockingAppender.java   |   3 +-
 .../log4j/test/appender/DeadlockAppender.java   |   3 +-
 .../log4j/test/appender/FailOnceAppender.java   |   3 +-
 .../log4j/test/appender/InMemoryAppender.java   |   4 +-
 .../log4j/test/appender/ListAppender.java       |   5 +-
 .../test/appender/UsesLoggingAppender.java      |   3 +-
 log4j-core/src/test/resources/log4j-test2.xml   |   2 +-
 .../log4j/flume/appender/FlumeAppender.java     |  10 +-
 .../log4j/core/appender/db/jpa/JpaAppender.java |   7 +-
 .../log4j/perf/jmh/LoggerConfigBenchmark.java   |   3 +-
 .../logging/log4j/perf/nogc/DemoAppender.java   |   3 +-
 .../logging/log4j/perf/util/DemoAppender.java   |   3 +-
 .../log4j/web/appender/ServletAppender.java     |   8 +-
 64 files changed, 645 insertions(+), 558 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerTest.java
----------------------------------------------------------------------
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerTest.java
index d21fa62..48b073d 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerTest.java
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.AbstractAppender;
 import org.apache.logging.log4j.core.config.ConfigurationFactory;
+import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.test.appender.ListAppender;
 import org.junit.After;
@@ -507,7 +508,7 @@ public class LoggerTest {
         int counter;
 
         CountingAppender() {
-            super("Counter", null, null);
+            super("Counter", null, null, true, Property.EMPTY_ARRAY);
             counter = 0;
         }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
----------------------------------------------------------------------
diff --git a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
index 7a9ade9..7d2bf10 100644
--- a/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
+++ b/log4j-cassandra/src/main/java/org/apache/logging/log4j/cassandra/CassandraAppender.java
@@ -22,6 +22,7 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.appender.AbstractAppender;
 import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender;
 import org.apache.logging.log4j.core.appender.db.ColumnMapping;
+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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
@@ -40,8 +41,8 @@ import org.apache.logging.log4j.core.util.Clock;
 public class CassandraAppender extends AbstractDatabaseAppender<CassandraManager> {
 
     private CassandraAppender(final String name, final Filter filter, final boolean ignoreExceptions,
-                              final CassandraManager manager) {
-        super(name, filter, ignoreExceptions, manager);
+                              final Property[] properties, final CassandraManager manager) {
+        super(name, filter, null, ignoreExceptions, properties, manager);
     }
 
     @PluginBuilderFactory
@@ -177,7 +178,7 @@ public class CassandraAppender extends AbstractDatabaseAppender<CassandraManager
             final CassandraManager manager = CassandraManager.getManager(getName(), contactPoints, columns, useTls,
                 clusterName, keyspace, table, username, password, useClockForTimestampGenerator, bufferSize, batched,
                 batchType);
-            return new CassandraAppender(getName(), getFilter(), isIgnoreExceptions(), manager);
+            return new CassandraAppender(getName(), getFilter(), isIgnoreExceptions(), null, manager);
         }
 
     }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
index c97f70c..77e547e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractAppender.java
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
 import org.apache.logging.log4j.core.config.plugins.PluginElement;
@@ -60,47 +61,56 @@ public abstract class AbstractAppender extends AbstractFilterable implements App
         @PluginConfiguration
         private Configuration configuration;
 
+        public Configuration getConfiguration() {
+            return configuration;
+        }
+
+        public Layout<? extends Serializable> getLayout() {
+            return layout;
+        }
+
         public String getName() {
             return name;
         }
 
-        public boolean isIgnoreExceptions() {
-            return ignoreExceptions;
+        public Layout<? extends Serializable> getOrCreateLayout() {
+            if (layout == null) {
+                return PatternLayout.createDefaultLayout();
+            }
+            return layout;
         }
 
-        public Layout<? extends Serializable> getLayout() {
+        public Layout<? extends Serializable> getOrCreateLayout(final Charset charset) {
+            if (layout == null) {
+                return PatternLayout.newBuilder().withCharset(charset).build();
+            }
             return layout;
         }
 
-        public B withName(final String name) {
-            this.name = name;
+        public boolean isIgnoreExceptions() {
+            return ignoreExceptions;
+        }
+
+        public B setConfiguration(final Configuration configuration) {
+            this.configuration = configuration;
             return asBuilder();
         }
 
-        public B withIgnoreExceptions(final boolean ignoreExceptions) {
+        public B setIgnoreExceptions(final boolean ignoreExceptions) {
             this.ignoreExceptions = ignoreExceptions;
             return asBuilder();
         }
 
-        public B withLayout(final Layout<? extends Serializable> layout) {
+        public B setLayout(final Layout<? extends Serializable> layout) {
             this.layout = layout;
             return asBuilder();
         }
 
-        public Layout<? extends Serializable> getOrCreateLayout() {
-            if (layout == null) {
-                return PatternLayout.createDefaultLayout();
-            }
-            return layout;
+        public B setName(final String name) {
+            this.name = name;
+            return asBuilder();
         }
         
-        public Layout<? extends Serializable> getOrCreateLayout(final Charset charset) {
-            if (layout == null) {
-                return PatternLayout.newBuilder().withCharset(charset).build();
-            }
-            return layout;
-        }
-
         /**
          * @deprecated Use {@link #setConfiguration(Configuration)}
          */
@@ -110,20 +120,44 @@ public abstract class AbstractAppender extends AbstractFilterable implements App
             return asBuilder();
         }
 
-        public B setConfiguration(final Configuration configuration) {
-            this.configuration = configuration;
-            return asBuilder();
+        /**
+         * @deprecated use {@link #setIgnoreExceptions(boolean)}.
+         */
+        @Deprecated
+        public B withIgnoreExceptions(final boolean ignoreExceptions) {
+            return setIgnoreExceptions(ignoreExceptions);
         }
 
-        public Configuration getConfiguration() {
-            return configuration;
+        /**
+         * @deprecated use {@link #setLayout(Layout)}.
+         */
+        @Deprecated
+        public B withLayout(final Layout<? extends Serializable> layout) {
+            return setLayout(layout);
+        }
+
+        /**
+         * @deprecated use {@link #setName(String)}.
+         */
+        @Deprecated
+        public B withName(final String name) {
+            return setName(name);
         }
         
     }
     
+    public static int parseInt(final String s, final int defaultValue) {
+        try {
+            return Integers.parseInt(s, defaultValue);
+        } catch (final NumberFormatException e) {
+            LOGGER.error("Could not parse \"{}\" as an integer,  using default value {}: {}", s, defaultValue, e);
+            return defaultValue;
+        }
+    }
     private final String name;
     private final boolean ignoreExceptions;
     private final Layout<? extends Serializable> layout;
+
     private ErrorHandler handler = new DefaultErrorHandler(this);
 
     /**
@@ -132,9 +166,11 @@ public abstract class AbstractAppender extends AbstractFilterable implements App
      * @param name The Appender name.
      * @param filter The Filter to associate with the Appender.
      * @param layout The layout to use to format the event.
+     * @deprecated Use {@link #AbstractAppender(String, Filter, Layout, boolean, Property[])}.
      */
+    @Deprecated
     protected AbstractAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout) {
-        this(name, filter, layout, true);
+        this(name, filter, layout, true, Property.EMPTY_ARRAY);
     }
 
     /**
@@ -145,24 +181,32 @@ public abstract class AbstractAppender extends AbstractFilterable implements App
      * @param layout The layout to use to format the event.
      * @param ignoreExceptions If true, exceptions will be logged and suppressed. If false errors will be logged and
      *            then passed to the application.
+     * @deprecated Use {@link #AbstractAppender(String, Filter, Layout, boolean, Property[])}
      */
+    @Deprecated
     protected AbstractAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout,
             final boolean ignoreExceptions) {
-        super(filter);
+        this(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
+    }
+
+    /**
+     * Constructor.
+     * 
+     * @param name The Appender name.
+     * @param filter The Filter to associate with the Appender.
+     * @param layout The layout to use to format the event.
+     * @param ignoreExceptions If true, exceptions will be logged and suppressed. If false errors will be logged and
+     *            then passed to the application.
+     * @since 2.11.2
+     */
+    protected AbstractAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout,
+            final boolean ignoreExceptions, final Property[] properties) {
+        super(filter, properties);
         this.name = Objects.requireNonNull(name, "name");
         this.layout = layout;
         this.ignoreExceptions = ignoreExceptions;
     }
 
-    public static int parseInt(final String s, final int defaultValue) {
-        try {
-            return Integers.parseInt(s, defaultValue);
-        } catch (final NumberFormatException e) {
-            LOGGER.error("Could not parse \"{}\" as an integer,  using default value {}: {}", s, defaultValue, e);
-            return defaultValue;
-        }
-    }
-
     /**
      * Handle an error with a message using the {@link ErrorHandler} configured for this Appender.
      * 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractFileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractFileAppender.java
index 09127c3..7537d99 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractFileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractFileAppender.java
@@ -23,6 +23,7 @@ import java.util.concurrent.TimeUnit;
 
 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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.validation.constraints.Required;
 import org.apache.logging.log4j.core.net.Advertiser;
@@ -159,9 +160,9 @@ public abstract class AbstractFileAppender<M extends OutputStreamManager> extend
 
     private AbstractFileAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
             final M manager, final String filename, final boolean ignoreExceptions,
-            final boolean immediateFlush, final Advertiser advertiser) {
+            final boolean immediateFlush, final Advertiser advertiser, final Property[] properties) {
 
-        super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
+        super(name, layout, filter, ignoreExceptions, immediateFlush, properties, manager);
         if (advertiser != null) {
             final Map<String, String> configuration = new HashMap<>(layout.getContentFormat());
             configuration.putAll(manager.getContentFormat());

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
index f0f0a41..d6acc08 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractOutputStreamAppender.java
@@ -22,6 +22,7 @@ import java.util.concurrent.TimeUnit;
 import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.config.Property;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.util.Constants;
 
@@ -94,10 +95,29 @@ public abstract class AbstractOutputStreamAppender<M extends OutputStreamManager
      * @param name The name of the Appender.
      * @param layout The layout to format the message.
      * @param manager The OutputStreamManager.
+     * @deprecated Use {@link #AbstractOutputStreamAppender(String, Layout, Filter, boolean, boolean, Property[], OutputStreamManager)}
      */
+    @Deprecated
     protected AbstractOutputStreamAppender(final String name, final Layout<? extends Serializable> layout,
             final Filter filter, final boolean ignoreExceptions, final boolean immediateFlush, final M manager) {
-        super(name, filter, layout, ignoreExceptions);
+        super(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
+        this.manager = manager;
+        this.immediateFlush = immediateFlush;
+    }
+
+    /**
+     * Instantiates a WriterAppender and set the output destination to a new {@link java.io.OutputStreamWriter}
+     * initialized with <code>os</code> as its {@link java.io.OutputStream}.
+     *
+     * @param name The name of the Appender.
+     * @param layout The layout to format the message.
+     * @param properties optional properties
+     * @param manager The OutputStreamManager.
+     */
+    protected AbstractOutputStreamAppender(final String name, final Layout<? extends Serializable> layout,
+            final Filter filter, final boolean ignoreExceptions, final boolean immediateFlush,
+            final Property[] properties, final M manager) {
+        super(name, filter, layout, ignoreExceptions, properties);
         this.manager = manager;
         this.immediateFlush = immediateFlush;
     }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractWriterAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractWriterAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractWriterAppender.java
index 81c1391..f94ef59 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractWriterAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AbstractWriterAppender.java
@@ -1,126 +1,148 @@
-/*
- * 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.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.apache.logging.log4j.core.Filter;
-import org.apache.logging.log4j.core.LogEvent;
-import org.apache.logging.log4j.core.StringLayout;
-
-/**
- * Appends log events as strings to a writer.
- * 
- * @param <M>
- *            The kind of {@link WriterManager} under management
- */
-public abstract class AbstractWriterAppender<M extends WriterManager> extends AbstractAppender {
-
-    /**
-     * Immediate flush means that the underlying writer will be flushed at the
-     * end of each append operation. Immediate flush is slower but ensures that
-     * each append request is actually written. If <code>immediateFlush</code>
-     * is set to {@code false}, then there is a good chance that the last few
-     * logs events are not actually written to persistent media if and when the
-     * application crashes.
-     */
-    protected final boolean immediateFlush;
-    private final M manager;
-    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
-    private final Lock readLock = readWriteLock.readLock();
-
-    /**
-     * Instantiates.
-     * 
-     * @param name
-     *            The name of the Appender.
-     * @param layout
-     *            The layout to format the message.
-     * @param manager
-     *            The OutputStreamManager.
-     */
-    protected AbstractWriterAppender(final String name, final StringLayout layout, final Filter filter,
-            final boolean ignoreExceptions, final boolean immediateFlush, final M manager) {
-        super(name, filter, layout, ignoreExceptions);
-        this.manager = manager;
-        this.immediateFlush = immediateFlush;
-    }
-
-    /**
-     * Actual writing occurs here.
-     * <p>
-     * Most subclasses will need to override this method.
-     * </p>
-     * 
-     * @param event
-     *            The LogEvent.
-     */
-    @Override
-    public void append(final LogEvent event) {
-        readLock.lock();
-        try {
-            final String str = getStringLayout().toSerializable(event);
-            if (str.length() > 0) {
-                manager.write(str);
-                if (this.immediateFlush || event.isEndOfBatch()) {
-                    manager.flush();
-                }
-            }
-        } catch (final AppenderLoggingException ex) {
-            error("Unable to write " + manager.getName() + " for appender " + getName(), event, ex);
-            throw ex;
-        } finally {
-            readLock.unlock();
-        }
-    }
-
-    /**
-     * Gets the manager.
-     * 
-     * @return the manager.
-     */
-    public M getManager() {
-        return manager;
-    }
-
-    public StringLayout getStringLayout() {
-        return (StringLayout) getLayout();
-    }
-
-    @Override
-    public void start() {
-        if (getLayout() == null) {
-            LOGGER.error("No layout set for the appender named [{}].", getName());
-        }
-        if (manager == null) {
-            LOGGER.error("No OutputStreamManager set for the appender named [{}].", getName());
-        }
-        super.start();
-    }
-
-    @Override
-    public boolean stop(final long timeout, final TimeUnit timeUnit) {
-        setStopping();
-        boolean stopped = super.stop(timeout, timeUnit, false);
-        stopped &= manager.stop(timeout, timeUnit);
-        setStopped();
-        return stopped;
-    }
-}
+/*
+ * 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.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.logging.log4j.core.Filter;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.StringLayout;
+import org.apache.logging.log4j.core.config.Property;
+
+/**
+ * Appends log events as strings to a writer.
+ * 
+ * @param <M>
+ *            The kind of {@link WriterManager} under management
+ */
+public abstract class AbstractWriterAppender<M extends WriterManager> extends AbstractAppender {
+
+    /**
+     * Immediate flush means that the underlying writer will be flushed at the
+     * end of each append operation. Immediate flush is slower but ensures that
+     * each append request is actually written. If <code>immediateFlush</code>
+     * is set to {@code false}, then there is a good chance that the last few
+     * logs events are not actually written to persistent media if and when the
+     * application crashes.
+     */
+    protected final boolean immediateFlush;
+    private final M manager;
+    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
+    private final Lock readLock = readWriteLock.readLock();
+
+    /**
+     * Instantiates.
+     * 
+     * @param name
+     *            The name of the Appender.
+     * @param layout
+     *            The layout to format the message.
+     * @param properties 
+     *            Optional properties.
+     * @param manager
+     *            The OutputStreamManager.
+     */
+    protected AbstractWriterAppender(final String name, final StringLayout layout, final Filter filter,
+            final boolean ignoreExceptions, final boolean immediateFlush, Property[] properties, final M manager) {
+        super(name, filter, layout, ignoreExceptions, properties);
+        this.manager = manager;
+        this.immediateFlush = immediateFlush;
+    }
+
+    /**
+     * Instantiates.
+     * 
+     * @param name
+     *            The name of the Appender.
+     * @param layout
+     *            The layout to format the message.
+     * @param manager
+     *            The OutputStreamManager.
+     * @deprecated Use {@link #AbstractWriterAppender(String, StringLayout, Filter, boolean, boolean, Property[], WriterManager)}.
+     */
+    @Deprecated
+    protected AbstractWriterAppender(final String name, final StringLayout layout, final Filter filter,
+            final boolean ignoreExceptions, final boolean immediateFlush, final M manager) {
+        super(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
+        this.manager = manager;
+        this.immediateFlush = immediateFlush;
+    }
+
+    /**
+     * Actual writing occurs here.
+     * <p>
+     * Most subclasses will need to override this method.
+     * </p>
+     * 
+     * @param event
+     *            The LogEvent.
+     */
+    @Override
+    public void append(final LogEvent event) {
+        readLock.lock();
+        try {
+            final String str = getStringLayout().toSerializable(event);
+            if (str.length() > 0) {
+                manager.write(str);
+                if (this.immediateFlush || event.isEndOfBatch()) {
+                    manager.flush();
+                }
+            }
+        } catch (final AppenderLoggingException ex) {
+            error("Unable to write " + manager.getName() + " for appender " + getName(), event, ex);
+            throw ex;
+        } finally {
+            readLock.unlock();
+        }
+    }
+
+    /**
+     * Gets the manager.
+     * 
+     * @return the manager.
+     */
+    public M getManager() {
+        return manager;
+    }
+
+    public StringLayout getStringLayout() {
+        return (StringLayout) getLayout();
+    }
+
+    @Override
+    public void start() {
+        if (getLayout() == null) {
+            LOGGER.error("No layout set for the appender named [{}].", getName());
+        }
+        if (manager == null) {
+            LOGGER.error("No OutputStreamManager set for the appender named [{}].", getName());
+        }
+        super.start();
+    }
+
+    @Override
+    public boolean stop(final long timeout, final TimeUnit timeUnit) {
+        setStopping();
+        boolean stopped = super.stop(timeout, timeUnit, false);
+        stopped &= manager.stop(timeout, timeUnit);
+        setStopped();
+        return stopped;
+    }
+}

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java
index b0ed1d9..bf8a163 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/AsyncAppender.java
@@ -41,6 +41,7 @@ import org.apache.logging.log4j.core.config.AppenderControl;
 import org.apache.logging.log4j.core.config.AppenderRef;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.ConfigurationException;
+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.PluginAliases;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
@@ -62,6 +63,7 @@ public final class AsyncAppender extends AbstractAppender {
 
     private static final int DEFAULT_QUEUE_SIZE = 1024;
     private static final LogEvent SHUTDOWN_LOG_EVENT = new AbstractLogEvent() {
+        private static final long serialVersionUID = -1761035149477086330L;
     };
 
     private static final AtomicLong THREAD_SEQUENCE = new AtomicLong(1);
@@ -79,10 +81,10 @@ public final class AsyncAppender extends AbstractAppender {
     private AsyncQueueFullPolicy asyncQueueFullPolicy;
 
     private AsyncAppender(final String name, final Filter filter, final AppenderRef[] appenderRefs,
-                          final String errorRef, final int queueSize, final boolean blocking,
-                          final boolean ignoreExceptions, final long shutdownTimeout, final Configuration config,
-                          final boolean includeLocation, final BlockingQueueFactory<LogEvent> blockingQueueFactory) {
-        super(name, filter, null, ignoreExceptions);
+            final String errorRef, final int queueSize, final boolean blocking, final boolean ignoreExceptions,
+            final long shutdownTimeout, final Configuration config, final boolean includeLocation,
+            final BlockingQueueFactory<LogEvent> blockingQueueFactory, final Property[] properties) {
+        super(name, filter, null, ignoreExceptions, properties);
         this.queue = blockingQueueFactory.create(queueSize);
         this.queueSize = queueSize;
         this.blocking = blocking;
@@ -270,7 +272,7 @@ public final class AsyncAppender extends AbstractAppender {
         }
 
         return new AsyncAppender(name, filter, appenderRefs, errorRef, size, blocking, ignoreExceptions,
-            shutdownTimeout, config, includeLocation, new ArrayBlockingQueueFactory<LogEvent>());
+            shutdownTimeout, config, includeLocation, new ArrayBlockingQueueFactory<LogEvent>(), null);
     }
 
     @PluginBuilderFactory
@@ -374,7 +376,7 @@ public final class AsyncAppender extends AbstractAppender {
         @Override
         public AsyncAppender build() {
             return new AsyncAppender(name, filter, appenderRefs, errorRef, bufferSize, blocking, ignoreExceptions,
-                shutdownTimeout, configuration, includeLocation, blockingQueueFactory);
+                shutdownTimeout, configuration, includeLocation, blockingQueueFactory, null);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
index 8e3b453..7a9864f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java
@@ -20,6 +20,7 @@ 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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
@@ -90,8 +91,9 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
     }
 
     private ConsoleAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
-            final OutputStreamManager manager, final boolean ignoreExceptions, final Target target) {
-        super(name, layout, filter, ignoreExceptions, true, manager);
+            final OutputStreamManager manager, final boolean ignoreExceptions, final Target target,
+            Property[] properties) {
+        super(name, layout, filter, ignoreExceptions, true, properties, manager);
         this.target = target;
     }
 
@@ -125,7 +127,7 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
         final boolean isFollow = Boolean.parseBoolean(follow);
         final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
         final Target target = targetStr == null ? DEFAULT_TARGET : Target.valueOf(targetStr);
-        return new ConsoleAppender(name, layout, filter, getManager(target, isFollow, false, layout), ignoreExceptions, target);
+        return new ConsoleAppender(name, layout, filter, getManager(target, isFollow, false, layout), ignoreExceptions, target, null);
     }
 
     /**
@@ -166,13 +168,13 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
             LOGGER.error("Cannot use both follow and direct on ConsoleAppender");
             return null;
         }
-        return new ConsoleAppender(name, layout, filter, getManager(target, follow, direct, layout), ignoreExceptions, target);
+        return new ConsoleAppender(name, layout, filter, getManager(target, follow, direct, layout), ignoreExceptions, target, null);
     }
 
     public static ConsoleAppender createDefaultAppenderForLayout(final Layout<? extends Serializable> layout) {
         // this method cannot use the builder class without introducing an infinite loop due to DefaultConfiguration
         return new ConsoleAppender("DefaultConsole-" + COUNT.incrementAndGet(), layout, null,
-                getDefaultManager(DEFAULT_TARGET, false, false, layout), true, DEFAULT_TARGET);
+                getDefaultManager(DEFAULT_TARGET, false, false, layout), true, DEFAULT_TARGET, null);
     }
 
     @PluginBuilderFactory
@@ -219,7 +221,7 @@ public final class ConsoleAppender extends AbstractOutputStreamAppender<OutputSt
             }
             final Layout<? extends Serializable> layout = getOrCreateLayout(target.getDefaultCharset());
             return new ConsoleAppender(getName(), layout, getFilter(), getManager(target, follow, direct, layout),
-                    isIgnoreExceptions(), target);
+                    isIgnoreExceptions(), target, getPropertyArray());
         }
     }
 

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/CountingNoOpAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/CountingNoOpAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/CountingNoOpAppender.java
index 0e3ac47..4c4c68e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/CountingNoOpAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/CountingNoOpAppender.java
@@ -23,6 +23,7 @@ import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.Core;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
+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.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
@@ -36,7 +37,11 @@ public class CountingNoOpAppender extends AbstractAppender  {
     private final AtomicLong total = new AtomicLong();
 
     public CountingNoOpAppender(final String name, final Layout<?> layout) {
-        super(name, null, layout);
+        super(name, null, layout, true, Property.EMPTY_ARRAY);
+    }
+
+    private CountingNoOpAppender(final String name, final Layout<?> layout, final Property[] properties) {
+        super(name, null, layout, true, properties);
     }
 
     public long getCount() {
@@ -53,6 +58,6 @@ public class CountingNoOpAppender extends AbstractAppender  {
      */
     @PluginFactory
     public static CountingNoOpAppender createAppender(@PluginAttribute("name") final String name) {
-        return new CountingNoOpAppender(Objects.requireNonNull(name), null);
+        return new CountingNoOpAppender(Objects.requireNonNull(name), null, Property.EMPTY_ARRAY);
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FailoverAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FailoverAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FailoverAppender.java
index 659caf1..3032e30 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FailoverAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FailoverAppender.java
@@ -28,6 +28,7 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.AppenderControl;
 import org.apache.logging.log4j.core.config.Configuration;
+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.PluginAliases;
 import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
@@ -62,15 +63,15 @@ public final class FailoverAppender extends AbstractAppender {
     private volatile long nextCheckNanos = 0;
 
     private FailoverAppender(final String name, final Filter filter, final String primary, final String[] failovers,
-                             final int intervalMillis, final Configuration config, final boolean ignoreExceptions) {
-        super(name, filter, null, ignoreExceptions);
+            final int intervalMillis, final Configuration config, final boolean ignoreExceptions,
+            Property[] properties) {
+        super(name, filter, null, ignoreExceptions, properties);
         this.primaryRef = primary;
         this.failovers = failovers;
         this.config = config;
         this.intervalNanos = TimeUnit.MILLISECONDS.toNanos(intervalMillis);
     }
 
-
     @Override
     public void start() {
         final Map<String, Appender> map = config.getAppenders();
@@ -213,6 +214,6 @@ public final class FailoverAppender extends AbstractAppender {
 
         final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true);
 
-        return new FailoverAppender(name, filter, primary, failovers, retryIntervalMillis, config, ignoreExceptions);
+        return new FailoverAppender(name, filter, primary, failovers, retryIntervalMillis, config, ignoreExceptions, null);
     }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
index 034fb15..7dd239b 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/FileAppender.java
@@ -26,6 +26,7 @@ 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.Configuration;
+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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
@@ -99,7 +100,8 @@ public final class FileAppender extends AbstractOutputStreamAppender<FileManager
             }
 
             return new FileAppender(getName(), layout, getFilter(), manager, fileName, isIgnoreExceptions(),
-                    !bufferedIo || isImmediateFlush(), advertise ? getConfiguration().getAdvertiser() : null);
+                    !bufferedIo || isImmediateFlush(), advertise ? getConfiguration().getAdvertiser() : null,
+                    getPropertyArray());
         }
 
         public String getAdvertiseUri() {
@@ -232,12 +234,9 @@ public final class FileAppender extends AbstractOutputStreamAppender<FileManager
         .withBufferedIo(Booleans.parseBoolean(bufferedIo, true))
         .withBufferSize(Integers.parseInt(bufferSizeStr, DEFAULT_BUFFER_SIZE))
         .setConfiguration(config)
-        .withFileName(fileName).setFilter(filter)
-            .withIgnoreExceptions(Booleans.parseBoolean(ignoreExceptions, true))
-            .withImmediateFlush(Booleans.parseBoolean(immediateFlush, true))
-            .withLayout(layout)
-            .withLocking(Boolean.parseBoolean(locking))
-            .withName(name)
+        .withFileName(fileName).setFilter(filter).setIgnoreExceptions(Booleans.parseBoolean(ignoreExceptions, true))
+            .withImmediateFlush(Booleans.parseBoolean(immediateFlush, true)).setLayout(layout)
+            .withLocking(Boolean.parseBoolean(locking)).setName(name)
             .build();
         // @formatter:on
     }
@@ -255,9 +254,9 @@ public final class FileAppender extends AbstractOutputStreamAppender<FileManager
 
     private FileAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
             final FileManager manager, final String filename, final boolean ignoreExceptions,
-            final boolean immediateFlush, final Advertiser advertiser) {
+            final boolean immediateFlush, final Advertiser advertiser, Property[] properties) {
 
-        super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
+        super(name, layout, filter, ignoreExceptions, immediateFlush, properties, manager);
         if (advertiser != null) {
             final Map<String, String> configuration = new HashMap<>(layout.getContentFormat());
             configuration.putAll(manager.getContentFormat());

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java
index 59f93c8..f7ced5c 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/HttpAppender.java
@@ -72,9 +72,11 @@ public final class HttpAppender extends AbstractAppender {
 
         @Override
         public HttpAppender build() {
-            final HttpManager httpManager = new HttpURLConnectionManager(getConfiguration(), getConfiguration().getLoggerContext(),
-                getName(), url, method, connectTimeoutMillis, readTimeoutMillis, headers, sslConfiguration, verifyHostname);
-            return new HttpAppender(getName(), getLayout(), getFilter(), isIgnoreExceptions(), httpManager);
+            final HttpManager httpManager = new HttpURLConnectionManager(getConfiguration(),
+                    getConfiguration().getLoggerContext(), getName(), url, method, connectTimeoutMillis,
+                    readTimeoutMillis, headers, sslConfiguration, verifyHostname);
+            return new HttpAppender(getName(), getLayout(), getFilter(), isIgnoreExceptions(), httpManager,
+                    getPropertyArray());
         }
 
         public URL getUrl() {
@@ -152,8 +154,8 @@ public final class HttpAppender extends AbstractAppender {
     private final HttpManager manager;
 
     private HttpAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
-                         final boolean ignoreExceptions, final HttpManager manager) {
-        super(name, filter, layout, ignoreExceptions);
+            final boolean ignoreExceptions, final HttpManager manager, final Property[] properties) {
+        super(name, filter, layout, ignoreExceptions, properties);
         Objects.requireNonNull(layout, "layout");
         this.manager = Objects.requireNonNull(manager, "manager");
     }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileAppender.java
index a6162bd..15a3a63 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/MemoryMappedFileAppender.java
@@ -27,6 +27,7 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
+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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
@@ -88,7 +89,7 @@ public final class MemoryMappedFileAppender extends AbstractOutputStreamAppender
             }
 
             return new MemoryMappedFileAppender(name, layout, getFilter(), manager, fileName, isIgnoreExceptions(), false,
-                    advertise ? getConfiguration().getAdvertiser() : null);
+                    advertise ? getConfiguration().getAdvertiser() : null, getPropertyArray());
         }
 
         public B setFileName(final String fileName) {
@@ -128,8 +129,9 @@ public final class MemoryMappedFileAppender extends AbstractOutputStreamAppender
 
     private MemoryMappedFileAppender(final String name, final Layout<? extends Serializable> layout,
             final Filter filter, final MemoryMappedFileManager manager, final String filename,
-            final boolean ignoreExceptions, final boolean immediateFlush, final Advertiser advertiser) {
-        super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
+            final boolean ignoreExceptions, final boolean immediateFlush, final Advertiser advertiser,
+            final Property[] properties) {
+        super(name, layout, filter, ignoreExceptions, immediateFlush, properties, manager);
         if (advertiser != null) {
             final Map<String, String> configuration = new HashMap<>(layout.getContentFormat());
             configuration.putAll(manager.getContentFormat());
@@ -237,11 +239,8 @@ public final class MemoryMappedFileAppender extends AbstractOutputStreamAppender
         .setAdvertiseURI(advertiseURI)
         .setAppend(isAppend)
         .setConfiguration(config)
-        .setFileName(fileName).setFilter(filter)
-            .withIgnoreExceptions(ignoreExceptions)
-            .withImmediateFlush(isImmediateFlush)
-            .withLayout(layout)
-            .withName(name)
+        .setFileName(fileName).setFilter(filter).setIgnoreExceptions(ignoreExceptions)
+            .withImmediateFlush(isImmediateFlush).setLayout(layout).setName(name)
             .setRegionLength(regionLength)
             .build();
         // @formatter:on

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/NullAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/NullAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/NullAppender.java
index 1733f9a..b90a8dd 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/NullAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/NullAppender.java
@@ -19,6 +19,7 @@ package org.apache.logging.log4j.core.appender;
 import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.Core;
 import org.apache.logging.log4j.core.LogEvent;
+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.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginFactory;
@@ -39,8 +40,7 @@ public class NullAppender extends AbstractAppender {
 	}
 
 	private NullAppender(final String name) {
-		super(name, null, null);
-		// Do nothing
+		super(name, null, null, true, Property.EMPTY_ARRAY);
 	}
 
 	@Override

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/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
index ddca626..3c84938 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
@@ -23,6 +23,8 @@ 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.appender.MemoryMappedFileAppender.Builder;
+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;
@@ -41,7 +43,8 @@ public final class OutputStreamAppender extends AbstractOutputStreamAppender<Out
     /**
      * Builds OutputStreamAppender instances.
      */
-    public static class Builder implements org.apache.logging.log4j.core.util.Builder<OutputStreamAppender> {
+    public static class Builder<B extends Builder<B>> extends AbstractOutputStreamAppender.Builder<B>
+            implements org.apache.logging.log4j.core.util.Builder<OutputStreamAppender> {
 
         private Filter filter;
 
@@ -49,47 +52,28 @@ public final class OutputStreamAppender extends AbstractOutputStreamAppender<Out
 
         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);
+            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 Builder setFilter(final Filter aFilter) {
-            this.filter = aFilter;
-            return this;
-        }
-
-        public Builder setFollow(final boolean shouldFollow) {
+        public B 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;
+            return asBuilder();
         }
 
-        public Builder setTarget(final OutputStream aTarget) {
+        public B setTarget(final OutputStream aTarget) {
             this.target = aTarget;
-            return this;
+            return asBuilder();
         }
     }
+    
     /**
      * Holds data to pass to factory method.
      */
@@ -167,7 +151,7 @@ public final class OutputStreamAppender extends AbstractOutputStreamAppender<Out
         if (layout == null) {
             layout = PatternLayout.createDefaultLayout();
         }
-        return new OutputStreamAppender(name, layout, filter, getManager(target, follow, layout), ignore);
+        return new OutputStreamAppender(name, layout, filter, getManager(target, follow, layout), ignore, null);
     }
 
     private static OutputStreamManager getManager(final OutputStream target, final boolean follow,
@@ -184,8 +168,8 @@ public final class OutputStreamAppender extends AbstractOutputStreamAppender<Out
     }
 
     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);
+            final OutputStreamManager manager, final boolean ignoreExceptions, final Property[] properties) {
+        super(name, layout, filter, ignoreExceptions, true, properties, manager);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileAppender.java
index 0ea8d99..98df988 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RandomAccessFileAppender.java
@@ -27,6 +27,7 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
+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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
@@ -82,7 +83,7 @@ public final class RandomAccessFileAppender extends AbstractOutputStreamAppender
             }
 
             return new RandomAccessFileAppender(name, layout, getFilter(), manager, fileName, isIgnoreExceptions(),
-                    immediateFlush, advertise ? getConfiguration().getAdvertiser() : null);
+                    immediateFlush, advertise ? getConfiguration().getAdvertiser() : null, getPropertyArray());
         }
 
         public B setFileName(final String fileName) {
@@ -113,9 +114,10 @@ public final class RandomAccessFileAppender extends AbstractOutputStreamAppender
 
     private RandomAccessFileAppender(final String name, final Layout<? extends Serializable> layout,
             final Filter filter, final RandomAccessFileManager manager, final String filename,
-            final boolean ignoreExceptions, final boolean immediateFlush, final Advertiser advertiser) {
+            final boolean ignoreExceptions, final boolean immediateFlush, final Advertiser advertiser, 
+            final Property[] properties) {
 
-        super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
+        super(name, layout, filter, ignoreExceptions, immediateFlush, properties, manager);
         if (advertiser != null) {
             final Map<String, String> configuration = new HashMap<>(
                     layout.getContentFormat());
@@ -227,11 +229,8 @@ public final class RandomAccessFileAppender extends AbstractOutputStreamAppender
         .setAppend(isAppend)
         .withBufferSize(bufferSize)
         .setConfiguration(configuration)
-        .setFileName(fileName).setFilter(filter)
-            .withIgnoreExceptions(ignoreExceptions)
-            .withImmediateFlush(isFlush)
-            .withLayout(layout)
-            .withName(name)
+        .setFileName(fileName).setFilter(filter).setIgnoreExceptions(ignoreExceptions)
+            .withImmediateFlush(isFlush).setLayout(layout).setName(name)
             .build();
     }
     

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
index cb9303a..ed42236 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingFileAppender.java
@@ -34,6 +34,7 @@ import org.apache.logging.log4j.core.appender.rolling.RollingFileManager;
 import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy;
 import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
 import org.apache.logging.log4j.core.config.Configuration;
+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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
@@ -152,7 +153,8 @@ public final class RollingFileAppender extends AbstractOutputStreamAppender<Roll
             manager.initialize();
 
             return new RollingFileAppender(getName(), layout, getFilter(), manager, fileName, filePattern,
-                    isIgnoreExceptions(), isImmediateFlush(), advertise ? getConfiguration().getAdvertiser() : null);
+                    isIgnoreExceptions(), isImmediateFlush(), advertise ? getConfiguration().getAdvertiser() : null,
+                    getPropertyArray());
         }
 
         public String getAdvertiseUri() {
@@ -274,8 +276,9 @@ public final class RollingFileAppender extends AbstractOutputStreamAppender<Roll
 
     private RollingFileAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
             final RollingFileManager manager, final String fileName, final String filePattern,
-            final boolean ignoreExceptions, final boolean immediateFlush, final Advertiser advertiser) {
-        super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
+            final boolean ignoreExceptions, final boolean immediateFlush, final Advertiser advertiser,
+            final Property[] properties) {
+        super(name, layout, filter, ignoreExceptions, immediateFlush, properties, manager);
         if (advertiser != null) {
             final Map<String, String> configuration = new HashMap<>(layout.getContentFormat());
             configuration.put("contentType", layout.getContentType());
@@ -385,13 +388,10 @@ public final class RollingFileAppender extends AbstractOutputStreamAppender<Roll
         .withBufferSize(bufferSize)
         .setConfiguration(config)
         .withFileName(fileName)
-        .withFilePattern(filePattern).setFilter(filter)
-                .withIgnoreExceptions(Booleans.parseBoolean(ignore, true))
-                .withImmediateFlush(Booleans.parseBoolean(immediateFlush, true))
-                .withLayout(layout)
+        .withFilePattern(filePattern).setFilter(filter).setIgnoreExceptions(Booleans.parseBoolean(ignore, true))
+                .withImmediateFlush(Booleans.parseBoolean(immediateFlush, true)).setLayout(layout)
                 .withCreateOnDemand(false)
-                .withLocking(false)
-                .withName(name)
+                .withLocking(false).setName(name)
                 .withPolicy(policy)
                 .withStrategy(strategy)
                 .build();

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
index a3d8611..87bd023 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/RollingRandomAccessFileAppender.java
@@ -34,6 +34,7 @@ import org.apache.logging.log4j.core.appender.rolling.RollingRandomAccessFileMan
 import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy;
 import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
 import org.apache.logging.log4j.core.config.Configuration;
+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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
@@ -55,7 +56,7 @@ public final class RollingRandomAccessFileAppender extends AbstractOutputStreamA
         public Builder() {
             super();
             withBufferSize(RollingRandomAccessFileManager.DEFAULT_BUFFER_SIZE);
-            withIgnoreExceptions(true);
+            setIgnoreExceptions(true);
             withImmediateFlush(true);
         }
 
@@ -138,8 +139,9 @@ public final class RollingRandomAccessFileAppender extends AbstractOutputStreamA
 
             manager.initialize();
 
-            return new RollingRandomAccessFileAppender(name, layout,getFilter(), manager, fileName, filePattern,
-                    isIgnoreExceptions(), immediateFlush, bufferSize, advertise ? getConfiguration().getAdvertiser() : null);
+            return new RollingRandomAccessFileAppender(name, layout, getFilter(), manager, fileName, filePattern,
+                    isIgnoreExceptions(), immediateFlush, bufferSize,
+                    advertise ? getConfiguration().getAdvertiser() : null, getPropertyArray());
         }
 
         public B withFileName(final String fileName) {
@@ -201,9 +203,9 @@ public final class RollingRandomAccessFileAppender extends AbstractOutputStreamA
 
     private RollingRandomAccessFileAppender(final String name, final Layout<? extends Serializable> layout,
             final Filter filter, final RollingRandomAccessFileManager manager, final String fileName,
-            final String filePattern, final boolean ignoreExceptions,
-            final boolean immediateFlush, final int bufferSize, final Advertiser advertiser) {
-        super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
+            final String filePattern, final boolean ignoreExceptions, final boolean immediateFlush,
+            final int bufferSize, final Advertiser advertiser, final Property[] properties) {
+        super(name, layout, filter, ignoreExceptions, immediateFlush, properties, manager);
         if (advertiser != null) {
             final Map<String, String> configuration = new HashMap<>(layout.getContentFormat());
             configuration.put("contentType", layout.getContentType());
@@ -334,11 +336,8 @@ public final class RollingRandomAccessFileAppender extends AbstractOutputStreamA
            .withBufferSize(bufferSize)
            .setConfiguration(configuration)
            .withFileName(fileName)
-           .withFilePattern(filePattern).setFilter(filter)
-           .withIgnoreExceptions(isIgnoreExceptions)
-           .withImmediateFlush(isImmediateFlush)
-           .withLayout(layout)
-           .withName(name)
+           .withFilePattern(filePattern).setFilter(filter).setIgnoreExceptions(isIgnoreExceptions)
+           .withImmediateFlush(isImmediateFlush).setLayout(layout).setName(name)
            .withPolicy(policy)
            .withStrategy(strategy)
            .build();

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelector.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelector.java
index 30a28f1..0d9cefa 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelector.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/ScriptAppenderSelector.java
@@ -27,6 +27,7 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
+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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
@@ -132,8 +133,9 @@ public class ScriptAppenderSelector extends AbstractAppender {
         return new Builder();
     }
 
-    private ScriptAppenderSelector(final String name, final Filter filter, final Layout<? extends Serializable> layout) {
-        super(name, filter, layout);
+    private ScriptAppenderSelector(final String name, final Filter filter, final Layout<? extends Serializable> layout,
+            final Property[] properties) {
+        super(name, filter, layout, true, Property.EMPTY_ARRAY);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SmtpAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SmtpAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SmtpAppender.java
index e3aac4d..714fe2d 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SmtpAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SmtpAppender.java
@@ -26,6 +26,7 @@ import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.DefaultConfiguration;
+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.PluginAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
@@ -64,9 +65,9 @@ public final class SmtpAppender extends AbstractAppender {
     /** The SMTP Manager */
     private final SmtpManager manager;
 
-    private SmtpAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout, final SmtpManager manager,
-                         final boolean ignoreExceptions) {
-        super(name, filter, layout, ignoreExceptions);
+    private SmtpAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout,
+            final SmtpManager manager, final boolean ignoreExceptions, final Property[] properties) {
+        super(name, filter, layout, ignoreExceptions, properties);
         this.manager = manager;
     }
 
@@ -153,7 +154,7 @@ public final class SmtpAppender extends AbstractAppender {
             return null;
         }
 
-        return new SmtpAppender(name, filter, layout, manager, ignoreExceptions);
+        return new SmtpAppender(name, filter, layout, manager, ignoreExceptions, null);
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java
index ce4d254..39be95e 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SocketAppender.java
@@ -28,6 +28,7 @@ import org.apache.logging.log4j.core.Filter;
 import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.config.Configuration;
+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.PluginAliases;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
@@ -221,7 +222,8 @@ public class SocketAppender extends AbstractOutputStreamAppender<AbstractSocketM
                     getConnectTimeoutMillis(), getSslConfiguration(), getReconnectDelayMillis(), getImmediateFail(), layout, getBufferSize(), getSocketOptions());
 
             return new SocketAppender(name, layout, getFilter(), manager, isIgnoreExceptions(),
-                    !bufferedIo || immediateFlush, getAdvertise() ? getConfiguration().getAdvertiser() : null);
+                    !bufferedIo || immediateFlush, getAdvertise() ? getConfiguration().getAdvertiser() : null,
+                    getPropertyArray());
         }
     }
     
@@ -235,8 +237,8 @@ public class SocketAppender extends AbstractOutputStreamAppender<AbstractSocketM
 
     protected SocketAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
             final AbstractSocketManager manager, final boolean ignoreExceptions, final boolean immediateFlush,
-            final Advertiser advertiser) {
-        super(name, layout, filter, ignoreExceptions, immediateFlush, manager);
+            final Advertiser advertiser, final Property[] properties) {
+        super(name, layout, filter, ignoreExceptions, immediateFlush, properties, manager);
         if (advertiser != null) {
             final Map<String, String> configuration = new HashMap<>(layout.getContentFormat());
             configuration.putAll(manager.getContentFormat());
@@ -249,6 +251,16 @@ public class SocketAppender extends AbstractOutputStreamAppender<AbstractSocketM
         this.advertiser = advertiser;
     }
 
+    /**
+     * @deprecated {@link #SocketAppender(String, Layout, Filter, AbstractSocketManager, boolean, boolean, Advertiser, Property[])}.
+     */
+    @Deprecated
+    protected SocketAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
+            final AbstractSocketManager manager, final boolean ignoreExceptions, final boolean immediateFlush,
+            final Advertiser advertiser) {
+        this(name, layout, filter, manager, ignoreExceptions, immediateFlush, advertiser, Property.EMPTY_ARRAY);
+    }
+
     @Override
     public boolean stop(final long timeout, final TimeUnit timeUnit) {
         setStopping();
@@ -320,11 +332,8 @@ public class SocketAppender extends AbstractOutputStreamAppender<AbstractSocketM
         .withAdvertise(advertise)
         .setConfiguration(configuration)
         .withConnectTimeoutMillis(connectTimeoutMillis).setFilter(filter)
-            .withHost(host)
-            .withIgnoreExceptions(ignoreExceptions)
-            .withImmediateFail(immediateFail)
-            .withLayout(layout)
-            .withName(name)
+            .withHost(host).setIgnoreExceptions(ignoreExceptions)
+            .withImmediateFail(immediateFail).setLayout(layout).setName(name)
             .withPort(port)
             .withProtocol(protocol)
             .withReconnectDelayMillis(reconnectDelayMillis)

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
index 2b14598..87ec9f8 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/SyslogAppender.java
@@ -25,6 +25,7 @@ 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.Configuration;
+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.PluginBuilderAttribute;
 import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
@@ -124,7 +125,7 @@ public class SyslogAppender extends SocketAppender {
                             .setEscapeNL(escapeNL)
                             .setCharset(charsetName)
                             .build();
-                        // @formatter:off
+                        // @formatter:on
             }
             final String name = getName();
             if (name == null) {
@@ -135,7 +136,7 @@ public class SyslogAppender extends SocketAppender {
                     sslConfiguration, getReconnectDelayMillis(), getImmediateFail(), layout, Constants.ENCODER_BYTE_BUFFER_SIZE, null);
 
             return new SyslogAppender(name, layout, getFilter(), isIgnoreExceptions(), isImmediateFlush(), manager,
-                    getAdvertise() ? configuration.getAdvertiser() : null);
+                    getAdvertise() ? configuration.getAdvertiser() : null, null);
         }
 
         public Facility getFacility() {
@@ -305,9 +306,19 @@ public class SyslogAppender extends SocketAppender {
 
     protected SyslogAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
                              final boolean ignoreExceptions, final boolean immediateFlush,
-                             final AbstractSocketManager manager, final Advertiser advertiser) {
-        super(name, layout, filter, manager, ignoreExceptions, immediateFlush, advertiser);
+                             final AbstractSocketManager manager, final Advertiser advertiser, Property[] properties) {
+        super(name, layout, filter, manager, ignoreExceptions, immediateFlush, advertiser, properties);
+    }
 
+    /**
+     * @deprecated Use
+     * {@link #SyslogAppender(String, Layout, Filter, boolean, boolean, AbstractSocketManager, Advertiser, Property[])}.
+     */
+    @Deprecated
+    protected SyslogAppender(final String name, final Layout<? extends Serializable> layout, final Filter filter,
+            final boolean ignoreExceptions, final boolean immediateFlush, final AbstractSocketManager manager,
+            final Advertiser advertiser) {
+        super(name, layout, filter, manager, ignoreExceptions, immediateFlush, advertiser, Property.EMPTY_ARRAY);
     }
 
     /**
@@ -393,10 +404,8 @@ public class SyslogAppender extends SocketAppender {
         .withSslConfiguration(sslConfiguration)
         .withConnectTimeoutMillis(connectTimeoutMillis)
         .withReconnectDelayMillis(reconnectDelayMillis)
-        .withImmediateFail(immediateFail)
-        .withName(appName)
-        .withImmediateFlush(immediateFlush)
-        .withIgnoreExceptions(ignoreExceptions).setFilter(filter)
+        .withImmediateFail(immediateFail).setName(appName)
+        .withImmediateFlush(immediateFlush).setIgnoreExceptions(ignoreExceptions).setFilter(filter)
                 .setConfiguration(configuration)
                 .withAdvertise(advertise)
                 .setFacility(facility)

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterAppender.java
index dc8f4d2..a5683eb 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/WriterAppender.java
@@ -16,12 +16,16 @@
  */
 package org.apache.logging.log4j.core.appender;
 
+import java.io.Serializable;
 import java.io.Writer;
 
 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.StringLayout;
+import org.apache.logging.log4j.core.appender.HttpAppender.Builder;
+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;
@@ -37,53 +41,29 @@ public final class WriterAppender extends AbstractWriterAppender<WriterManager>
     /**
      * Builds WriterAppender instances.
      */
-    public static class Builder implements org.apache.logging.log4j.core.util.Builder<WriterAppender> {
-
-        private Filter filter;
+    public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
+            implements org.apache.logging.log4j.core.util.Builder<WriterAppender> {
 
         private boolean follow = false;
 
-        private boolean ignoreExceptions = true;
-
-        private StringLayout layout = PatternLayout.createDefaultLayout();
-
-        private String name;
-
         private Writer target;
 
         @Override
         public WriterAppender build() {
-            return new WriterAppender(name, layout, filter, getManager(target, follow, layout), ignoreExceptions);
-        }
-
-        public Builder setFilter(final Filter aFilter) {
-            this.filter = aFilter;
-            return this;
+            StringLayout layout = (StringLayout) getLayout();
+            StringLayout actualLayout = layout != null ? layout : PatternLayout.createDefaultLayout();
+            return new WriterAppender(getName(), actualLayout, getFilter(), getManager(target, follow, actualLayout),
+                    isIgnoreExceptions(), getPropertyArray());
         }
 
-        public Builder setFollow(final boolean shouldFollow) {
+        public B setFollow(final boolean shouldFollow) {
             this.follow = shouldFollow;
-            return this;
-        }
-
-        public Builder setIgnoreExceptions(final boolean shouldIgnoreExceptions) {
-            this.ignoreExceptions = shouldIgnoreExceptions;
-            return this;
-        }
-
-        public Builder setLayout(final StringLayout aLayout) {
-            this.layout = aLayout;
-            return this;
-        }
-
-        public Builder setName(final String aName) {
-            this.name = aName;
-            return this;
+            return asBuilder();
         }
 
-        public Builder setTarget(final Writer aTarget) {
+        public B setTarget(final Writer aTarget) {
             this.target = aTarget;
-            return this;
+            return asBuilder();
         }
     }
     /**
@@ -160,7 +140,7 @@ public final class WriterAppender extends AbstractWriterAppender<WriterManager>
         if (layout == null) {
             layout = PatternLayout.createDefaultLayout();
         }
-        return new WriterAppender(name, layout, filter, getManager(target, follow, layout), ignore);
+        return new WriterAppender(name, layout, filter, getManager(target, follow, layout), ignore, null);
     }
 
     private static WriterManager getManager(final Writer target, final boolean follow, final StringLayout layout) {
@@ -176,8 +156,8 @@ public final class WriterAppender extends AbstractWriterAppender<WriterManager>
     }
 
     private WriterAppender(final String name, final StringLayout layout, final Filter filter,
-            final WriterManager manager, final boolean ignoreExceptions) {
-        super(name, layout, filter, ignoreExceptions, true, manager);
+            final WriterManager manager, final boolean ignoreExceptions, final Property[] properties) {
+        super(name, layout, filter, ignoreExceptions, true, properties, manager);
     }
 
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/61b77dfb/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java
index 09798fd..f720461 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/appender/db/AbstractDatabaseAppender.java
@@ -28,6 +28,7 @@ import org.apache.logging.log4j.core.Layout;
 import org.apache.logging.log4j.core.LogEvent;
 import org.apache.logging.log4j.core.appender.AbstractAppender;
 import org.apache.logging.log4j.core.appender.AppenderLoggingException;
+import org.apache.logging.log4j.core.config.Property;
 
 /**
  * An abstract Appender for writing events to a database of some type, be it relational or NoSQL. All database appenders
@@ -53,10 +54,12 @@ public abstract class AbstractDatabaseAppender<T extends AbstractDatabaseManager
      * @param ignoreExceptions If {@code true} exceptions encountered when appending events are logged; otherwise
      *                         they are propagated to the caller.
      * @param manager The matching {@link AbstractDatabaseManager} implementation.
+     * @deprecated Use {@link #AbstractDatabaseAppender(String, Filter, Layout, boolean, Property[], AbstractDatabaseManager)}.
      */
+    @Deprecated
     protected AbstractDatabaseAppender(final String name, final Filter filter, final boolean ignoreExceptions,
                                        final T manager) {
-        super(name, filter, null, ignoreExceptions);
+        super(name, filter, null, ignoreExceptions, Property.EMPTY_ARRAY);
         this.manager = manager;
     }
 
@@ -69,10 +72,29 @@ public abstract class AbstractDatabaseAppender<T extends AbstractDatabaseManager
      * @param ignoreExceptions If {@code true} exceptions encountered when appending events are logged; otherwise
      *                         they are propagated to the caller.
      * @param manager The matching {@link AbstractDatabaseManager} implementation.
+     * @deprecated Use {@link #AbstractDatabaseAppender(String, Filter, Layout, boolean, Property[], AbstractDatabaseManager)}
      */
+    @Deprecated
     protected AbstractDatabaseAppender(final String name, final Filter filter,
             final Layout<? extends Serializable> layout, final boolean ignoreExceptions, final T manager) {
-        super(name, filter, layout, ignoreExceptions);
+        super(name, filter, layout, ignoreExceptions, Property.EMPTY_ARRAY);
+        this.manager = manager;
+    }
+
+    /**
+     * Instantiates the base appender.
+     *
+     * @param name The appender name.
+     * @param filter The filter, if any, to use.
+     * @param layout The layout to use to format the event.
+     * @param ignoreExceptions If {@code true} exceptions encountered when appending events are logged; otherwise
+     *                         they are propagated to the caller.
+     * @param manager The matching {@link AbstractDatabaseManager} implementation.
+     */
+    protected AbstractDatabaseAppender(final String name, final Filter filter,
+            final Layout<? extends Serializable> layout, final boolean ignoreExceptions, 
+            final Property[] properties, final T manager) {
+        super(name, filter, layout, ignoreExceptions, properties);
         this.manager = manager;
     }