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 2022/01/20 15:14:42 UTC

[logging-log4j2] branch master updated (38cd370 -> 26716d6)

This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git.


    from 38cd370  Log4j 1.2 bridge now logs a warning instead of throwing an NullPointerException when building a Syslog appender with a missing "SyslogHost" param.
     new 7ae3b35  Log4j 1.2 bridge should allow property and XML attributes to start with either an upper-case or lower-case letter.
     new 26716d6  Log4j 1.2 bridge should allow property and XML attributes to start with either an upper-case or lower-case letter.

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../org/apache/log4j/builders/AbstractBuilder.java | 136 ++++++++++++---------
 .../builders/appender/AsyncAppenderBuilder.java    |   2 +-
 .../builders/appender/ConsoleAppenderBuilder.java  |  14 +--
 .../appender/DailyRollingFileAppenderBuilder.java  |   2 +-
 .../builders/appender/FileAppenderBuilder.java     |   2 +-
 .../builders/appender/RewriteAppenderBuilder.java  |   2 +-
 .../appender/RollingFileAppenderBuilder.java       |   2 +-
 .../builders/appender/SyslogAppenderBuilder.java   |  82 +++++++------
 .../builders/filter/LevelMatchFilterBuilder.java   |   2 +-
 .../builders/filter/LevelRangeFilterBuilder.java   |   4 +-
 .../builders/filter/StringMatchFilterBuilder.java  |   2 +-
 .../log4j/builders/layout/HtmlLayoutBuilder.java   |  15 +--
 .../log4j/builders/layout/TTCCLayoutBuilder.java   |   4 +-
 .../config/AbstractLog4j1ConfigurationTest.java    |  58 +++++++++
 .../config/Log4j1ConfigurationFactoryTest.java     |  54 ++++----
 .../log4j/config/PropertiesConfigurationTest.java  |  25 +++-
 .../config/SyslogAppenderConfigurationTest.java    |  87 +++++++++++++
 .../apache/log4j/config/XmlConfigurationTest.java  |  45 +++++--
 .../config-1.2/log4j-capitalization.properties     |  27 ++++
 .../resources/config-1.2/log4j-capitalization.xml  |  28 +++++
 .../log4j1-syslog-protocol-default.properties      |   9 ++
 .../log4j1-syslog-protocol-tcp.properties          |  10 ++
 ...1-syslog.xml => log4j1-syslog-protocol-tcp.xml} |   3 +-
 .../log4j1-syslog-protocol-udp.properties          |  10 ++
 ...1-syslog.xml => log4j1-syslog-protocol-udp.xml} |   3 +-
 25 files changed, 466 insertions(+), 162 deletions(-)
 create mode 100644 log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
 create mode 100644 log4j-1.2-api/src/test/java/org/apache/log4j/config/SyslogAppenderConfigurationTest.java
 create mode 100644 log4j-1.2-api/src/test/resources/config-1.2/log4j-capitalization.properties
 create mode 100644 log4j-1.2-api/src/test/resources/config-1.2/log4j-capitalization.xml
 create mode 100644 log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-default.properties
 create mode 100644 log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-tcp.properties
 copy log4j-1.2-api/src/test/resources/{log4j1-syslog.xml => log4j1-syslog-protocol-tcp.xml} (95%)
 create mode 100644 log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-udp.properties
 copy log4j-1.2-api/src/test/resources/{log4j1-syslog.xml => log4j1-syslog-protocol-udp.xml} (95%)

[logging-log4j2] 01/02: Log4j 1.2 bridge should allow property and XML attributes to start with either an upper-case or lower-case letter.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 7ae3b353f9feb01403a179ff8a10d90dee57f353
Author: Gary Gregory <ga...@gmail.com>
AuthorDate: Thu Jan 20 08:12:53 2022 -0500

    Log4j 1.2 bridge should allow property and XML attributes to start with
    either an upper-case or lower-case letter.
    
    For example, "target" vs. "Target" in
    "log4j.appender.Console.Target=System.err"
---
 .../org/apache/log4j/builders/AbstractBuilder.java | 136 ++++++++++++---------
 .../builders/appender/AsyncAppenderBuilder.java    |   2 +-
 .../builders/appender/ConsoleAppenderBuilder.java  |  14 +--
 .../appender/DailyRollingFileAppenderBuilder.java  |   2 +-
 .../builders/appender/FileAppenderBuilder.java     |   2 +-
 .../builders/appender/RewriteAppenderBuilder.java  |   2 +-
 .../appender/RollingFileAppenderBuilder.java       |   2 +-
 .../builders/appender/SyslogAppenderBuilder.java   |  82 +++++++------
 .../builders/filter/LevelMatchFilterBuilder.java   |   2 +-
 .../builders/filter/LevelRangeFilterBuilder.java   |   4 +-
 .../builders/filter/StringMatchFilterBuilder.java  |   2 +-
 .../log4j/builders/layout/HtmlLayoutBuilder.java   |  15 +--
 .../log4j/builders/layout/TTCCLayoutBuilder.java   |   4 +-
 .../config/SyslogAppenderConfigurationTest.java    |  87 +++++++++++++
 .../log4j1-syslog-protocol-default.properties      |   9 ++
 .../log4j1-syslog-protocol-tcp.properties          |  10 ++
 .../test/resources/log4j1-syslog-protocol-tcp.xml  |  37 ++++++
 .../log4j1-syslog-protocol-udp.properties          |  10 ++
 .../test/resources/log4j1-syslog-protocol-udp.xml  |  37 ++++++
 19 files changed, 336 insertions(+), 123 deletions(-)

diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/AbstractBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/AbstractBuilder.java
index 988c1c2..eb21e84 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/AbstractBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/AbstractBuilder.java
@@ -22,7 +22,6 @@ import static org.apache.log4j.xml.XmlConfiguration.VALUE_ATTR;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Properties;
 
