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 2016/09/22 03:38:31 UTC

logging-log4j2 git commit: [LOG4J2-1523] Log4j 1 appenders. Classic RollingFileAppender.

Repository: logging-log4j2
Updated Branches:
  refs/heads/master a2af6ed49 -> 906abebb3


[LOG4J2-1523] Log4j 1 appenders. Classic RollingFileAppender.

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

Branch: refs/heads/master
Commit: 906abebb3814cc82b02d12daa7836656a9d6c71e
Parents: a2af6ed
Author: Gary Gregory <gg...@apache.org>
Authored: Wed Sep 21 20:38:29 2016 -0700
Committer: Gary Gregory <gg...@apache.org>
Committed: Wed Sep 21 20:38:29 2016 -0700

----------------------------------------------------------------------
 .../log4j/config/Log4j1ConfigurationParser.java | 531 ++++++++++---------
 .../config/Log4j1ConfigurationFactoryTest.java  |  34 +-
 ...4j-RollingFileAppender-with-props.properties |  27 +
 .../log4j-RollingFileAppender.properties        |  22 +
 4 files changed, 360 insertions(+), 254 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/906abebb/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationParser.java
----------------------------------------------------------------------
diff --git a/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationParser.java b/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationParser.java
index adc512c..0d5be53 100644
--- a/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationParser.java
+++ b/log4j-1.2-api/src/main/java/org/apache/log4j/config/Log4j1ConfigurationParser.java
@@ -42,281 +42,306 @@ import org.apache.logging.log4j.status.StatusLogger;
  */
 public class Log4j1ConfigurationParser {
 
-    private final Properties properties = new Properties();
-    private final ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
+	private final Properties properties = new Properties();
+	private final ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory
+			.newConfigurationBuilder();
 
-    /**
-     * Parse a Log4j 1.2 properties configuration file into a ConfigurationBuilder.
-     *
-     * @param input  InputStream to read from, will not be closed.
-     * @return  the populated ConfigurationBuilder, never {@literal null}
-     * @throws IOException  if unable to read the input
-     * @throws ConfigurationException  if the input does not contain a valid configuration
-     */
-    public ConfigurationBuilder<BuiltConfiguration> buildConfigurationBuilder(final InputStream input) throws IOException {
-        properties.load(input);
-        final String rootCategoryValue = getLog4jValue("rootCategory");
-        final String rootLoggerValue = getLog4jValue("rootLogger");
-        if (rootCategoryValue == null && rootLoggerValue == null) {
-            // This is not a Log4j 1 properties configuration file.
-            throw new ConfigurationException("Input does not contain a valid Log4j 1.x properties configuration");
-        }
-        builder.setConfigurationName("Log4j1");
-        // DEBUG
-        final String debugValue = getLog4jValue("debug");
-        if (Boolean.valueOf(debugValue)) {
-            builder.setStatusLevel(Level.DEBUG);
-        }
-        // Root
-        final String[] sortedAppenderNamesC = buildRootLogger(getLog4jValue("rootCategory"));
-        final String[] sortedAppenderNamesL = buildRootLogger(getLog4jValue("rootLogger"));
-        final String[] sortedAppenderNames = sortedAppenderNamesL.length > 0 ? sortedAppenderNamesL
-                : sortedAppenderNamesC;
-        // Appenders
-        final Map<String, String> classNameToProperty = buildClassToPropertyPrefixMap(sortedAppenderNames);
-        for (final Map.Entry<String, String> entry : classNameToProperty.entrySet()) {
-            final String appenderName = entry.getKey();
-            final String appenderClass = entry.getValue();
-            buildAppender(appenderName, appenderClass);
-        }
-        // Loggers
-        buildLoggers("log4j.category.");
-        buildLoggers("log4j.logger.");
-        return builder;
-    }
+	/**
+	 * Parse a Log4j 1.2 properties configuration file into a
+	 * ConfigurationBuilder.
+	 *
+	 * @param input
+	 *            InputStream to read from, will not be closed.
+	 * @return the populated ConfigurationBuilder, never {@literal null}
+	 * @throws IOException
+	 *             if unable to read the input
+	 * @throws ConfigurationException
+	 *             if the input does not contain a valid configuration
+	 */
+	public ConfigurationBuilder<BuiltConfiguration> buildConfigurationBuilder(final InputStream input)
+			throws IOException {
+		properties.load(input);
+		final String rootCategoryValue = getLog4jValue("rootCategory");
+		final String rootLoggerValue = getLog4jValue("rootLogger");
+		if (rootCategoryValue == null && rootLoggerValue == null) {
+			// This is not a Log4j 1 properties configuration file.
+			throw new ConfigurationException("Input does not contain a valid Log4j 1.x properties configuration");
+		}
+		builder.setConfigurationName("Log4j1");
+		// DEBUG
+		final String debugValue = getLog4jValue("debug");
+		if (Boolean.valueOf(debugValue)) {
+			builder.setStatusLevel(Level.DEBUG);
+		}
+		// Root
+		final String[] sortedAppenderNamesC = buildRootLogger(getLog4jValue("rootCategory"));
+		final String[] sortedAppenderNamesL = buildRootLogger(getLog4jValue("rootLogger"));
+		final String[] sortedAppenderNames = sortedAppenderNamesL.length > 0 ? sortedAppenderNamesL
+				: sortedAppenderNamesC;
+		// Appenders
+		final Map<String, String> classNameToProperty = buildClassToPropertyPrefixMap(sortedAppenderNames);
+		for (final Map.Entry<String, String> entry : classNameToProperty.entrySet()) {
+			final String appenderName = entry.getKey();
+			final String appenderClass = entry.getValue();
+			buildAppender(appenderName, appenderClass);
+		}
+		// Loggers
+		buildLoggers("log4j.category.");
+		buildLoggers("log4j.logger.");
+		return builder;
+	}
 
-    private Map<String, String> buildClassToPropertyPrefixMap(final String[] sortedAppenderNames) {
-        final String prefix = "log4j.appender.";
-        final int preLength = prefix.length();
-        final Map<String, String> map = new HashMap<>(sortedAppenderNames.length);
-        for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
-            final Object keyObj = entry.getKey();
-            if (keyObj != null) {
-                final String key = keyObj.toString();
-                if (key.startsWith(prefix)) {
-                    if (key.indexOf('.', preLength) < 0) {
-                        final String name = key.substring(preLength);
-                        if (Arrays.binarySearch(sortedAppenderNames, name) >= 0) {
-                            final Object value = entry.getValue();
-                            if (value != null) {
-                                map.put(name, value.toString());
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return map;
-    }
+	private Map<String, String> buildClassToPropertyPrefixMap(final String[] sortedAppenderNames) {
+		final String prefix = "log4j.appender.";
+		final int preLength = prefix.length();
+		final Map<String, String> map = new HashMap<>(sortedAppenderNames.length);
+		for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
+			final Object keyObj = entry.getKey();
+			if (keyObj != null) {
+				final String key = keyObj.toString();
+				if (key.startsWith(prefix)) {
+					if (key.indexOf('.', preLength) < 0) {
+						final String name = key.substring(preLength);
+						if (Arrays.binarySearch(sortedAppenderNames, name) >= 0) {
+							final Object value = entry.getValue();
+							if (value != null) {
+								map.put(name, value.toString());
+							}
+						}
+					}
+				}
+			}
+		}
+		return map;
+	}
 
-    private void buildAppender(final String appenderName, final String appenderClass) {
-        switch (appenderClass) {
-        case "org.apache.log4j.ConsoleAppender":
-            buildConsoleAppender(appenderName);
-            break;
-        case "org.apache.log4j.FileAppender":
-            buildFileAppender(appenderName);
-            break;
-        case "org.apache.log4j.varia.NullAppender":
-            buildNullAppender(appenderName);
-            break;
-        default:
-            reportWarning("Unknown appender class: " + appenderClass + "; ignoring appender: " + appenderName);
-        }
-    }
+	private void buildAppender(final String appenderName, final String appenderClass) {
+		switch (appenderClass) {
+		case "org.apache.log4j.ConsoleAppender":
+			buildConsoleAppender(appenderName);
+			break;
+		case "org.apache.log4j.FileAppender":
+			buildFileAppender(appenderName);
+			break;
+		case "org.apache.log4j.RollingFileAppender":
+			buildRollingFileAppender(appenderName);
+			break;
+		case "org.apache.log4j.varia.NullAppender":
+			buildNullAppender(appenderName);
+			break;
+		default:
+			reportWarning("Unknown appender class: " + appenderClass + "; ignoring appender: " + appenderName);
+		}
+	}
 
 	private void buildConsoleAppender(final String appenderName) {
-        final AppenderComponentBuilder appenderBuilder = builder.newAppender(appenderName, "Console");
-        final String targetValue = getLog4jAppenderValue(appenderName, "Target", "System.out");
-        if (targetValue != null) {
-            final ConsoleAppender.Target target;
-            switch (targetValue) {
-            case "System.out":
-                target = ConsoleAppender.Target.SYSTEM_OUT;
-                break;
-            case "System.err":
-                target = ConsoleAppender.Target.SYSTEM_ERR;
-                break;
-            default:
-                reportWarning("Unknown value for console Target: " + targetValue);
-                target = null;
-            }
-            if (target != null) {
-                appenderBuilder.addAttribute("target", target);
-            }
-        }
-        buildAttribute(appenderName, appenderBuilder, "Follow", "follow");
-        if ("false".equalsIgnoreCase(getLog4jAppenderValue(appenderName, "ImmediateFlush"))) {
-            reportWarning("ImmediateFlush=false is not supported on Console appender");
-        }
-        buildAppenderLayout(appenderName, appenderBuilder);
-        builder.add(appenderBuilder);
-    }
+		final AppenderComponentBuilder appenderBuilder = builder.newAppender(appenderName, "Console");
+		final String targetValue = getLog4jAppenderValue(appenderName, "Target", "System.out");
+		if (targetValue != null) {
+			final ConsoleAppender.Target target;
+			switch (targetValue) {
+			case "System.out":
+				target = ConsoleAppender.Target.SYSTEM_OUT;
+				break;
+			case "System.err":
+				target = ConsoleAppender.Target.SYSTEM_ERR;
+				break;
+			default:
+				reportWarning("Unknown value for console Target: " + targetValue);
+				target = null;
+			}
+			if (target != null) {
+				appenderBuilder.addAttribute("target", target);
+			}
+		}
+		buildAttribute(appenderName, appenderBuilder, "Follow", "follow");
+		if ("false".equalsIgnoreCase(getLog4jAppenderValue(appenderName, "ImmediateFlush"))) {
+			reportWarning("ImmediateFlush=false is not supported on Console appender");
+		}
+		buildAppenderLayout(appenderName, appenderBuilder);
+		builder.add(appenderBuilder);
+	}
 
-    private void buildFileAppender(final String appenderName) {
-        final AppenderComponentBuilder appenderBuilder = builder.newAppender(appenderName, "File");
-        buildMandatoryAttribute(appenderName, appenderBuilder, "File", "fileName");
-        buildAttribute(appenderName, appenderBuilder, "Append", "append");
-        buildAttribute(appenderName, appenderBuilder, "BufferedIO", "bufferedIo");
-        buildAttribute(appenderName, appenderBuilder, "BufferSize", "bufferSize");
-        buildAttribute(appenderName, appenderBuilder, "ImmediateFlush", "immediateFlush");
-        buildAppenderLayout(appenderName, appenderBuilder);
-        builder.add(appenderBuilder);
-    }
+	private void buildFileAppender(final String appenderName) {
+		final AppenderComponentBuilder appenderBuilder = builder.newAppender(appenderName, "File");
+		buildMandatoryAttribute(appenderName, appenderBuilder, "File", "fileName");
+		buildAttribute(appenderName, appenderBuilder, "Append", "append");
+		buildAttribute(appenderName, appenderBuilder, "BufferedIO", "bufferedIo");
+		buildAttribute(appenderName, appenderBuilder, "BufferSize", "bufferSize");
+		buildAttribute(appenderName, appenderBuilder, "ImmediateFlush", "immediateFlush");
+		buildAppenderLayout(appenderName, appenderBuilder);
+		builder.add(appenderBuilder);
+	}
 
-    private void buildAttribute(final String componentName, final ComponentBuilder componentBuilder,
-                                final String sourceAttributeName, final String targetAttributeName) {
-        final String attributeValue = getLog4jAppenderValue(componentName, sourceAttributeName);
-        if (attributeValue != null) {
-            componentBuilder.addAttribute(targetAttributeName, attributeValue);
-        }
-    }
+	private void buildRollingFileAppender(final String appenderName) {
+		final AppenderComponentBuilder appenderBuilder = builder.newAppender(appenderName, "RollingFile");
+		buildMandatoryAttribute(appenderName, appenderBuilder, "File", "fileName");
+		final String fileName = getLog4jAppenderValue(appenderName, "File");
+		appenderBuilder.addAttribute("filePattern", fileName + ".%i");
+		final String maxFileSizeString = getLog4jAppenderValue(appenderName, "MaxFileSize", "10485760");
+		final String maxBackupIndexString = getLog4jAppenderValue(appenderName, "MaxBackupIndex", "1");
+		final ComponentBuilder<?> triggeringPolicy = builder.newComponent("Policies").addComponent(
+				builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", maxFileSizeString));
+		appenderBuilder.addComponent(triggeringPolicy);
+		appenderBuilder.addComponent(
+				builder.newComponent("DefaultRolloverStrategy").addAttribute("max", maxBackupIndexString));
+		builder.add(appenderBuilder);
+	}
+
+	private void buildAttribute(final String componentName, final ComponentBuilder componentBuilder,
+			final String sourceAttributeName, final String targetAttributeName) {
+		final String attributeValue = getLog4jAppenderValue(componentName, sourceAttributeName);
+		if (attributeValue != null) {
+			componentBuilder.addAttribute(targetAttributeName, attributeValue);
+		}
+	}
 
-    private void buildAttributeWithDefault(final String componentName, final ComponentBuilder componentBuilder,
-                                           final String sourceAttributeName, final String targetAttributeName, final String defaultValue) {
-        final String attributeValue = getLog4jAppenderValue(componentName, sourceAttributeName, defaultValue);
-        componentBuilder.addAttribute(targetAttributeName, attributeValue);
-    }
+	private void buildAttributeWithDefault(final String componentName, final ComponentBuilder componentBuilder,
+			final String sourceAttributeName, final String targetAttributeName, final String defaultValue) {
+		final String attributeValue = getLog4jAppenderValue(componentName, sourceAttributeName, defaultValue);
+		componentBuilder.addAttribute(targetAttributeName, attributeValue);
+	}
 
-    private void buildMandatoryAttribute(final String componentName, final ComponentBuilder componentBuilder,
-                                         final String sourceAttributeName, final String targetAttributeName) {
-        final String attributeValue = getLog4jAppenderValue(componentName, sourceAttributeName);
-        if (attributeValue != null) {
-            componentBuilder.addAttribute(targetAttributeName, attributeValue);
-        } else {
-            reportWarning("Missing " + sourceAttributeName + " for " + componentName);
-        }
-    }
+	private void buildMandatoryAttribute(final String componentName, final ComponentBuilder componentBuilder,
+			final String sourceAttributeName, final String targetAttributeName) {
+		final String attributeValue = getLog4jAppenderValue(componentName, sourceAttributeName);
+		if (attributeValue != null) {
+			componentBuilder.addAttribute(targetAttributeName, attributeValue);
+		} else {
+			reportWarning("Missing " + sourceAttributeName + " for " + componentName);
+		}
+	}
 
-    private void buildNullAppender(String appenderName) {
-        final AppenderComponentBuilder appenderBuilder = builder.newAppender(appenderName, "Null");
-        builder.add(appenderBuilder);
+	private void buildNullAppender(String appenderName) {
+		final AppenderComponentBuilder appenderBuilder = builder.newAppender(appenderName, "Null");
+		builder.add(appenderBuilder);
 	}
 
-    private void buildAppenderLayout(final String name, final AppenderComponentBuilder appenderBuilder) {
-        final String layoutClass = getLog4jAppenderValue(name, "layout", null);
-        if (layoutClass != null) {
-            switch (layoutClass) {
-            case "org.apache.log4j.PatternLayout":
-            case "org.apache.log4j.EnhancedPatternLayout": {
-                final String pattern = getLog4jAppenderValue(name, "layout.ConversionPattern", null)
+	private void buildAppenderLayout(final String name, final AppenderComponentBuilder appenderBuilder) {
+		final String layoutClass = getLog4jAppenderValue(name, "layout", null);
+		if (layoutClass != null) {
+			switch (layoutClass) {
+			case "org.apache.log4j.PatternLayout":
+			case "org.apache.log4j.EnhancedPatternLayout": {
+				final String pattern = getLog4jAppenderValue(name, "layout.ConversionPattern", null)
 
-                    // Log4j 2's %x (NDC) is not compatible with Log4j 1's %x
-                    //   Log4j 1: "foo bar baz"
-                    //   Log4j 2: "[foo, bar, baz]"
-                    // Use %ndc to get the Log4j 1 format
-                    .replace("%x", "%ndc")
+						// Log4j 2's %x (NDC) is not compatible with Log4j 1's
+						// %x
+						// Log4j 1: "foo bar baz"
+						// Log4j 2: "[foo, bar, baz]"
+						// Use %ndc to get the Log4j 1 format
+						.replace("%x", "%ndc")
 
-                    // Log4j 2's %X (MDC) is not compatible with Log4j 1's %X
-                    //   Log4j 1: "{{foo,bar}{hoo,boo}}"
-                    //   Log4j 2: "{foo=bar,hoo=boo}"
-                    // Use %properties to get the Log4j 1 format
-                    .replace("%X", "%properties");
+						// Log4j 2's %X (MDC) is not compatible with Log4j 1's
+						// %X
+						// Log4j 1: "{{foo,bar}{hoo,boo}}"
+						// Log4j 2: "{foo=bar,hoo=boo}"
+						// Use %properties to get the Log4j 1 format
+						.replace("%X", "%properties");
 
-                appenderBuilder.add(newPatternLayout(pattern));
-                break;
-            }
-            case "org.apache.log4j.SimpleLayout": {
-                appenderBuilder.add(newPatternLayout("%level - %m%n"));
-                break;
-            }
-            case "org.apache.log4j.TTCCLayout": {
-                String pattern = "%r ";
-                if (Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.ThreadPrinting", "true"))) {
-                    pattern += "[%t] ";
-                }
-                pattern += "%p ";
-                if (Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.CategoryPrefixing", "true"))) {
-                    pattern += "%c ";
-                }
-                if (Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.ContextPrinting", "true"))) {
-                    pattern += "%notEmpty{%ndc }";
-                }
-                pattern += "- %m%n";
-                appenderBuilder.add(newPatternLayout(pattern));
-                break;
-            }
-            case "org.apache.log4j.HTMLLayout": {
-                final LayoutComponentBuilder htmlLayout = builder.newLayout("HtmlLayout");
-                htmlLayout.addAttribute("title",
-                        getLog4jAppenderValue(name, "layout.Title", "Log4J Log Messages"));
-                htmlLayout.addAttribute("locationInfo",
-                        Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.LocationInfo", "false")));
-                appenderBuilder.add(htmlLayout);
-                break;
-            }
-            case "org.apache.log4j.xml.XMLLayout": {
-                final LayoutComponentBuilder xmlLayout = builder.newLayout("Log4j1XmlLayout");
-                xmlLayout.addAttribute("locationInfo",
-                        Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.LocationInfo", "false")));
-                xmlLayout.addAttribute("properties",
-                        Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.Properties", "false")));
-                appenderBuilder.add(xmlLayout);
-                break;
-            }
-            default:
-                reportWarning("Unknown layout class: " + layoutClass);
-            }
-        }
-    }
+				appenderBuilder.add(newPatternLayout(pattern));
+				break;
+			}
+			case "org.apache.log4j.SimpleLayout": {
+				appenderBuilder.add(newPatternLayout("%level - %m%n"));
+				break;
+			}
+			case "org.apache.log4j.TTCCLayout": {
+				String pattern = "%r ";
+				if (Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.ThreadPrinting", "true"))) {
+					pattern += "[%t] ";
+				}
+				pattern += "%p ";
+				if (Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.CategoryPrefixing", "true"))) {
+					pattern += "%c ";
+				}
+				if (Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.ContextPrinting", "true"))) {
+					pattern += "%notEmpty{%ndc }";
+				}
+				pattern += "- %m%n";
+				appenderBuilder.add(newPatternLayout(pattern));
+				break;
+			}
+			case "org.apache.log4j.HTMLLayout": {
+				final LayoutComponentBuilder htmlLayout = builder.newLayout("HtmlLayout");
+				htmlLayout.addAttribute("title", getLog4jAppenderValue(name, "layout.Title", "Log4J Log Messages"));
+				htmlLayout.addAttribute("locationInfo",
+						Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.LocationInfo", "false")));
+				appenderBuilder.add(htmlLayout);
+				break;
+			}
+			case "org.apache.log4j.xml.XMLLayout": {
+				final LayoutComponentBuilder xmlLayout = builder.newLayout("Log4j1XmlLayout");
+				xmlLayout.addAttribute("locationInfo",
+						Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.LocationInfo", "false")));
+				xmlLayout.addAttribute("properties",
+						Boolean.parseBoolean(getLog4jAppenderValue(name, "layout.Properties", "false")));
+				appenderBuilder.add(xmlLayout);
+				break;
+			}
+			default:
+				reportWarning("Unknown layout class: " + layoutClass);
+			}
+		}
+	}
 
-    private LayoutComponentBuilder newPatternLayout(final String pattern) {
-        final LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout");
-        if (pattern != null) {
-            layoutBuilder.addAttribute("pattern", pattern);
-        }
-        return layoutBuilder;
-    }
+	private LayoutComponentBuilder newPatternLayout(final String pattern) {
+		final LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout");
+		if (pattern != null) {
+			layoutBuilder.addAttribute("pattern", pattern);
+		}
+		return layoutBuilder;
+	}
 
-    private String[] buildRootLogger(final String rootLoggerValue) {
-        if (rootLoggerValue == null) {
-            return new String[0];
-        }
-        final String[] rootLoggerParts = rootLoggerValue.split("\\s*,\\s*");
-        final Level rootLoggerLevel = rootLoggerParts.length > 0 ? Level.valueOf(rootLoggerParts[0]) : Level.ERROR;
-        final String[] sortedAppenderNames = Arrays.copyOfRange(rootLoggerParts, 1, rootLoggerParts.length);
-        Arrays.sort(sortedAppenderNames);
-        final RootLoggerComponentBuilder loggerBuilder = builder.newRootLogger(rootLoggerLevel);
-        for (final String appender : sortedAppenderNames) {
-            loggerBuilder.add(builder.newAppenderRef(appender));
-        }
-        builder.add(loggerBuilder);
-        return sortedAppenderNames;
-    }
+	private String[] buildRootLogger(final String rootLoggerValue) {
+		if (rootLoggerValue == null) {
+			return new String[0];
+		}
+		final String[] rootLoggerParts = rootLoggerValue.split("\\s*,\\s*");
+		final Level rootLoggerLevel = rootLoggerParts.length > 0 ? Level.valueOf(rootLoggerParts[0]) : Level.ERROR;
+		final String[] sortedAppenderNames = Arrays.copyOfRange(rootLoggerParts, 1, rootLoggerParts.length);
+		Arrays.sort(sortedAppenderNames);
+		final RootLoggerComponentBuilder loggerBuilder = builder.newRootLogger(rootLoggerLevel);
+		for (final String appender : sortedAppenderNames) {
+			loggerBuilder.add(builder.newAppenderRef(appender));
+		}
+		builder.add(loggerBuilder);
+		return sortedAppenderNames;
+	}
 
-    private void buildLoggers(final String prefix) {
-        final int preLength = prefix.length();
-        for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
-            final Object keyObj = entry.getKey();
-            if (keyObj != null) {
-                final String key = keyObj.toString();
-                if (key.startsWith(prefix)) {
-                    final String name = key.substring(preLength);
-                    final Object value = entry.getValue();
-                    if (value != null) {
-                        builder.add(builder.newLogger(name, Level.valueOf(value.toString())));
-                    }
-                }
-            }
-        }
+	private void buildLoggers(final String prefix) {
+		final int preLength = prefix.length();
+		for (final Map.Entry<Object, Object> entry : properties.entrySet()) {
+			final Object keyObj = entry.getKey();
+			if (keyObj != null) {
+				final String key = keyObj.toString();
+				if (key.startsWith(prefix)) {
+					final String name = key.substring(preLength);
+					final Object value = entry.getValue();
+					if (value != null) {
+						builder.add(builder.newLogger(name, Level.valueOf(value.toString())));
+					}
+				}
+			}
+		}
 
-    }
+	}
 
-    private String getLog4jAppenderValue(final String appenderName, final String attributeName) {
-        return properties.getProperty("log4j.appender." + appenderName + "." + attributeName);
-    }
+	private String getLog4jAppenderValue(final String appenderName, final String attributeName) {
+		return properties.getProperty("log4j.appender." + appenderName + "." + attributeName);
+	}
 
-    private String getLog4jAppenderValue(final String appenderName, final String attributeName,
-                                         final String defaultValue) {
-        return properties.getProperty("log4j.appender." + appenderName + "." + attributeName, defaultValue);
-    }
+	private String getLog4jAppenderValue(final String appenderName, final String attributeName,
+			final String defaultValue) {
+		return properties.getProperty("log4j.appender." + appenderName + "." + attributeName, defaultValue);
+	}
 
-    private String getLog4jValue(final String key) {
-        return properties.getProperty("log4j." + key);
-    }
+	private String getLog4jValue(final String key) {
+		return properties.getProperty("log4j." + key);
+	}
 
-    private void reportWarning(final String msg) {
-        StatusLogger.getLogger().warn("Log4j 1 configuration parser: " + msg);
-    }
+	private void reportWarning(final String msg) {
+		StatusLogger.getLogger().warn("Log4j 1 configuration parser: " + msg);
+	}
 
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/906abebb/log4j-1.2-api/src/test/java/org/apache/log4j/config/Log4j1ConfigurationFactoryTest.java
----------------------------------------------------------------------
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 842bf6b..81be695 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
@@ -32,6 +32,12 @@ import org.apache.logging.log4j.core.appender.ConsoleAppender;
 import org.apache.logging.log4j.core.appender.ConsoleAppender.Target;
 import org.apache.logging.log4j.core.appender.FileAppender;
 import org.apache.logging.log4j.core.appender.NullAppender;
+import org.apache.logging.log4j.core.appender.RollingFileAppender;
+import org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy;
+import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
+import org.apache.logging.log4j.core.appender.rolling.RolloverStrategy;
+import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy;
+import org.apache.logging.log4j.core.appender.rolling.TriggeringPolicy;
 import org.apache.logging.log4j.core.config.Configuration;
 import org.apache.logging.log4j.core.config.LoggerConfig;
 import org.apache.logging.log4j.core.layout.HtmlLayout;
@@ -121,7 +127,6 @@ public class Log4j1ConfigurationFactoryTest {
 
 	@Test
 	public void testNullAppender() throws Exception {
-		StatusLogger.getLogger().setLevel(Level.TRACE);
 		final Configuration configuration = configure("config-1.2/log4j-NullAppender.properties");
 		final Appender appender = configuration.getAppender("NullAppender");
 		assertNotNull(appender);
@@ -129,4 +134,31 @@ public class Log4j1ConfigurationFactoryTest {
 		assertTrue(appender.getClass().getName(), appender instanceof NullAppender);
 	}
 
+	@Test
+	public void testRollingFileAppender() throws Exception {
+		StatusLogger.getLogger().setLevel(Level.TRACE);
+		final Configuration configuration = configure("config-1.2/log4j-RollingFileAppender.properties");
+		final Appender appender = configuration.getAppender("RFA");
+		assertNotNull(appender);
+		assertEquals("RFA", appender.getName());
+		assertTrue(appender.getClass().getName(), appender instanceof RollingFileAppender);
+		final RollingFileAppender rfa = (RollingFileAppender) appender;
+		assertEquals("./hadoop.log", rfa.getFileName());
+		assertEquals("./hadoop.log.%i", rfa.getFilePattern());
+		final TriggeringPolicy triggeringPolicy = rfa.getTriggeringPolicy();
+		assertNotNull(triggeringPolicy);
+		assertTrue(triggeringPolicy.getClass().getName(), triggeringPolicy instanceof CompositeTriggeringPolicy);
+		final CompositeTriggeringPolicy ctp = (CompositeTriggeringPolicy) triggeringPolicy;
+		final TriggeringPolicy[] triggeringPolicies = ctp.getTriggeringPolicies();
+		assertEquals(1, triggeringPolicies.length);
+		final TriggeringPolicy tp = triggeringPolicies[0];
+		assertTrue(tp.getClass().getName(), tp instanceof SizeBasedTriggeringPolicy);
+		final SizeBasedTriggeringPolicy sbtp = (SizeBasedTriggeringPolicy) tp;
+		assertEquals(256 * 1024 * 1024, sbtp.getMaxFileSize());
+		final RolloverStrategy rolloverStrategy = rfa.getManager().getRolloverStrategy();
+		assertTrue(rolloverStrategy.getClass().getName(), rolloverStrategy instanceof DefaultRolloverStrategy);
+		final DefaultRolloverStrategy drs = (DefaultRolloverStrategy) rolloverStrategy;
+		assertEquals(20, drs.getMaxIndex());
+	}
+
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/906abebb/log4j-1.2-api/src/test/resources/config-1.2/log4j-RollingFileAppender-with-props.properties
----------------------------------------------------------------------
diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-RollingFileAppender-with-props.properties b/log4j-1.2-api/src/test/resources/config-1.2/log4j-RollingFileAppender-with-props.properties
new file mode 100644
index 0000000..26fd391
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-RollingFileAppender-with-props.properties
@@ -0,0 +1,27 @@
+###############################################################################
+#
+# Log4J 1.2 Configuration.
+#
+
+hadoop.log.dir=.
+hadoop.log.file=hadoop.log
+
+log4j.rootLogger=TRACE, RFA
+
+#
+# Rolling File Appender - cap space usage at 5gb.
+#
+hadoop.log.maxfilesize=256MB
+hadoop.log.maxbackupindex=20
+log4j.appender.RFA=org.apache.log4j.RollingFileAppender
+log4j.appender.RFA.File=${hadoop.log.dir}/${hadoop.log.file}
+
+log4j.appender.RFA.MaxFileSize=${hadoop.log.maxfilesize}
+log4j.appender.RFA.MaxBackupIndex=${hadoop.log.maxbackupindex}
+
+log4j.appender.RFA.layout=org.apache.log4j.PatternLayout
+
+# Pattern format: Date LogLevel LoggerName LogMessage
+log4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n
+# Debugging Pattern format
+#log4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/906abebb/log4j-1.2-api/src/test/resources/config-1.2/log4j-RollingFileAppender.properties
----------------------------------------------------------------------
diff --git a/log4j-1.2-api/src/test/resources/config-1.2/log4j-RollingFileAppender.properties b/log4j-1.2-api/src/test/resources/config-1.2/log4j-RollingFileAppender.properties
new file mode 100644
index 0000000..d18c39a
--- /dev/null
+++ b/log4j-1.2-api/src/test/resources/config-1.2/log4j-RollingFileAppender.properties
@@ -0,0 +1,22 @@
+###############################################################################
+#
+# Log4J 1.2 Configuration.
+#
+
+log4j.rootLogger=TRACE, RFA
+
+#
+# Rolling File Appender - cap space usage at 5gb.
+#
+log4j.appender.RFA=org.apache.log4j.RollingFileAppender
+log4j.appender.RFA.File=./hadoop.log
+
+log4j.appender.RFA.MaxFileSize=256MB
+log4j.appender.RFA.MaxBackupIndex=20
+
+log4j.appender.RFA.layout=org.apache.log4j.PatternLayout
+
+# Pattern format: Date LogLevel LoggerName LogMessage
+log4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n
+# Debugging Pattern format
+#log4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n