@@ -35,6 +34,7 @@ import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.core.filter.CompositeFilter;
 import org.apache.logging.log4j.core.filter.ThresholdFilter;
 import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Strings;
 import org.w3c.dom.Element;
 
 /**
@@ -55,67 +55,24 @@ public abstract class AbstractBuilder {
     private final Properties properties;
 
     public AbstractBuilder() {
-        this.prefix = null;
-        this.properties = new Properties();
+        this(null, new Properties());
     }
 
-    public AbstractBuilder(String prefix, Properties props) {
-        this.prefix = prefix + ".";
+    public AbstractBuilder(final String prefix, final Properties props) {
+        this.prefix = prefix != null ? prefix + "." : null;
         this.properties = (Properties) props.clone();
-        Map<String, String> map = new HashMap<>();
+        final Map<String, String> map = new HashMap<>();
         System.getProperties().forEach((k, v) -> map.put(k.toString(), v.toString()));
         props.forEach((k, v) -> map.put(k.toString(), v.toString()));
         // normalize keys to lower case for case-insensitive access.
-        props.forEach((k, v) -> map.put(toLowerCase(k.toString()), v.toString()));
-        props.entrySet().forEach(e -> this.properties.put(toLowerCase(e.getKey().toString()), e.getValue()));
+        props.forEach((k, v) -> map.put(toBeanKey(k.toString()), v.toString()));
+        props.entrySet().forEach(e -> this.properties.put(toBeanKey(e.getKey().toString()), e.getValue()));
     }
 
-    public String getProperty(String key) {
-        return getProperty(key, null);
-    }
-
-    public String getProperty(String key, String defaultValue) {
-        String fullKey = prefix + key;
-        String value = properties.getProperty(fullKey);
-        value = value != null ? value : properties.getProperty(toLowerCase(fullKey), defaultValue);
-        value = value == null ? defaultValue : substVars(value);
-        return value == null ? defaultValue : value;
-    }
-
-    protected String getNameAttribute(Element element) {
-        return element.getAttribute(NAME_ATTR);
-    }
-
-    protected String getValueAttribute(Element element) {
-        return substVars(element.getAttribute(VALUE_ATTR));
-    }
-
-    public boolean getBooleanProperty(String key) {
-        return Boolean.parseBoolean(getProperty(key, Boolean.FALSE.toString()));
-    }
-
-    public int getIntegerProperty(String key, int defaultValue) {
-        String value = null;
-        try {
-            value = getProperty(key);
-            if (value != null) {
-                return Integer.parseInt(value);
-            }
-        } catch (Exception ex) {
-            LOGGER.warn("Error converting value {} of {} to an integer: {}", value, key, ex.getMessage());
-        }
-        return defaultValue;
-    }
-
-    public Properties getProperties() {
-        return properties;
-    }
-
-
-    protected org.apache.logging.log4j.core.Filter buildFilters(String level, Filter filter) {
+    protected org.apache.logging.log4j.core.Filter buildFilters(final String level, final Filter filter) {
         if (level != null && filter != null) {
-            List<org.apache.logging.log4j.core.Filter> filterList = new ArrayList<>();
-            org.apache.logging.log4j.core.Filter thresholdFilter =
+            final List<org.apache.logging.log4j.core.Filter> filterList = new ArrayList<>();
+            final org.apache.logging.log4j.core.Filter thresholdFilter =
                     ThresholdFilter.createFilter(OptionConverter.convertLevel(level, Level.TRACE),
                             org.apache.logging.log4j.core.Filter.Result.NEUTRAL,
                             org.apache.logging.log4j.core.Filter.Result.DENY);
@@ -144,12 +101,79 @@ public abstract class AbstractBuilder {
         return null;
     }
 
-    protected String substVars(String value) {
+    private String capitalize(final String value) {
+        if (Strings.isEmpty(value) || Character.isUpperCase(value.charAt(0))) {
+            return value;
+        }
+        final char[] chars = value.toCharArray();
+        chars[0] = Character.toUpperCase(chars[0]);
+        return new String(chars);
+    }
+
+    public boolean getBooleanProperty(final String key) {
+        return Boolean.parseBoolean(getProperty(key, Boolean.FALSE.toString()));
+    }
+
+    public int getIntegerProperty(final String key, final int defaultValue) {
+        String value = null;
+        try {
+            value = getProperty(key);
+            if (value != null) {
+                return Integer.parseInt(value);
+            }
+        } catch (final Exception ex) {
+            LOGGER.warn("Error converting value {} of {} to an integer: {}", value, key, ex.getMessage());
+        }
+        return defaultValue;
+    }
+
+    protected String getNameAttribute(final Element element) {
+        return element.getAttribute(NAME_ATTR);
+    }
+
+    protected String getNameAttributeKey(final Element element) {
+        return toBeanKey(element.getAttribute(NAME_ATTR));
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public String getProperty(final String key) {
+        return getProperty(key, null);
+    }
+
+    public String getProperty(final String key, final String defaultValue) {
+        String value = properties.getProperty(prefix + toJavaKey(key));
+        value = value != null ? value : properties.getProperty(prefix + toBeanKey(key), defaultValue);
+        value = value != null ? substVars(value) : defaultValue;
+        return value != null ? value : defaultValue;
+    }
+
+    protected String getValueAttribute(final Element element) {
+        return substVars(element.getAttribute(VALUE_ATTR));
+    }
+
+
+    protected String substVars(final String value) {
         return OptionConverter.substVars(value, properties);
     }
 
-    String toLowerCase(final String value) {
-        return value == null ? null : value.toLowerCase(Locale.ROOT);
+    String toBeanKey(final String value) {
+        return capitalize(value);
+    }
+
+    String toJavaKey(final String value) {
+        return uncapitalize(value);
+    }
+
+    private String uncapitalize(final String value) {
+        if (Strings.isEmpty(value) || Character.isLowerCase(value.charAt(0))) {
+            return value;
+        }
+        final char[] chars = value.toCharArray();
+        chars[0] = Character.toLowerCase(chars[0]);
+        return new String(chars);
     }
 
 }
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/AsyncAppenderBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/AsyncAppenderBuilder.java
index 5707d74..8657156 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/AsyncAppenderBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/AsyncAppenderBuilder.java
@@ -79,7 +79,7 @@ public class AsyncAppenderBuilder extends AbstractBuilder implements AppenderBui
                     }
                     break;
                 case PARAM_TAG: {
-                    switch (getNameAttribute(currentElement)) {
+                    switch (getNameAttributeKey(currentElement)) {
                         case BUFFER_SIZE_PARAM: {
                             String value = getValueAttribute(currentElement);
                             if (value == null) {
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/ConsoleAppenderBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/ConsoleAppenderBuilder.java
index 9757cb9..5f5af5d 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/ConsoleAppenderBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/ConsoleAppenderBuilder.java
@@ -51,9 +51,10 @@ import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
  */
 @Plugin(name = "org.apache.log4j.ConsoleAppender", category = CATEGORY)
 public class ConsoleAppenderBuilder extends AbstractBuilder implements AppenderBuilder {
+
     private static final String SYSTEM_OUT = "System.out";
     private static final String SYSTEM_ERR = "System.err";
-    private static final String TARGET = "target";
+    private static final String TARGET_PARAM = "Target";
 
     private static final Logger LOGGER = StatusLogger.getLogger();
 
@@ -80,11 +81,11 @@ public class ConsoleAppenderBuilder extends AbstractBuilder implements AppenderB
                     filters.get().add(config.parseFilters(currentElement));
                     break;
                 case PARAM_TAG: {
-                    switch (getNameAttribute(currentElement)) {
-                        case TARGET: {
+                    switch (getNameAttributeKey(currentElement)) {
+                        case TARGET_PARAM: {
                             String value = getValueAttribute(currentElement);
                             if (value == null) {
-                                LOGGER.warn("No value supplied for target parameter. Defaulting to System.out.");
+                                LOGGER.warn("No value supplied for target parameter. Defaulting to " + SYSTEM_OUT);
                             } else {
                                 switch (value) {
                                     case SYSTEM_OUT:
@@ -94,8 +95,7 @@ public class ConsoleAppenderBuilder extends AbstractBuilder implements AppenderB
                                         target.set(SYSTEM_ERR);
                                         break;
                                     default:
-                                        LOGGER.warn("Invalid value \"{}\" for target parameter. Using default of System.out",
-                                                value);
+                                        LOGGER.warn("Invalid value \"{}\" for target parameter. Using default of {}", value, SYSTEM_OUT);
                                 }
                             }
                             break;
@@ -134,7 +134,7 @@ public class ConsoleAppenderBuilder extends AbstractBuilder implements AppenderB
         Layout layout = configuration.parseLayout(layoutPrefix, name, props);
         Filter filter = configuration.parseAppenderFilters(props, filterPrefix, name);
         String level = getProperty(THRESHOLD_PARAM);
-        String target = getProperty(TARGET);
+        String target = getProperty(TARGET_PARAM);
         return createAppender(name, layout, filter, level, target, configuration);
     }
 
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/DailyRollingFileAppenderBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/DailyRollingFileAppenderBuilder.java
index 2da188c..0f47576 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/DailyRollingFileAppenderBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/DailyRollingFileAppenderBuilder.java
@@ -86,7 +86,7 @@ public class DailyRollingFileAppenderBuilder extends AbstractBuilder implements
                     filter.set(config.parseFilters(currentElement));
                     break;
                 case PARAM_TAG: {
-                    switch (getNameAttribute(currentElement)) {
+                    switch (getNameAttributeKey(currentElement)) {
                         case FILE_PARAM:
                             fileName.set(getValueAttribute(currentElement));
                             break;
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/FileAppenderBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/FileAppenderBuilder.java
index 0d16f34..7697232 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/FileAppenderBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/FileAppenderBuilder.java
@@ -80,7 +80,7 @@ public class FileAppenderBuilder extends AbstractBuilder implements AppenderBuil
                     filter.set(config.parseFilters(currentElement));
                     break;
                 case PARAM_TAG: {
-                    switch (getNameAttribute(currentElement)) {
+                    switch (getNameAttributeKey(currentElement)) {
                         case FILE_PARAM:
                             fileName.set(getValueAttribute(currentElement));
                             break;
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RewriteAppenderBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RewriteAppenderBuilder.java
index c15cd03..3cfff48 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RewriteAppenderBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RewriteAppenderBuilder.java
@@ -92,7 +92,7 @@ public class RewriteAppenderBuilder extends AbstractBuilder implements AppenderB
                     break;
                 }
                 case PARAM_TAG: {
-                    if (getNameAttribute(currentElement).equalsIgnoreCase(THRESHOLD_PARAM)) {
+                    if (getNameAttributeKey(currentElement).equalsIgnoreCase(THRESHOLD_PARAM)) {
                         String value = getValueAttribute(currentElement);
                         if (value == null) {
                             LOGGER.warn("No value supplied for Threshold parameter, ignoring.");
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RollingFileAppenderBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RollingFileAppenderBuilder.java
index 2ebbbb9..754b4af 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RollingFileAppenderBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/RollingFileAppenderBuilder.java
@@ -89,7 +89,7 @@ public class RollingFileAppenderBuilder extends AbstractBuilder implements Appen
                     filter.set(config.parseFilters(currentElement));
                     break;
                 case PARAM_TAG: {
-                    switch (getNameAttribute(currentElement)) {
+                    switch (getNameAttributeKey(currentElement)) {
                         case FILE_PARAM:
                             fileName.set(getValueAttribute(currentElement));
                             break;
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/SyslogAppenderBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/SyslogAppenderBuilder.java
index 54a8611..31618a4 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/SyslogAppenderBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/appender/SyslogAppenderBuilder.java
@@ -16,19 +16,30 @@
  */
 package org.apache.log4j.builders.appender;
 
+import static org.apache.log4j.builders.BuilderManager.CATEGORY;
+import static org.apache.log4j.config.Log4j1Configuration.THRESHOLD_PARAM;
+import static org.apache.log4j.xml.XmlConfiguration.FILTER_TAG;
+import static org.apache.log4j.xml.XmlConfiguration.LAYOUT_TAG;
+import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
+import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
+
+import java.io.Serializable;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+
 import org.apache.log4j.Appender;
 import org.apache.log4j.Layout;
 import org.apache.log4j.bridge.AppenderWrapper;
 import org.apache.log4j.bridge.LayoutAdapter;
 import org.apache.log4j.bridge.LayoutWrapper;
 import org.apache.log4j.builders.AbstractBuilder;
-import org.apache.log4j.builders.Holder;
 import org.apache.log4j.config.Log4j1Configuration;
 import org.apache.log4j.config.PropertiesConfiguration;
 import org.apache.log4j.spi.Filter;
 import org.apache.log4j.xml.XmlConfiguration;
 import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.core.appender.SyslogAppender;
+import org.apache.logging.log4j.core.appender.SocketAppender;
 import org.apache.logging.log4j.core.layout.SyslogLayout;
 import org.apache.logging.log4j.core.net.Facility;
 import org.apache.logging.log4j.core.net.Protocol;
@@ -37,27 +48,19 @@ import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.Strings;
 import org.w3c.dom.Element;
 
-import java.util.Properties;
-
-import static org.apache.log4j.builders.BuilderManager.CATEGORY;
-import static org.apache.log4j.config.Log4j1Configuration.THRESHOLD_PARAM;
-import static org.apache.log4j.xml.XmlConfiguration.FILTER_TAG;
-import static org.apache.log4j.xml.XmlConfiguration.LAYOUT_TAG;
-import static org.apache.log4j.xml.XmlConfiguration.NAME_ATTR;
-import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
-import static org.apache.log4j.xml.XmlConfiguration.VALUE_ATTR;
-import static org.apache.log4j.xml.XmlConfiguration.forEachElement;
-
 /**
  * Build a File Appender
  */
 @Plugin(name = "org.apache.log4j.net.SyslogAppender", category = CATEGORY)
 public class SyslogAppenderBuilder extends AbstractBuilder implements AppenderBuilder {
 
+    private static final String DEFAULT_HOST = "localhost";
+    private static int DEFAULT_PORT = 514;
+    private static final String DEFAULT_FACILITY = "LOCAL0";
     private static final Logger LOGGER = StatusLogger.getLogger();
     private static final String FACILITY_PARAM = "Facility";
     private static final String SYSLOG_HOST_PARAM = "SyslogHost";
-    private static final int SYSLOG_PORT = 512;
+    private static final String PROTOCOL_PARAM = "Protocol";
 
     public SyslogAppenderBuilder() {
     }
@@ -69,12 +72,13 @@ public class SyslogAppenderBuilder extends AbstractBuilder implements AppenderBu
     @Override
     public Appender parseAppender(Element appenderElement, XmlConfiguration config) {
         String name = getNameAttribute(appenderElement);
-        Holder<Layout> layout = new Holder<>();
-        Holder<Filter> filter = new Holder<>();
-        Holder<String> facility = new Holder<>();
-        Holder<String> level = new Holder<>();
-        Holder<String> host = new Holder<>();
-        forEachElement(appenderElement.getChildNodes(), (currentElement) -> {
+        AtomicReference<Layout> layout = new AtomicReference<>();
+        AtomicReference<Filter> filter = new AtomicReference<>();
+        AtomicReference<String> facility = new AtomicReference<>();
+        AtomicReference<String> level = new AtomicReference<>();
+        AtomicReference<String> host = new AtomicReference<>();
+        AtomicReference<Protocol> protocol = new AtomicReference<>();
+        forEachElement(appenderElement.getChildNodes(), currentElement -> {
             switch (currentElement.getTagName()) {
                 case LAYOUT_TAG:
                     layout.set(config.parseLayout(currentElement));
@@ -83,7 +87,7 @@ public class SyslogAppenderBuilder extends AbstractBuilder implements AppenderBu
                     filter.set(config.parseFilters(currentElement));
                     break;
                 case PARAM_TAG: {
-                    switch (getNameAttribute(currentElement)) {
+                    switch (getNameAttributeKey(currentElement)) {
                         case SYSLOG_HOST_PARAM: {
                             host.set(getValueAttribute(currentElement));
                             break;
@@ -100,13 +104,16 @@ public class SyslogAppenderBuilder extends AbstractBuilder implements AppenderBu
                             }
                             break;
                         }
+                        case PROTOCOL_PARAM:
+                            protocol.set(Protocol.valueOf(getValueAttribute(currentElement)));
+                            break;
                     }
                     break;
                 }
             }
         });
 
-        return createAppender(name, config, layout.get(), facility.get(), filter.get(), host.get(), level.get());
+        return createAppender(name, config, layout.get(), facility.get(), filter.get(), host.get(), level.get(), protocol.get());
     }
 
 
@@ -116,18 +123,19 @@ public class SyslogAppenderBuilder extends AbstractBuilder implements AppenderBu
         Filter filter = configuration.parseAppenderFilters(props, filterPrefix, name);
         Layout layout = configuration.parseLayout(layoutPrefix, name, props);
         String level = getProperty(THRESHOLD_PARAM);
-        String facility = getProperty(FACILITY_PARAM, "LOCAL0");
-        String syslogHost = getProperty(SYSLOG_HOST_PARAM, "localhost:514");
+        String facility = getProperty(FACILITY_PARAM, DEFAULT_FACILITY);
+        String syslogHost = getProperty(SYSLOG_HOST_PARAM, DEFAULT_HOST + ":" + DEFAULT_PORT);
+        String protocol = getProperty(PROTOCOL_PARAM, Protocol.TCP.name());
 
-        return createAppender(name, configuration, layout, facility, filter, syslogHost, level);
+        return createAppender(name, configuration, layout, facility, filter, syslogHost, level, Protocol.valueOf(protocol));
     }
 
     private Appender createAppender(final String name, final Log4j1Configuration configuration, Layout layout,
-            String facility, final Filter filter, final String syslogHost, final String level) {
-        Holder<String> host = new Holder<>();
-        Holder<Integer> port = new Holder<>();
+            String facility, final Filter filter, final String syslogHost, final String level, final Protocol protocol) {
+        AtomicReference<String> host = new AtomicReference<>();
+        AtomicInteger port = new AtomicInteger();
         resolveSyslogHost(syslogHost, host, port);
-        org.apache.logging.log4j.core.Layout appenderLayout;
+        org.apache.logging.log4j.core.Layout<? extends Serializable> appenderLayout;
         if (layout instanceof LayoutWrapper) {
             appenderLayout = ((LayoutWrapper) layout).getLayout();
         } else if (layout != null) {
@@ -140,20 +148,18 @@ public class SyslogAppenderBuilder extends AbstractBuilder implements AppenderBu
         }
 
         org.apache.logging.log4j.core.Filter fileFilter = buildFilters(level, filter);
-        return new AppenderWrapper(SyslogAppender.newBuilder()
+        return new AppenderWrapper(SocketAppender.newBuilder()
                 .setName(name)
                 .setConfiguration(configuration)
                 .setLayout(appenderLayout)
                 .setFilter(fileFilter)
                 .setPort(port.get())
-                .setProtocol(Protocol.TCP)
+                .setProtocol(protocol)
                 .setHost(host.get())
                 .build());
     }
 
-    private void resolveSyslogHost(String syslogHost, Holder<String> host, Holder<Integer> port) {
-        int urlPort = -1;
-
+    private void resolveSyslogHost(String syslogHost, AtomicReference<String> host, AtomicInteger port) {
         //
         //  If not an unbracketed IPv6 address then
         //      parse as a URL
@@ -161,14 +167,14 @@ public class SyslogAppenderBuilder extends AbstractBuilder implements AppenderBu
         final String[] parts = syslogHost != null ? syslogHost.split(":") : Strings.EMPTY_ARRAY;
         if (parts.length == 1) {
             host.set(parts[0]);
-            port.set(SYSLOG_PORT);
+            port.set(DEFAULT_PORT);
         } else if (parts.length == 2) {
             host.set(parts[0]);
             port.set(Integer.parseInt(parts[1]));
         } else {
-            LOGGER.warn("Invalid syslogHost setting: {}. Using default", syslogHost);
-            host.set("localhost");
-            port.set(SYSLOG_PORT);
+            LOGGER.warn("Invalid {} setting: {}. Using default.", SYSLOG_HOST_PARAM, syslogHost);
+            host.set(DEFAULT_HOST);
+            port.set(DEFAULT_PORT);
         }
     }
 }
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelMatchFilterBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelMatchFilterBuilder.java
index 42821c2..218ae46 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelMatchFilterBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelMatchFilterBuilder.java
@@ -59,7 +59,7 @@ public class LevelMatchFilterBuilder extends AbstractBuilder implements FilterBu
         final Holder<Boolean> acceptOnMatch = new BooleanHolder();
         forEachElement(filterElement.getElementsByTagName("param"), (currentElement) -> {
             if (currentElement.getTagName().equals("param")) {
-                switch (getNameAttribute(currentElement)) {
+                switch (getNameAttributeKey(currentElement)) {
                     case LEVEL:
                         level.set(getValueAttribute(currentElement));
                         break;
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilder.java
index 532d06a..34cc475 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/LevelRangeFilterBuilder.java
@@ -27,7 +27,6 @@ import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.core.filter.LevelRangeFilter;
-import org.apache.logging.log4j.status.StatusLogger;
 import org.w3c.dom.Element;
 
 
@@ -42,7 +41,6 @@ import static org.apache.log4j.xml.XmlConfiguration.*;
 @Plugin(name = "org.apache.log4j.varia.LevelRangeFilter", category = CATEGORY)
 public class LevelRangeFilterBuilder extends AbstractBuilder implements FilterBuilder {
 
-    private static final Logger LOGGER = StatusLogger.getLogger();
     private static final String LEVEL_MAX = "LevelMax";
     private static final String LEVEL_MIN = "LevelMin";
     private static final String ACCEPT_ON_MATCH = "AcceptOnMatch";
@@ -61,7 +59,7 @@ public class LevelRangeFilterBuilder extends AbstractBuilder implements FilterBu
         final Holder<Boolean> acceptOnMatch = new BooleanHolder();
         forEachElement(filterElement.getElementsByTagName("param"), (currentElement) -> {
             if (currentElement.getTagName().equals("param")) {
-                switch (getNameAttribute(currentElement)) {
+                switch (getNameAttributeKey(currentElement)) {
                     case LEVEL_MAX:
                         levelMax.set(getValueAttribute(currentElement));
                         break;
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/StringMatchFilterBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/StringMatchFilterBuilder.java
index bd28b78..2a16cf0 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/StringMatchFilterBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/filter/StringMatchFilterBuilder.java
@@ -50,7 +50,7 @@ public class StringMatchFilterBuilder extends AbstractBuilder implements FilterB
         final Holder<String> text = new Holder<>();
         forEachElement(filterElement.getElementsByTagName("param"), (currentElement) -> {
             if (currentElement.getTagName().equals("param")) {
-                switch (getNameAttribute(currentElement)) {
+                switch (getNameAttributeKey(currentElement)) {
                     case STRING_TO_MATCH:
                         text.set(getValueAttribute(currentElement));
                         break;
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/HtmlLayoutBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/HtmlLayoutBuilder.java
index 423350e..196225d 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/HtmlLayoutBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/HtmlLayoutBuilder.java
@@ -26,7 +26,6 @@ import org.apache.log4j.xml.XmlConfiguration;
 import org.apache.logging.log4j.Logger;
 import org.apache.logging.log4j.plugins.Plugin;
 import org.apache.logging.log4j.core.layout.HtmlLayout;
-import org.apache.logging.log4j.status.StatusLogger;
 import org.w3c.dom.Element;
 
 import java.util.Properties;
@@ -40,10 +39,8 @@ import static org.apache.log4j.xml.XmlConfiguration.*;
 @Plugin(name = "org.apache.log4j.HTMLLayout", category = CATEGORY)
 public class HtmlLayoutBuilder extends AbstractBuilder implements LayoutBuilder {
 
-    private static final Logger LOGGER = StatusLogger.getLogger();
-
-    private static final String TITLE = "Title";
-    private static final String LOCATION_INFO = "LocationInfo";
+    private static final String TITLE_PARAM = "Title";
+    private static final String LOCATION_INFO_PARAM = "LocationInfo";
 
     public HtmlLayoutBuilder() {
     }
@@ -59,9 +56,9 @@ public class HtmlLayoutBuilder extends AbstractBuilder implements LayoutBuilder
         final Holder<Boolean> locationInfo = new BooleanHolder();
         forEachElement(layoutElement.getElementsByTagName("param"), (currentElement) -> {
             if (currentElement.getTagName().equals(PARAM_TAG)) {
-                if (TITLE.equalsIgnoreCase(currentElement.getAttribute("name"))) {
+                if (TITLE_PARAM.equalsIgnoreCase(currentElement.getAttribute("name"))) {
                     title.set(currentElement.getAttribute("value"));
-                } else if (LOCATION_INFO.equalsIgnoreCase(currentElement.getAttribute("name"))) {
+                } else if (LOCATION_INFO_PARAM.equalsIgnoreCase(currentElement.getAttribute("name"))) {
                     locationInfo.set(Boolean.parseBoolean(currentElement.getAttribute("value")));
                 }
             }
@@ -71,8 +68,8 @@ public class HtmlLayoutBuilder extends AbstractBuilder implements LayoutBuilder
 
     @Override
     public Layout parseLayout(PropertiesConfiguration config) {
-        String title = getProperty(TITLE);
-        boolean locationInfo = getBooleanProperty(LOCATION_INFO);
+        String title = getProperty(TITLE_PARAM);
+        boolean locationInfo = getBooleanProperty(LOCATION_INFO_PARAM);
         return createLayout(title, locationInfo);
     }
 
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/TTCCLayoutBuilder.java b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/TTCCLayoutBuilder.java
index d93592b..ce54fd8 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/TTCCLayoutBuilder.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/builders/layout/TTCCLayoutBuilder.java
@@ -41,8 +41,6 @@ import static org.apache.log4j.xml.XmlConfiguration.*;
 @Plugin(name = "org.apache.log4j.TTCCLayout", category = CATEGORY)
 public class TTCCLayoutBuilder extends AbstractBuilder implements LayoutBuilder {
 
-    private static final Logger LOGGER = StatusLogger.getLogger();
-
     private static final String THREAD_PRINTING_PARAM = "ThreadPrinting";
     private static final String CATEGORY_PREFIXING_PARAM = "CategoryPrefixing";
     private static final String CONTEXT_PRINTING_PARAM = "ContextPrinting";
@@ -65,7 +63,7 @@ public class TTCCLayoutBuilder extends AbstractBuilder implements LayoutBuilder
         final Holder<String> timezone = new Holder<>();
         forEachElement(layoutElement.getElementsByTagName("param"), (currentElement) -> {
             if (currentElement.getTagName().equals(PARAM_TAG)) {
-                switch (getNameAttribute(currentElement)) {
+                switch (getNameAttributeKey(currentElement)) {
                     case THREAD_PRINTING_PARAM:
                         threadPrinting.set(Boolean.parseBoolean(getValueAttribute(currentElement)));
                         break;
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/config/SyslogAppenderConfigurationTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/config/SyslogAppenderConfigurationTest.java
new file mode 100644
index 0000000..fd5e077
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/SyslogAppenderConfigurationTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.log4j.config;
+
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.io.IOException;
+import java.util.Map;
+
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.appender.SocketAppender;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.net.AbstractSocketManager;
+import org.apache.logging.log4j.core.net.Protocol;
+import org.junit.Test;
+
+/**
+ * Class Description goes here.
+ */
+public class SyslogAppenderConfigurationTest {
+
+    private void checkProtocol(final Protocol expected, final Configuration configuration) {
+        final Map<String, Appender> appenders = configuration.getAppenders();
+        assertNotNull(appenders);
+        final String appenderName = "syslog";
+        final Appender appender = appenders.get(appenderName);
+        assertNotNull(appender, "Missing appender " + appenderName);
+        final SocketAppender socketAppender = (SocketAppender) appender;
+        @SuppressWarnings("resource")
+        final AbstractSocketManager manager = socketAppender.getManager();
+        final String prefix = expected + ":";
+        assertTrue(manager.getName().startsWith(prefix), () -> String.format("'%s' does not start with '%s'", manager.getName(), prefix));
+    }
+
+    private void checkProtocolPropertiesConfig(final Protocol expected, final String xmlPath) throws IOException {
+        checkProtocol(expected, TestConfigurator.configure(xmlPath).getConfiguration());
+    }
+
+    private void checkProtocolXmlConfig(final Protocol expected, final String xmlPath) throws IOException {
+        checkProtocol(expected, TestConfigurator.configure(xmlPath).getConfiguration());
+    }
+
+    @Test
+    public void testPropertiesProtocolDefault() throws Exception {
+        checkProtocolPropertiesConfig(Protocol.TCP, "target/test-classes/log4j1-syslog-protocol-default.properties");
+    }
+
+    @Test
+    public void testPropertiesProtocolTcp() throws Exception {
+        checkProtocolPropertiesConfig(Protocol.TCP, "target/test-classes/log4j1-syslog-protocol-tcp.properties");
+    }
+
+    @Test
+    public void testPropertiesProtocolUdp() throws Exception {
+        checkProtocolPropertiesConfig(Protocol.UDP, "target/test-classes/log4j1-syslog-protocol-udp.properties");
+    }
+
+    @Test
+    public void testXmlProtocolDefault() throws Exception {
+        checkProtocolXmlConfig(Protocol.TCP, "target/test-classes/log4j1-syslog.xml");
+    }
+
+    @Test
+    public void testXmlProtocolTcp() throws Exception {
+        checkProtocolXmlConfig(Protocol.TCP, "target/test-classes/log4j1-syslog-protocol-tcp.xml");
+    }
+
+    @Test
+    public void testXmlProtocolUdp() throws Exception {
+        checkProtocolXmlConfig(Protocol.UDP, "target/test-classes/log4j1-syslog-protocol-udp.xml");
+    }
+}
diff --git a/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-default.properties b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-default.properties
new file mode 100644
index 0000000..5501074
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-default.properties
@@ -0,0 +1,9 @@
+log4j.rootLogger=DEBUG,syslog
+log4j.appender.syslog=org.apache.log4j.net.SyslogAppender
+log4j.appender.syslog.Threshold=DEBUG
+log4j.appender.syslog.syslogHost=localhost
+log4j.appender.syslog.port=9999
+log4j.appender.syslog.header=true
+log4j.appender.syslog.Facility=LOCAL3
+log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
+log4j.appender.syslog.layout.conversionPattern=Main[%pid] :%t: %c %-4p - %m\n
diff --git a/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-tcp.properties b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-tcp.properties
new file mode 100644
index 0000000..2b6b704
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-tcp.properties
@@ -0,0 +1,10 @@
+log4j.rootLogger=DEBUG,syslog
+log4j.appender.syslog=org.apache.log4j.net.SyslogAppender
+log4j.appender.syslog.Threshold=DEBUG
+log4j.appender.syslog.syslogHost=localhost
+log4j.appender.syslog.port=9999
+log4j.appender.syslog.protocol=TCP
+log4j.appender.syslog.header=true
+log4j.appender.syslog.Facility=LOCAL3
+log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
+log4j.appender.syslog.layout.conversionPattern=Main[%pid] :%t: %c %-4p - %m\n
diff --git a/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-tcp.xml b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-tcp.xml
new file mode 100644
index 0000000..47c3768
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-tcp.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+  <appender name="syslog" class="org.apache.log4j.net.SyslogAppender">
+    <param name="SyslogHost" value="localhost:9999"/>
+    <param name="Facility" value="USER"/>
+    <param name="FacilityPrinting" value="true"/>
+    <param name="Threshold" value="DEBUG"/>
+    <param name="protocol" value="TCP"/>
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
+    </layout>
+  </appender>
+
+  <root>
+    <priority value ="trace" />
+    <appender-ref ref="syslog" />
+  </root>
+
+</log4j:configuration>
diff --git a/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-udp.properties b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-udp.properties
new file mode 100644
index 0000000..1735ade
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-udp.properties
@@ -0,0 +1,10 @@
+log4j.rootLogger=DEBUG,syslog
+log4j.appender.syslog=org.apache.log4j.net.SyslogAppender
+log4j.appender.syslog.Threshold=DEBUG
+log4j.appender.syslog.syslogHost=localhost
+log4j.appender.syslog.port=9999
+log4j.appender.syslog.protocol=UDP
+log4j.appender.syslog.header=true
+log4j.appender.syslog.Facility=LOCAL3
+log4j.appender.syslog.layout=org.apache.log4j.PatternLayout
+log4j.appender.syslog.layout.conversionPattern=Main[%pid] :%t: %c %-4p - %m\n
diff --git a/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-udp.xml b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-udp.xml
new file mode 100644
index 0000000..279ec94
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/log4j1-syslog-protocol-udp.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+-->
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+  <appender name="syslog" class="org.apache.log4j.net.SyslogAppender">
+    <param name="SyslogHost" value="localhost:9999"/>
+    <param name="Facility" value="USER"/>
+    <param name="FacilityPrinting" value="true"/>
+    <param name="Threshold" value="DEBUG"/>
+    <param name="protocol" value="UDP"/>
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
+    </layout>
+  </appender>
+
+  <root>
+    <priority value ="trace" />
+    <appender-ref ref="syslog" />
+  </root>
+
+</log4j:configuration>

[logging-log4j2] 02/02: Log4j 1.2 bridge should allow property and XML attributes to start with either an upper-case or lower-case letter.

Posted by gg...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ggregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 26716d6df9bb1a9cc2f5128c4d452c7cc5c5b93c
Author: ppkarwasz <un...@github>
AuthorDate: Thu Jan 20 08:23:47 2022 -0500

    Log4j 1.2 bridge should allow property and XML attributes to start with either an upper-case or lower-case letter.
---
 .../config/AbstractLog4j1ConfigurationTest.java    | 58 ++++++++++++++++++++++
 .../config/Log4j1ConfigurationFactoryTest.java     | 54 +++++++++++---------
 .../log4j/config/PropertiesConfigurationTest.java  | 25 +++++++++-
 .../apache/log4j/config/XmlConfigurationTest.java  | 45 ++++++++++++-----
 .../config-1.2/log4j-capitalization.properties     | 27 ++++++++++
 .../resources/config-1.2/log4j-capitalization.xml  | 28 +++++++++++
 6 files changed, 200 insertions(+), 37 deletions(-)

diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
new file mode 100644
index 0000000..69d2c09
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/AbstractLog4j1ConfigurationTest.java
@@ -0,0 +1,58 @@
+/*
+ * 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.log4j.config;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+import java.net.URISyntaxException;
+
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.appender.ConsoleAppender;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.layout.PatternLayout;
+
+public abstract class AbstractLog4j1ConfigurationTest {
+
+    abstract Configuration getConfiguration(String configResourcePrefix) throws URISyntaxException, IOException;
+
+    public void testConsoleCapitalization() throws Exception {
+        final Configuration config = getConfiguration("config-1.2/log4j-capitalization");
+        final Appender capitalized = config.getAppender("ConsoleCapitalized");
+        assertNotNull(capitalized);
+        assertEquals(capitalized.getClass(), ConsoleAppender.class);
+        final Appender javaStyle = config.getAppender("ConsoleJavaStyle");
+        assertNotNull(javaStyle);
+        assertEquals(javaStyle.getClass(), ConsoleAppender.class);
+        testConsoleAppender((ConsoleAppender) capitalized, (ConsoleAppender) javaStyle);
+    }
+
+    private void testConsoleAppender(ConsoleAppender expected, ConsoleAppender actual) {
+        assertEquals("immediateFlush", expected.getImmediateFlush(), actual.getImmediateFlush());
+        assertEquals("target", expected.getTarget(), actual.getTarget());
+        assertEquals("layoutClass", expected.getLayout().getClass(), actual.getLayout().getClass());
+        if (expected.getLayout() instanceof PatternLayout) {
+            patternLayoutEquals((PatternLayout) expected.getLayout(), (PatternLayout) actual.getLayout());
+        }
+    }
+
+    private void patternLayoutEquals(PatternLayout expected, PatternLayout actual) {
+        assertEquals(expected.getCharset(), actual.getCharset());
+        assertEquals(expected.getConversionPattern(), actual.getConversionPattern());
+    }
+}
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/config/Log4j1ConfigurationFactoryTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/config/Log4j1ConfigurationFactoryTest.java
index 5ebf0ec..f206790 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/config/Log4j1ConfigurationFactoryTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/Log4j1ConfigurationFactoryTest.java
@@ -20,7 +20,6 @@ import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-
 import java.io.File;
 import java.net.URISyntaxException;
 import java.net.URL;
@@ -28,7 +27,6 @@ import java.nio.file.FileSystemException;
 import java.nio.file.Files;
 import java.nio.file.Path;
 import java.util.concurrent.TimeUnit;
-
 import org.apache.log4j.layout.Log4j1XmlLayout;
 import org.apache.logging.log4j.Level;
 import org.apache.logging.log4j.core.Appender;
@@ -50,7 +48,18 @@ import org.apache.logging.log4j.core.layout.HtmlLayout;
 import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.junit.Test;
 
-public class Log4j1ConfigurationFactoryTest {
+public class Log4j1ConfigurationFactoryTest extends AbstractLog4j1ConfigurationTest {
+
+    private static final String SUFFIX = ".properties";
+
+    @Override
+    protected Configuration getConfiguration(final String configResource) throws URISyntaxException {
+        final URL configLocation = ClassLoader.getSystemResource(configResource + SUFFIX);
+        assertNotNull(configResource, configLocation);
+        final Configuration configuration = new Log4j1ConfigurationFactory().getConfiguration(null, "test", configLocation.toURI());
+        assertNotNull(configuration);
+        return configuration;
+    }
 
     private Layout<?> testConsole(final String configResource) throws Exception {
         final Configuration configuration = getConfiguration(configResource);
@@ -81,61 +90,53 @@ public class Log4j1ConfigurationFactoryTest {
         return appender.getLayout();
     }
 
-    private Configuration getConfiguration(final String configResource) throws URISyntaxException {
-        final URL configLocation = ClassLoader.getSystemResource(configResource);
-        assertNotNull(configResource, configLocation);
-        final Configuration configuration = new Log4j1ConfigurationFactory().getConfiguration(null, "test", configLocation.toURI());
-        assertNotNull(configuration);
-        return configuration;
-    }
-
     @Test
     public void testConsoleEnhancedPatternLayout() throws Exception {
-        final PatternLayout layout = (PatternLayout) testConsole("config-1.2/log4j-console-EnhancedPatternLayout.properties");
+       final PatternLayout layout = (PatternLayout) testConsole("config-1.2/log4j-console-EnhancedPatternLayout");
         assertEquals("%d{ISO8601} [%t][%c] %-5p %properties %ndc: %m%n", layout.getConversionPattern());
     }
 
     @Test
     public void testConsoleHtmlLayout() throws Exception {
-        final HtmlLayout layout = (HtmlLayout) testConsole("config-1.2/log4j-console-HtmlLayout.properties");
+       final HtmlLayout layout = (HtmlLayout) testConsole("config-1.2/log4j-console-HtmlLayout");
         assertEquals("Headline", layout.getTitle());
         assertTrue(layout.isLocationInfo());
     }
 
     @Test
     public void testConsolePatternLayout() throws Exception {
-        final PatternLayout layout = (PatternLayout) testConsole("config-1.2/log4j-console-PatternLayout.properties");
+       final PatternLayout layout = (PatternLayout) testConsole("config-1.2/log4j-console-PatternLayout");
         assertEquals("%d{ISO8601} [%t][%c] %-5p: %m%n", layout.getConversionPattern());
     }
 
     @Test
     public void testConsoleSimpleLayout() throws Exception {
-        final PatternLayout layout = (PatternLayout) testConsole("config-1.2/log4j-console-SimpleLayout.properties");
+       final PatternLayout layout = (PatternLayout) testConsole("config-1.2/log4j-console-SimpleLayout");
         assertEquals("%level - %m%n", layout.getConversionPattern());
     }
 
     @Test
     public void testConsoleTtccLayout() throws Exception {
-        final PatternLayout layout = (PatternLayout) testConsole("config-1.2/log4j-console-TTCCLayout.properties");
+       final PatternLayout layout = (PatternLayout) testConsole("config-1.2/log4j-console-TTCCLayout");
         assertEquals("%r [%t] %p %notEmpty{%ndc }- %m%n", layout.getConversionPattern());
     }
 
     @Test
     public void testConsoleXmlLayout() throws Exception {
-        final Log4j1XmlLayout layout = (Log4j1XmlLayout) testConsole("config-1.2/log4j-console-XmlLayout.properties");
+       final Log4j1XmlLayout layout = (Log4j1XmlLayout) testConsole("config-1.2/log4j-console-XmlLayout");
         assertTrue(layout.isLocationInfo());
         assertFalse(layout.isProperties());
     }
 
     @Test
     public void testFileSimpleLayout() throws Exception {
-        final PatternLayout layout = (PatternLayout) testFile("config-1.2/log4j-file-SimpleLayout.properties");
+       final PatternLayout layout = (PatternLayout) testFile("config-1.2/log4j-file-SimpleLayout");
         assertEquals("%level - %m%n", layout.getConversionPattern());
     }
 
     @Test
     public void testNullAppender() throws Exception {
-        final Configuration configuration = getConfiguration("config-1.2/log4j-NullAppender.properties");
+       final Configuration configuration = getConfiguration("config-1.2/log4j-NullAppender");
         final Appender appender = configuration.getAppender("NullAppender");
         assertNotNull(appender);
         assertEquals("NullAppender", appender.getName());
@@ -144,17 +145,17 @@ public class Log4j1ConfigurationFactoryTest {
 
     @Test
     public void testRollingFileAppender() throws Exception {
-        testRollingFileAppender("config-1.2/log4j-RollingFileAppender.properties", "RFA", "target/hadoop.log.%i");
+       testRollingFileAppender("config-1.2/log4j-RollingFileAppender", "RFA", "target/hadoop.log.%i");
     }
 
     @Test
     public void testDailyRollingFileAppender() throws Exception {
-        testDailyRollingFileAppender("config-1.2/log4j-DailyRollingFileAppender.properties", "DRFA", "target/hadoop.log%d{.yyyy-MM-dd}");
+       testDailyRollingFileAppender("config-1.2/log4j-DailyRollingFileAppender", "DRFA", "target/hadoop.log%d{.yyyy-MM-dd}");
     }
 
     @Test
     public void testRollingFileAppenderWithProperties() throws Exception {
-        testRollingFileAppender("config-1.2/log4j-RollingFileAppender-with-props.properties", "RFA", "target/hadoop.log.%i");
+       testRollingFileAppender("config-1.2/log4j-RollingFileAppender-with-props", "RFA", "target/hadoop.log.%i");
     }
 
     @Test
@@ -163,7 +164,7 @@ public class Log4j1ConfigurationFactoryTest {
         final Path tempFilePath = new File(tempFileName).toPath();
         Files.deleteIfExists(tempFilePath);
         try {
-            final Configuration configuration = getConfiguration("config-1.2/log4j-system-properties-1.properties");
+            final Configuration configuration = getConfiguration("config-1.2/log4j-system-properties-1");
             final RollingFileAppender appender = configuration.getAppender("RFA");
             appender.stop(10, TimeUnit.SECONDS);
             // System.out.println("expected: " + tempFileName + " Actual: " + appender.getFileName());
@@ -179,7 +180,7 @@ public class Log4j1ConfigurationFactoryTest {
 
     @Test
     public void testSystemProperties2() throws Exception {
-        final Configuration configuration = getConfiguration("config-1.2/log4j-system-properties-2.properties");
+       final Configuration configuration = getConfiguration("config-1.2/log4j-system-properties-2");
         final RollingFileAppender appender = configuration.getAppender("RFA");
         assertEquals("${java.io.tmpdir}/hadoop.log", appender.getFileName());
         appender.stop(10, TimeUnit.SECONDS);
@@ -243,4 +244,9 @@ public class Log4j1ConfigurationFactoryTest {
         configuration.stop();
     }
 
+    @Override
+    @Test
+    public void testConsoleCapitalization() throws Exception {
+        super.testConsoleCapitalization();
+    }
 }
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/config/PropertiesConfigurationTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/config/PropertiesConfigurationTest.java
index bc1fb51..bd3a291 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/config/PropertiesConfigurationTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/PropertiesConfigurationTest.java
@@ -21,6 +21,9 @@ import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
 import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
 import java.util.List;
 import java.util.Map;
 
@@ -36,6 +39,7 @@ import org.apache.logging.log4j.core.Appender;
 import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.appender.FileAppender;
 import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.ConfigurationSource;
 import org.apache.logging.log4j.core.filter.CompositeFilter;
 import org.apache.logging.log4j.core.filter.Filterable;
 import org.apache.logging.log4j.core.filter.LevelRangeFilter;
@@ -44,9 +48,22 @@ import org.junit.Test;
 /**
  * Test configuration from Properties.
  */
-public class PropertiesConfigurationTest {
+public class PropertiesConfigurationTest extends AbstractLog4j1ConfigurationTest {
 
     private static final String TEST_KEY = "log4j.test.tmpdir";
+    private static final String SUFFIX = ".properties";
+
+    @Override
+    Configuration getConfiguration(String configResourcePrefix) throws URISyntaxException, IOException {
+        final String configResource = configResourcePrefix + SUFFIX;
+        final InputStream inputStream = ClassLoader.getSystemResourceAsStream(configResource);
+        final ConfigurationSource source = new ConfigurationSource(inputStream);
+        final LoggerContext context = LoggerContext.getContext(false);
+        final Configuration configuration = new PropertiesConfigurationFactory().getConfiguration(context, source);
+        assertNotNull("No configuration created", configuration);
+        configuration.initialize();
+        return configuration;
+    }
 
     @Test
     public void testConfigureNullPointerException() throws Exception {
@@ -165,4 +182,10 @@ public class PropertiesConfigurationTest {
         }
     }
 
+    @Override
+    @Test
+    public void testConsoleCapitalization() throws Exception {
+        super.testConsoleCapitalization();
+    }
+
 }
\ No newline at end of file
diff --git a/log4j-1.2-api/src/test/java/org/apache/log4j/config/XmlConfigurationTest.java b/log4j-1.2-api/src/test/java/org/apache/log4j/config/XmlConfigurationTest.java
index c4cc360..8c912fa 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/config/XmlConfigurationTest.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/XmlConfigurationTest.java
@@ -16,6 +16,17 @@
  */
 package org.apache.log4j.config;
 
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.util.List;
+import java.util.Map;
+
 import org.apache.log4j.ListAppender;
 import org.apache.log4j.LogManager;
 import org.apache.log4j.Logger;
@@ -23,27 +34,31 @@ import org.apache.log4j.bridge.AppenderAdapter;
 import org.apache.log4j.spi.LoggingEvent;
 import org.apache.log4j.xml.XmlConfigurationFactory;
 import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.ConfigurationSource;
 import org.apache.logging.log4j.core.config.Configurator;
-import org.apache.logging.log4j.core.LoggerContext;
 import org.apache.logging.log4j.spi.LoggerContextFactory;
 import org.junit.Test;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.InputStream;
-import java.util.List;
-import java.util.Map;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-
 /**
  * Test configuration from XML.
  */
-public class XmlConfigurationTest {
+public class XmlConfigurationTest extends AbstractLog4j1ConfigurationTest {
+
+    private static final String SUFFIX = ".xml";
+
+    @Override
+    Configuration getConfiguration(String configResourcePrefix) throws URISyntaxException, IOException {
+        final String configResource = configResourcePrefix + SUFFIX;
+        final InputStream inputStream = ClassLoader.getSystemResourceAsStream(configResource);
+        final ConfigurationSource source = new ConfigurationSource(inputStream);
+        final LoggerContext context = LoggerContext.getContext(false);
+        final Configuration configuration = new XmlConfigurationFactory().getConfiguration(context, source);
+        assertNotNull("No configuration created", configuration);
+        configuration.initialize();
+        return configuration;
+    }
 
     @Test
     public void testXML() throws Exception {
@@ -94,4 +109,10 @@ public class XmlConfigurationTest {
         return context;
     }
 
+    @Override
+    @Test
+    public void testConsoleCapitalization() throws Exception {
+        super.testConsoleCapitalization();
+    }
+
 }
diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-capitalization.properties b/log4j-1.2-api/src/test/resources/config-1.2/log4j-capitalization.properties
new file mode 100644
index 0000000..101d062
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-capitalization.properties
@@ -0,0 +1,27 @@
+###############################################################################
+#
+# Log4J 1.2 Configuration.
+#
+
+log4j.rootLogger=TRACE, ConsoleCapitalized, ConsoleJavaStyle
+
+##############################################################################
+#
+# The Console log
+#
+
+log4j.appender.ConsoleCapitalized=org.apache.log4j.ConsoleAppender
+log4j.appender.ConsoleCapitalized.Encoding=ISO-8859-1
+log4j.appender.ConsoleCapitalized.Follow=true
+log4j.appender.ConsoleCapitalized.ImmediateFlush=false
+log4j.appender.ConsoleCapitalized.Target=System.err
+log4j.appender.ConsoleCapitalized.layout=org.apache.log4j.PatternLayout
+log4j.appender.ConsoleCapitalized.layout.ConversionPattern=%d{ISO8601} [%t][%c] %-5p: %m%n
+
+log4j.appender.ConsoleJavaStyle=org.apache.log4j.ConsoleAppender
+log4j.appender.ConsoleJavaStyle.Encoding=ISO-8859-1
+log4j.appender.ConsoleJavaStyle.Follow=true
+log4j.appender.ConsoleJavaStyle.ImmediateFlush=false
+log4j.appender.ConsoleJavaStyle.Target=System.err
+log4j.appender.ConsoleJavaStyle.layout=org.apache.log4j.PatternLayout
+log4j.appender.ConsoleJavaStyle.layout.ConversionPattern=%d{ISO8601} [%t][%c] %-5p: %m%n
diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-capitalization.xml b/log4j-1.2-api/src/test/resources/config-1.2/log4j-capitalization.xml
new file mode 100644
index 0000000..0770db0
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-capitalization.xml
@@ -0,0 +1,28 @@
+<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
+  <appender name="ConsoleCapitalized" class="org.apache.log4j.ConsoleAppender">
+    <param name="Encoding" value="ISO-8859-1" />
+    <param name="Follow" value="true" />
+    <param name="ImmediateFlush" value="false" />
+    <param name="Target" value="System.err" />
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="ConversionPattern" value="%d{ISO8601} [%t][%c] %-5p: %m%n" />
+    </layout>
+  </appender>
+
+  <appender name="ConsoleJavaStyle" class="org.apache.log4j.ConsoleAppender">
+    <param name="encoding" value="ISO-8859-1" />
+    <param name="follow" value="true" />
+    <param name="immediateFlush" value="false" />
+    <param name="target" value="System.err" />
+    <layout class="org.apache.log4j.PatternLayout">
+      <param name="conversionPattern" value="%d{ISO8601} [%t][%c] %-5p: %m%n" />
+    </layout>
+  </appender>
+
+  <root>
+    <priority value="trace" />
+    <appender-ref ref="ConsoleCapitalized" />
+    <appender-ref ref="ConsoleJavaStyle" />
+  </root>
+</log4j:configuration>
\ No newline at end of file