You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rg...@apache.org on 2020/08/18 17:03:33 UTC

[logging-log4j2] branch master updated: LOG4J2-2847 Extend Log4j-config.xsd (#360)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new 22c1f39  LOG4J2-2847 Extend Log4j-config.xsd (#360)
22c1f39 is described below

commit 22c1f393635e61c1a44a809feab4d0950fa7f228
Author: Sebastian Thomschke <se...@users.noreply.github.com>
AuthorDate: Tue Aug 18 19:03:23 2020 +0200

    LOG4J2-2847 Extend Log4j-config.xsd (#360)
    
    This commit modifies the Log4j-config.xsd in the following ways:
    a) the type elements are re-order in a way that related types are
    physically close to each other, that helps with extending the schema in
    the future
    b) the Configuration type is extended by the missing attributes
    c) validation for boolean/integer types is added
    d) uniqueness is enforced when declaring custom levels, properties and
    loggers
    e) new configuration elements are added (filters, appenders)
    f) the default values and description of attributes are added
---
 log4j-core/src/main/resources/Log4j-config.xsd     | 1438 ++++++++++++++++++--
 .../log4j/core/config/xml/XmlSchemaTest.java       |  132 ++
 2 files changed, 1424 insertions(+), 146 deletions(-)

diff --git a/log4j-core/src/main/resources/Log4j-config.xsd b/log4j-core/src/main/resources/Log4j-config.xsd
index 0ead84d..f0c9081 100644
--- a/log4j-core/src/main/resources/Log4j-config.xsd
+++ b/log4j-core/src/main/resources/Log4j-config.xsd
@@ -16,149 +16,1295 @@
  limitations under the License.
 
 -->
-<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://logging.apache.org/log4j/2.0/config" targetNamespace="http://logging.apache.org/log4j/2.0/config" elementFormDefault="qualified" attributeFormDefault="unqualified">
-    <xs:element name="Configuration" type="ConfigurationType"/>
-    <xs:complexType name="ConfigurationType">
-        <xs:sequence>
-            <xs:choice minOccurs="0" maxOccurs="1">
-                <xs:element name="CustomLevels" type="CustomLevelsType"/>
-                <xs:element name="CustomLevel" type="CustomLevelType"/>
-            </xs:choice>
-            <xs:element name="Properties" type="PropertiesType" minOccurs="0"/>
-            <xs:choice minOccurs="0" maxOccurs="1">
-                <xs:element name="Filters" type="FiltersType"/>
-                <xs:element name="Filter" type="FilterType"/>
-            </xs:choice>
-            <xs:element name="ThresholdFilter" type="ThresholdFilterType" minOccurs="0"/>
-            <xs:element name="Appenders" type="AppendersType"/>
-            <xs:element name="Loggers" type="LoggersType"/>
-        </xs:sequence>
-        <xs:attribute name="packages" type="xs:string"/>
-        <xs:attribute name="status" type="xs:string"/>
-        <xs:attribute name="strict" type="xs:string"/>
-        <xs:attribute name="name" type="xs:string"/>
-        <xs:attribute name="advertiser" type="xs:string"/>
-        <xs:attribute name="shutdownTimeout" type="xs:string" use="optional"/>
-        <xs:attribute name="schema" type="xs:string"/>
-    </xs:complexType>
-    <xs:complexType name="PropertiesType">
-        <xs:sequence>
-            <xs:element name="Property" type="PropertyType" minOccurs="0" maxOccurs="unbounded"/>
-        </xs:sequence>
-    </xs:complexType>
-    <xs:complexType name="AppenderType">
-        <xs:sequence>
-            <xs:element name="Layout" type="LayoutType" minOccurs="0"/>
-            <xs:choice minOccurs="0" maxOccurs="1">
-                <xs:element name="Filters" type="FiltersType"/>
-                <xs:element name="Filter" type="FilterType"/>
-            </xs:choice>
-        </xs:sequence>
-        <xs:attribute name="type" type="xs:string" use="required"/>
-        <xs:attribute name="name" type="xs:string" use="required"/>
-        <xs:attribute name="fileName" type="xs:string" use="optional"/>
-    </xs:complexType>
-    <xs:complexType name="RootType">
-        <xs:sequence>
-            <xs:element name="AppenderRef" type="AppenderRefType" minOccurs="1" maxOccurs="unbounded"/>
-        </xs:sequence>
-        <xs:attribute name="level" type="xs:string"/>
-    </xs:complexType>
-    <xs:complexType name="PropertyType">
-        <xs:simpleContent>
-            <xs:extension base="xs:string">
-                <xs:attribute name="name" type="xs:string"/>
-            </xs:extension>
-        </xs:simpleContent>
-    </xs:complexType>
-    <xs:complexType name="KeyValuePairType">
-        <xs:simpleContent>
-            <xs:extension base="xs:string">
-                <xs:attribute name="key" type="xs:string"/>
-                <xs:attribute name="value" type="xs:string"/>
-            </xs:extension>
-        </xs:simpleContent>
-    </xs:complexType>
-    <xs:complexType name="AppendersType">
-        <xs:sequence>
-          <xs:element name="Appender" type="AppenderType" minOccurs="0" maxOccurs="unbounded"/>
-            <xs:element name="Console" type="ConsoleType" minOccurs="0"/>
-        </xs:sequence>
-    </xs:complexType>
- <xs:complexType name="ConsoleType">
-        <xs:sequence>
-            <xs:element name="PatternLayout" type="PatternLayoutType" minOccurs="1" maxOccurs="unbounded"/>
-        </xs:sequence>
-        <xs:attribute type="xs:string" name="name" use="required"/>
-        <xs:attribute type="xs:string" name="target" use="required"/>
-        <xs:attribute type="xs:string" name="follow" use="optional"/>
-  </xs:complexType>
-     <xs:complexType name="PatternLayoutType">
-        <xs:simpleContent>
-            <xs:extension base="xs:string">
-                <xs:attribute type="xs:string" name="pattern" use="required"/>
-            </xs:extension>
-        </xs:simpleContent>
-    </xs:complexType>
-               <xs:complexType name="AppenderRefType">
-        <xs:simpleContent>
-            <xs:extension base="xs:string">
-                <xs:attribute name="ref" type="xs:string" use="required"/>
-            </xs:extension>
-        </xs:simpleContent>
-    </xs:complexType>
-    <xs:complexType name="LoggerType">
-        <xs:sequence>
-            <xs:choice minOccurs="0" maxOccurs="1">
-                <xs:element name="Filters" type="FiltersType"/>
-                <xs:element name="Filter" type="FilterType"/>
-            </xs:choice>
-            <xs:element name="AppenderRef" type="AppenderRefType" minOccurs="0" maxOccurs="unbounded"/>
-        </xs:sequence>
-        <xs:attribute name="name" type="xs:string" use="required"/>
-        <xs:attribute name="level" type="xs:string" use="optional"/>
-        <xs:attribute name="additivity" type="xs:string" use="optional"/>
-    </xs:complexType>
-    <xs:complexType name="FilterType" mixed="true">
-        <xs:sequence>
-            <xs:element name="KeyValuePair" type="KeyValuePairType" minOccurs="0"/>
-        </xs:sequence>
-        <xs:attribute name="type" type="xs:string" use="required"/>
-        <xs:attribute name="level" type="xs:string" use="optional"/>
-        <xs:attribute name="marker" type="xs:string" use="optional"/>
-        <xs:attribute name="onMatch" type="xs:string" use="optional"/>
-        <xs:attribute name="onMismatch" type="xs:string" use="optional"/>
-    </xs:complexType>
-    <xs:complexType name="FiltersType">
-        <xs:sequence>
-            <xs:element name="Filter" type="FilterType" minOccurs="0" maxOccurs="unbounded"/>
-        </xs:sequence>
-    </xs:complexType>
-    <xs:complexType name="CustomLevelType">
-        <xs:attribute name="name" type="xs:string" use="required"/>
-        <xs:attribute name="intLevel" type="xs:string" use="required"/>
-    </xs:complexType>
-    <xs:complexType name="CustomLevelsType">
-        <xs:sequence>
-            <xs:element name="CustomLevel" type="CustomLevelType" minOccurs="0" maxOccurs="unbounded"/>
-        </xs:sequence>
-    </xs:complexType>
-    <xs:complexType name="LoggersType" mixed="true">
-        <xs:sequence>
-            <xs:element name="Logger" type="LoggerType" minOccurs="0" maxOccurs="unbounded"/>
-            <xs:element name="Root" type="RootType" minOccurs="1" maxOccurs="1"/>
-        </xs:sequence>
-    </xs:complexType>
-    <xs:complexType name="LayoutType" mixed="true">
-        <xs:sequence>
-            <xs:element name="Pattern" type="xs:string" minOccurs="0"/>
-        </xs:sequence>
-        <xs:attribute name="type" type="xs:string" use="required"/>
-        <xs:attribute name="pattern" type="xs:string" use="optional"/>
-    </xs:complexType>
-    <xs:complexType name="ThresholdFilterType">
-        <xs:attribute name="level" type="xs:string" use="optional"/>
-        <xs:attribute name="onMatch" type="xs:string" use="optional"/>
-        <xs:attribute name="onMismatch" type="xs:string" use="optional"/>
-    </xs:complexType>
-</xs:schema>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://logging.apache.org/log4j/2.0/config"
+   targetNamespace="http://logging.apache.org/log4j/2.0/config" elementFormDefault="qualified" attributeFormDefault="unqualified">
+
+   <!--
+    ================================================================================================================================
+    <Configuration> root element
+    ================================================================================================================================
+    -->
+   <element name="Configuration">
+      <complexType>
+         <sequence>
+            <choice minOccurs="0" maxOccurs="1">
+               <element name="CustomLevels" type="tns:CustomLevelsType">
+                  <unique name="UniqueCustomLevelName">
+                     <selector xpath="tns:CustomLevel" />
+                     <field xpath="@name" />
+                  </unique>
+               </element>
+               <element name="CustomLevel" type="tns:CustomLevelType" />
+            </choice>
+            <element name="Properties" minOccurs="0">
+               <complexType>
+                  <sequence>
+                     <element name="Property" type="tns:PropertyType" minOccurs="0" maxOccurs="unbounded" />
+                  </sequence>
+               </complexType>
+               <unique name="UniquePropertyName">
+                  <selector xpath="tns:Property" />
+                  <field xpath="@name" />
+               </unique>
+            </element>
+
+            <element name="Scripts" minOccurs="0" maxOccurs="unbounded">
+               <complexType>
+                  <sequence>
+                     <element name="ScriptFile" minOccurs="0" maxOccurs="unbounded">
+                        <complexType>
+                           <attribute name="name" type="string" use="required" />
+                           <attribute name="language" type="string" />
+                           <attribute name="path" type="string" use="required" />
+                           <attribute name="charset" type="string" />
+                        </complexType>
+                     </element>
+                  </sequence>
+               </complexType>
+            </element>
+
+            <group ref="tns:FilterChoiceGroup" minOccurs="0" maxOccurs="1" />
+
+            <element name="Appenders" type="tns:AppendersType" minOccurs="0" />
+
+            <element name="Loggers" type="tns:LoggersType" minOccurs="0">
+               <unique name="UniqueLoggerName">
+                  <selector xpath="tns:Logger" />
+                  <field xpath="@name" />
+               </unique>
+            </element>
+         </sequence>
+
+         <attribute name="advertiser" type="string">
+            <annotation>
+               <documentation>The Advertiser plugin name which will be used to advertise individual FileAppender or SocketAppender configurations. The only
+                  Advertiser plugin provided is 'multicastdns".
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="dest" type="string">
+            <annotation>
+               <documentation>Either "err" for stderr, "out" for stdout, a file path, or a URL.</documentation>
+            </annotation>
+         </attribute>
+         <attribute name="monitorInterval" type="tns:IntegerType">
+            <annotation>
+               <documentation>The minimum amount of time, in seconds, that must elapse before the file configuration is checked for changes.</documentation>
+            </annotation>
+         </attribute>
+         <attribute name="name" type="string">
+            <annotation>
+               <documentation>The name of the configuration.</documentation>
+            </annotation>
+         </attribute>
+         <attribute name="packages" type="string">
+            <annotation>
+               <documentation>A comma separated list of package names to search for plugins. Plugins are only loaded once per classloader so changing this value
+                  may not have any effect upon reconfiguration.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="schema" type="string">
+            <annotation>
+               <documentation>Identifies the location for the classloader to located the XML Schema to use to validate the configuration. Only valid when strict
+                  is set to true. If not set no schema validation will take place.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="shutdownHook">
+            <annotation>
+               <documentation>Specifies whether or not Log4j should automatically shutdown when the JVM shuts down. The shutdown hook is enabled by default but
+                  may be disabled by setting this attribute to "disable".
+               </documentation>
+            </annotation>
+            <simpleType>
+               <restriction base="string">
+                  <pattern value="(|disable|\$\{[^{}]+\})" />
+               </restriction>
+            </simpleType>
+         </attribute>
+         <attribute name="shutdownTimeout" type="tns:IntegerType" default="0">
+            <annotation>
+               <documentation>Specifies how many milliseconds appenders and background tasks will get to shutdown when the JVM shuts down. Default is zero which
+                  mean that each appender uses its default timeout, and don't wait for background tasks.
+               </documentation>
+            </annotation>
+         </attribute>
+         <attribute name="status">
+            <annotation>
+               <documentation>The level of internal Log4j events that should be logged to the console. Valid values for this attribute are "trace", "debug",
+                  "info", "warn", "error" and "fatal".
+               </documentation>
+            </annotation>
+            <simpleType>
+               <restriction base="string">
+                  <pattern
+                     value="([Tt][Rr][Aa][Cc][Ee]|[Dd][Ee][Bb][Uu][Gg]|[Ii][Nn][Ff][Oo]|[Ww][Aa][Rr][Nn]|[Ee][Rr][Rr][Oo][Rr]|[Ff][Aa][Tt][Aa][Ll]|[Oo][Ff][Ff]|\$\{[^{}]+\})" />
+               </restriction>
+            </simpleType>
+         </attribute>
+         <attribute name="strict" type="tns:BooleanType">
+            <annotation>
+               <documentation>Enables the use of the strict XML format. Not supported in JSON configurations.</documentation>
+            </annotation>
+         </attribute>
+         <attribute name="verbose" type="tns:BooleanType" default="false">
+            <annotation>
+               <documentation>Enables diagnostic information while loading plugins.</documentation>
+            </annotation>
+         </attribute>
+      </complexType>
+   </element>
+
+
+   <!--
+    ================================================================================================================================
+    <Configuration><CustomLevels> type and related types
+    ================================================================================================================================
+    -->
+   <complexType name="CustomLevelsType">
+      <sequence>
+         <element name="CustomLevel" type="tns:CustomLevelType" minOccurs="0" maxOccurs="unbounded" />
+      </sequence>
+   </complexType>
+
+   <complexType name="CustomLevelType">
+      <attribute name="name" type="string" use="required" />
+      <attribute name="intLevel" type="tns:IntegerType" use="required" />
+   </complexType>
+
+
+   <!--
+    ================================================================================================================================
+    Filter types
+    ================================================================================================================================
+    -->
+   <group name="FilterChoiceGroup">
+      <choice>
+         <element name="Filters">
+            <complexType>
+               <group ref="tns:FilterChoiceGroup" minOccurs="0" maxOccurs="unbounded" />
+            </complexType>
+         </element>
+         <element name="Filter" type="tns:FilterType" minOccurs="0" />
+         <element name="BurstFilter" type="tns:BurstFilterType" minOccurs="0" />
+         <element name="ContextMapFilter" type="tns:MapFilterType" minOccurs="0" />
+         <element name="DynamicThresholdFilter" type="tns:DynamicThresholdFilterType" minOccurs="0" />
+         <element name="MapFilter" type="tns:MapFilterType" minOccurs="0" />
+         <element name="MarkerFilter" type="tns:MarkerFilterType" minOccurs="0" />
+         <element name="NoMarkerFilter" type="tns:NoMarkerFilterType" minOccurs="0" />
+         <element name="RegexFilter" type="tns:RegexFilterType" minOccurs="0" />
+         <element name="ScriptFilter" type="tns:ScriptFilterType" minOccurs="0" />
+         <element name="StructuredDataFilter" type="tns:StructuredDataFilterType" minOccurs="0" />
+         <element name="ThreadContextMapFilter" type="tns:MapFilterType" minOccurs="0" />
+         <element name="ThresholdFilter" type="tns:ThresholdFilterType" minOccurs="0" />
+      </choice>
+   </group>
+
+   <complexType name="AbstractFilterType" abstract="true">
+      <attribute name="onMatch" type="tns:FilterActionType" default="NEUTRAL">
+         <annotation>
+            <documentation>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="onMismatch" type="tns:FilterActionType" default="DENY">
+         <annotation>
+            <documentation>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL.</documentation>
+         </annotation>
+      </attribute>
+   </complexType>
+
+   <simpleType name="FilterActionType">
+      <restriction base="string">
+         <enumeration value="ACCEPT" />
+         <enumeration value="accept" />
+         <enumeration value="DENY" />
+         <enumeration value="deny" />
+         <enumeration value="NEUTRAL" />
+         <enumeration value="neutral" />
+      </restriction>
+   </simpleType>
+
+   <complexType name="AbstractFilterTypeWithKeyValuePairs" abstract="true">
+      <complexContent>
+         <extension base="tns:AbstractFilterType">
+            <sequence>
+               <element name="KeyValuePair" type="tns:KeyValuePairType" minOccurs="0" maxOccurs="unbounded">
+                  <annotation>
+                     <documentation>
+                        One or more KeyValuePair elements that define the matching value for the key and the Level to evaluate when the key matches.
+                     </documentation>
+                  </annotation>
+               </element>
+            </sequence>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="BurstFilterType" mixed="true">
+      <complexContent>
+         <extension base="tns:AbstractFilterType">
+            <attribute name="rate" type="string">
+               <annotation>
+                  <documentation>The average number of events per second to allow.</documentation>
+               </annotation>
+            </attribute>
+            <attribute name="maxBurst" type="tns:IntegerType">
+               <annotation>
+                  <documentation>The maximum number of events that can occur before events are filtered for exceeding the average rate. The default is 10 times
+                     the rate.
+                  </documentation>
+               </annotation>
+            </attribute>
+            <attribute name="level" type="string" use="required">
+               <annotation>
+                  <documentation>Level of messages to be filtered. Anything at or below this level will be filtered out if maxBurst has been exceeded. The
+                     default is WARN meaning any messages that are higher than warn will be logged regardless of the size of a burst.
+                  </documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="FilterType" mixed="true">
+      <complexContent>
+         <extension base="tns:AbstractFilterType">
+            <sequence>
+               <element name="KeyValuePair" type="tns:KeyValuePairType" minOccurs="0" />
+            </sequence>
+            <attribute name="type" type="string" use="required">
+               <annotation>
+                  <documentation>The filter type, see https://logging.apache.org/log4j/2.x/manual/filters.html</documentation>
+               </annotation>
+            </attribute>
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="DynamicThresholdFilterType">
+      <complexContent>
+         <extension base="tns:AbstractFilterTypeWithKeyValuePairs">
+            <attribute name="key" type="string" use="required">
+               <annotation>
+                  <documentation>The name of the item in the ThreadContext Map to compare.</documentation>
+               </annotation>
+            </attribute>
+            <attribute name="defaultThreshold" type="string" use="required">
+               <annotation>
+                  <documentation>
+                     Level of messages to be filtered. The default threshold only applies if the log event contains the specified ThreadContext Map
+                     item and its value does not match any key in the key/value pairs.
+                  </documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="MapFilterType">
+      <complexContent>
+         <extension base="tns:AbstractFilterTypeWithKeyValuePairs">
+            <attribute name="operator" type="string">
+               <annotation>
+                  <documentation>
+                     If the operator is "or" then a match by any one of the key/value pairs will be considered to be a match, otherwise all the
+                     key/value pairs must match.
+                  </documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="MarkerFilterType">
+      <complexContent>
+         <extension base="tns:AbstractFilterType">
+            <attribute name="marker" type="string" use="required" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="NoMarkerFilterType">
+      <complexContent>
+         <extension base="tns:AbstractFilterType" />
+      </complexContent>
+   </complexType>
+
+   <complexType name="RegexFilterType">
+      <complexContent>
+         <extension base="tns:AbstractFilterType">
+            <attribute name="regex" type="string" use="required">
+               <annotation>
+                  <documentation>The regular expression.</documentation>
+               </annotation>
+            </attribute>
+            <attribute name="useRawMsg" type="tns:BooleanType" default="false">
+               <annotation>
+                  <documentation>If true the unformatted message will be used, otherwise the formatted message will be used.</documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="ScriptFilterType">
+      <complexContent>
+         <extension base="tns:AbstractFilterType">
+            <choice>
+               <element name="Script">
+                  <complexType mixed="true">
+                     <attribute name="name" type="string" />
+                     <attribute name="language" type="string" />
+                  </complexType>
+               </element>
+               <element name="ScriptFile"></element>
+               <element name="ScriptRef"></element>
+            </choice>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="StructuredDataFilterType">
+      <complexContent>
+         <extension base="tns:AbstractFilterTypeWithKeyValuePairs">
+            <attribute name="operator" type="string">
+               <annotation>
+                  <documentation>
+                     If the operator is "or" then a match by any one of the key/value pairs will be considered to be a match, otherwise all the
+                     key/value pairs must match.
+                  </documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="ThresholdFilterType">
+      <complexContent>
+         <extension base="tns:AbstractFilterType">
+            <attribute name="level" type="string" use="required">
+               <annotation>
+                  <documentation>A valid Level name to match on.</documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+
+   <!--
+    ================================================================================================================================
+    Layout types
+    ================================================================================================================================
+    -->
+   <complexType name="LayoutType">
+      <choice minOccurs="0" maxOccurs="unbounded">
+         <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+      </choice>
+      <attribute name="type" type="string" use="required" />
+      <anyAttribute processContents="lax" />
+   </complexType>
+
+   <complexType name="MessageLayoutType">
+   </complexType>
+
+   <complexType name="PatternLayoutType">
+       <!-- https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout -->
+      <sequence>
+         <choice minOccurs="0">
+            <element name="LevelPatternSelector">
+               <complexType>
+                  <sequence>
+                     <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                  </sequence>
+                  <anyAttribute processContents="lax" />
+               </complexType>
+            </element>
+            <element name="MarkerPatternSelector">
+               <complexType>
+                  <sequence>
+                     <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                  </sequence>
+                  <anyAttribute processContents="lax" />
+               </complexType>
+            </element>
+            <element name="ScriptPatternSelector">
+               <complexType>
+                  <sequence>
+                     <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                  </sequence>
+                  <anyAttribute processContents="lax" />
+               </complexType>
+            </element>
+         </choice>
+         <element name="Replace" minOccurs="0">
+            <complexType>
+               <attribute name="regex" type="string" />
+               <attribute name="replacement" type="string" />
+            </complexType>
+         </element>
+         <element name="Pattern" type="string" minOccurs="0" />
+      </sequence>
+      <attribute name="alwaysWriteExceptions" type="tns:BooleanType" default="true">
+         <annotation>
+            <documentation>If true exceptions are always written even if the pattern contains no exception conversions.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="charset" type="string">
+         <annotation>
+            <documentation>The character set to use when converting the syslog String to a byte array.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="disableAnsi" type="tns:BooleanType" default="false">
+         <annotation>
+            <documentation>If true, do not output ANSI escape codes.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="footer" type="string">
+         <annotation>
+            <documentation>Footer string to include at the bottom of each log file.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="header" type="string">
+         <annotation>
+            <documentation>Header string to include at the top of each log file.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="noConsoleNoAnsi" type="tns:BooleanType" default="false">
+         <annotation>
+            <documentation>If true and System.console() is null, do not output ANSI escape codes.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="pattern" type="string" />
+   </complexType>
+
+   <complexType name="HtmlLayoutType">
+      <attribute name="charset" type="string" />
+      <attribute name="contentType" type="string" />
+      <attribute name="locationInfo" type="tns:BooleanType" />
+      <attribute name="title" type="string" />
+      <attribute name="fontName" type="string" />
+      <attribute name="fontSize" type="string" />
+   </complexType>
+
+   <complexType name="AbstractJsonLayoutType">
+      <sequence>
+         <element name="KeyValuePair" type="tns:KeyValuePairType" minOccurs="0" maxOccurs="unbounded">
+            <annotation>
+               <documentation>
+                  One or more KeyValuePair elements that define custom field in the output.
+               </documentation>
+            </annotation>
+         </element>
+      </sequence>
+      <attribute name="charset" type="string" />
+      <attribute name="complete" type="tns:BooleanType" />
+      <attribute name="compact" type="tns:BooleanType" />
+      <attribute name="eventEol" type="tns:BooleanType" />
+      <attribute name="endOfLine" type="string" />
+      <attribute name="includeNullDelimiter" type="tns:BooleanType" />
+      <attribute name="includeStacktrace" type="tns:BooleanType" />
+      <attribute name="locationInfo" type="tns:BooleanType" />
+      <attribute name="properties" type="tns:BooleanType" />
+      <attribute name="stacktraceAsString" type="tns:BooleanType" />
+   </complexType>
+
+   <complexType name="JCsvParameterLayoutType">
+      <complexContent>
+         <extension base="tns:AbstractJsonLayoutType">
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="GelfLayoutType">
+      <sequence minOccurs="0">
+         <element name="MessagePattern" type="string" minOccurs="0" />
+         <element name="KeyValuePair" type="tns:KeyValuePairType" minOccurs="0" maxOccurs="unbounded">
+            <annotation>
+               <documentation>
+                  One or more KeyValuePair elements that define custom field in the output.
+               </documentation>
+            </annotation>
+         </element>
+      </sequence>
+      <attribute name="host" type="string" />
+      <attribute name="compressionType">
+         <simpleType>
+            <restriction base="string">
+               <enumeration value="GZIP" />
+               <enumeration value="ZLIB" />
+               <enumeration value="OFF" />
+            </restriction>
+         </simpleType>
+      </attribute>
+      <attribute name="compressionThreshold" type="tns:IntegerType" />
+      <attribute name="includeNullDelimiter" type="tns:BooleanType" />
+      <attribute name="includeStacktrace" type="tns:BooleanType" />
+      <attribute name="includeThreadContext" type="tns:BooleanType" />
+      <attribute name="messagePattern" type="string" />
+      <attribute name="threadContextExcludes" type="string" />
+      <attribute name="threadContextIncludes" type="string" />
+   </complexType>
+
+   <complexType name="JsonLayoutType">
+      <complexContent>
+         <extension base="tns:AbstractJsonLayoutType">
+            <attribute name="propertiesAsList" type="tns:BooleanType" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="XmlLayoutType">
+      <complexContent>
+         <extension base="tns:AbstractJsonLayoutType"></extension>
+      </complexContent>
+   </complexType>
+
+
+   <!--
+    ================================================================================================================================
+    Appender types
+    ================================================================================================================================
+    -->
+   <complexType name="AppendersType">
+      <sequence minOccurs="0" maxOccurs="unbounded">
+         <element name="Appender" type="tns:AppenderType" minOccurs="0" />
+         <element name="Async" type="tns:AsyncAppenderType" minOccurs="0" />
+         <element name="Console" type="tns:ConsoleAppenderType" minOccurs="0" />
+         <element name="Flume" type="tns:FlumeAppenderType" minOccurs="0" />
+         <element name="JeroMQ" type="tns:JeroMQAppenderType" minOccurs="0" />
+         <element name="JMS" type="tns:JMSAppenderType" minOccurs="0" />
+         <element name="JMSQueue" type="tns:JMSAppenderType" minOccurs="0" />
+         <element name="JMSTopic" type="tns:JMSAppenderType" minOccurs="0" />
+         <element name="Rewrite" type="tns:RewriteAppenderType" minOccurs="0" />
+         <element name="Routing" type="tns:RoutingAppenderType" minOccurs="0" />
+         <element name="SMTP" type="tns:SMTPAppenderType" minOccurs="0" />
+         <element name="File" type="tns:FileAppenderType" minOccurs="0" />
+         <element name="MemoryMappedFile" type="tns:MemoryMappedFileAppenderType" minOccurs="0" />
+         <element name="RandomAccessFile" type="tns:RandomAccessFileAppenderType" minOccurs="0" />
+         <element name="RollingFile" type="tns:RollingFileAppenderType" minOccurs="0" />
+         <element name="RollingRandomAccessFile" type="tns:RollingRandomAccessFileAppenderType" minOccurs="0" />
+         <element name="Socket" type="tns:SocketAppenderType" minOccurs="0" />
+         <element name="ScriptAppenderSelector" type="tns:ScriptAppenderSelectorType" minOccurs="0" />
+
+         <!-- undocumented appenders used in unit tests -->
+         <element name="AlwaysFail" type="tns:GenericAppenderType" minOccurs="0" />
+         <element name="Block" type="tns:GenericAppenderType" minOccurs="0" />
+         <element name="Blocking" type="tns:GenericAppenderType" minOccurs="0" />
+         <element name="Deadlock" type="tns:GenericAppenderType" minOccurs="0" />
+         <element name="Failover" minOccurs="0">
+            <complexType>
+               <complexContent>
+                  <extension base="tns:GenericAppenderType">
+                     <sequence>
+                        <element name="Failovers">
+                           <complexType>
+                              <sequence>
+                                 <any processContents="lax" />
+                              </sequence>
+                              <anyAttribute processContents="lax" />
+                           </complexType>
+                        </element>
+                     </sequence>
+                  </extension>
+               </complexContent>
+            </complexType>
+         </element>
+         <element name="FailOnce" type="tns:GenericAppenderType" minOccurs="0" />
+         <element name="Hanging" type="tns:GenericAppenderType" minOccurs="0" />
+         <element name="List" type="tns:GenericAppenderType" minOccurs="0" />
+      </sequence>
+   </complexType>
+
+   <complexType name="AbstractAppenderType" abstract="true">
+      <sequence>
+         <sequence>
+            <element name="Property" type="tns:PropertyType" minOccurs="0" maxOccurs="unbounded" />
+         </sequence>
+         <choice minOccurs="0">
+            <element name="Layout" type="tns:LayoutType" />
+            <element name="CsvParameterLayout" type="tns:JCsvParameterLayoutType" />
+            <element name="GelfLayout" type="tns:GelfLayoutType" />
+            <element name="HtmlLayout" type="tns:HtmlLayoutType" />
+            <element name="JsonLayout" type="tns:JsonLayoutType" />
+            <element name="MessageLayout" type="tns:MessageLayoutType" />
+            <element name="PatternLayout" type="tns:PatternLayoutType" />
+            <element name="XmlLayout" type="tns:XmlLayoutType" />
+         </choice>
+         <group ref="tns:FilterChoiceGroup" minOccurs="0" maxOccurs="1" />
+      </sequence>
+      <attribute name="name" type="string" use="required">
+         <annotation>
+            <documentation>The name of the appender.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="ignoreExceptions" type="tns:BooleanType" default="true">
+         <annotation>
+            <documentation>
+               The default is true, causing exceptions encountered while appending events to be internally logged and then ignored.
+               When set to false
+               exceptions will be propagated to the caller, instead.
+               You must set this to false when wrapping this Appender in a FailoverAppender.
+            </documentation>
+         </annotation>
+      </attribute>
+   </complexType>
+
+   <complexType name="AppenderType">
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <attribute name="type" type="string" use="required" />
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="GenericAppenderType">
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="AsyncAppenderType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#ConsoleAppender -->
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <sequence>
+               <element name="AppenderRef" type="tns:AppenderRefType" minOccurs="0" />
+               <choice minOccurs="0" maxOccurs="1">
+                  <element name="ArrayBlockingQueue">
+                     <complexType />
+                  </element>
+                  <element name="DisruptorBlockingQueue">
+                     <complexType />
+                  </element>
+                  <element name="JCToolsBlockingQueue">
+                     <complexType />
+                  </element>
+                  <element name="LinkedTransferQueue">
+                     <complexType />
+                  </element>
+               </choice>
+            </sequence>
+            <attribute name="blocking" type="tns:BooleanType" />
+            <attribute name="bufferSize" type="tns:IntegerType" />
+            <attribute name="error-ref" type="string" />
+            <attribute name="includeLocation" type="tns:BooleanType" />
+            <attribute name="shutdownTimeout" type="tns:IntegerType" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="ConsoleAppenderType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#ConsoleAppender -->
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <attribute name="direct" type="tns:BooleanType">
+               <annotation>
+                  <documentation>
+                     Write directly to java.io.FileDescriptor and bypass java.lang.System.out/.err. Can give up to 10x performance boost when the
+                     output is redirected to file or other process. Cannot be used with Jansi on Windows. Cannot be used with follow.
+                  </documentation>
+               </annotation>
+            </attribute>
+            <attribute name="follow" type="tns:BooleanType">
+               <annotation>
+                  <documentation>
+                     Identifies whether the appender honors reassignments of System.out or System.err via System.setOut or System.setErr made after
+                     configuration. Note that the follow attribute cannot be used with Jansi on Windows. Cannot be used with direct.
+                  </documentation>
+               </annotation>
+            </attribute>
+            <attribute name="target">
+               <annotation>
+                  <documentation>Default is SYSTEM_OUT.</documentation>
+               </annotation>
+               <simpleType>
+                  <restriction base="string">
+                     <enumeration value="SYSTEM_ERR" />
+                     <enumeration value="SYSTEM_OUT" />
+                  </restriction>
+               </simpleType>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="FlumeAppenderType">
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <sequence>
+               <element name="Agent" minOccurs="1" maxOccurs="unbounded">
+                  <complexType>
+                     <attribute name="host" type="string" />
+                     <attribute name="port" type="tns:IntegerType" />
+                  </complexType>
+               </element>
+               <element name="RFC5424Layout">
+                  <complexType>
+                     <anyAttribute processContents="lax" />
+                  </complexType>
+               </element>
+            </sequence>
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="JeroMQAppenderType">
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="JMSAppenderType">
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="RewriteAppenderType">
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <sequence>
+               <choice>
+                  <element name="MapRewritePolicy">
+                     <complexType>
+                        <sequence>
+                           <element name="KeyValuePair" type="tns:KeyValuePairType" maxOccurs="unbounded">
+                              <annotation>
+                                 <documentation>
+                                    One or more KeyValuePair elements that define the matching value for the key and the Level to evaluate when the
+                                    key
+                                    matches.
+                                 </documentation>
+                              </annotation>
+                           </element>
+                        </sequence>
+                     </complexType>
+                  </element>
+                  <element name="PropertiesRewritePolicy">
+                     <complexType>
+                        <sequence>
+                           <element name="Property" type="tns:PropertyType" maxOccurs="unbounded" />
+                        </sequence>
+                     </complexType>
+                  </element>
+               </choice>
+               <element name="AppenderRef" type="tns:AppenderRefType" minOccurs="0" />
+            </sequence>
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="RoutingAppenderType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#RoutingAppender -->
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <sequence>
+               <element name="Script" minOccurs="0">
+                  <complexType mixed="true">
+                     <sequence minOccurs="0">
+                        <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                     </sequence>
+                     <anyAttribute processContents="lax" />
+                  </complexType>
+               </element>
+               <element name="Routes">
+                  <complexType>
+                     <sequence>
+                        <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                     </sequence>
+                     <anyAttribute processContents="lax" />
+                  </complexType>
+               </element>
+               <element name="IdlePurgePolicy" minOccurs="0">
+                  <complexType>
+                     <sequence>
+                        <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                     </sequence>
+                     <anyAttribute processContents="lax" />
+                  </complexType>
+               </element>
+            </sequence>
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="SMTPAppenderType">
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="AbstractFileAppenderType" abstract="true">
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <attribute name="append" type="tns:BooleanType" default="true">
+               <annotation>
+                  <documentation>
+                     When true, records will be appended to the end of the file.
+                     When set to false, the file will be cleared before new records are
+                     written.
+                  </documentation>
+               </annotation>
+            </attribute>
+            <attribute name="advertise" type="tns:BooleanType" />
+            <attribute name="advertiseURI" type="string" />
+            <attribute name="fileName" type="string">
+               <annotation>
+                  <documentation>
+                     The name of the file to write to. If the file, or any of its parent directories, do not exist, they will be created.
+                  </documentation>
+               </annotation>
+            </attribute>
+            <attribute name="immediateFlush" type="tns:BooleanType" default="true">
+               <annotation>
+                  <documentation>
+                     When set to true, each write will be followed by a flush.
+                     This will guarantee the data is written to disk but could impact
+                     performance.
+                  </documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="RandomAccessFileAppenderType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#RandomAccessFileAppender -->
+      <complexContent>
+         <extension base="tns:AbstractFileAppenderType">
+            <attribute name="bufferedIO" type="tns:BooleanType" default="true">
+               <annotation>
+                  <documentation>
+                     When true, records will be written to a buffer and the data will be written to disk when the buffer is full or, if
+                     immediateFlush is set, when the record is written.
+                     File locking cannot be used with bufferedIO.
+                  </documentation>
+               </annotation>
+            </attribute>
+            <attribute name="bufferSize" type="tns:IntegerType" default="8192">
+               <annotation>
+                  <documentation>When bufferedIO is true, this is the buffer size, the default is 8192 bytes.</documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="FileAppenderType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender -->
+      <complexContent>
+         <extension base="tns:RandomAccessFileAppenderType">
+            <attribute name="createOnDemand" type="tns:BooleanType" default="false">
+               <annotation>
+                  <documentation>
+                     The appender creates the file on-demand. The appender only creates the file when a log event passes all filters and is routed
+                     to this appender.
+                  </documentation>
+               </annotation>
+            </attribute>
+            <attribute name="filePermissions" type="string">
+               <annotation>
+                  <documentation>
+                     File attribute permissions in POSIX format to apply whenever the file is created.
+                     Underlying files system shall support POSIX
+                     file attribute view.
+                  </documentation>
+               </annotation>
+            </attribute>
+            <attribute name="fileOwner" type="tns:BooleanType">
+               <annotation>
+                  <documentation>
+                     File owner to define whenever the file is created.
+                     Underlying files system shall support POSIX file attribute view.
+                  </documentation>
+               </annotation>
+            </attribute>
+            <attribute name="fileGroup" type="tns:BooleanType">
+               <annotation>
+                  <documentation>
+                     File group to define whenever the file is created.
+                     Underlying files system shall support POSIX file attribute view.
+                  </documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="MemoryMappedFileAppenderType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#MemoryMappedFileAppender -->
+      <complexContent>
+         <extension base="tns:AbstractFileAppenderType">
+            <attribute name="regionLength" type="tns:IntegerType">
+               <annotation>
+                  <documentation> The length of the mapped region, defaults to 32 MB (32 * 1024 * 1024 bytes). This parameter must be a value between 256 and
+                     1,073,741,824 (1 GB or 2^30); values outside this range will be adjusted to the closest valid value. Log4j will round the specified value
+                     up to the nearest power of two.
+                  </documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="RollingFileAppenderType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender -->
+      <complexContent>
+         <extension base="tns:FileAppenderType">
+            <sequence>
+               <group ref="tns:TriggeringPolicyChoiceGroup" minOccurs="0" maxOccurs="1" />
+               <choice minOccurs="0">
+                  <element name="DefaultRolloverStrategy" type="tns:DefaultRolloverStrategyType" />
+                  <element name="DirectWriteRolloverStrategy" type="tns:DirectWriteRolloverStrategy" />
+               </choice>
+            </sequence>
+            <attribute name="filePattern" type="string" use="required">
+               <annotation>
+                  <documentation>
+                     The pattern of the file name of the archived log file.
+                     The format of the pattern is dependent on the RolloverPolicy that is
+                     used.
+                  </documentation>
+               </annotation>
+            </attribute>
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="RollingRandomAccessFileAppenderType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender -->
+      <complexContent>
+         <extension base="tns:RollingFileAppenderType"></extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="ScriptAppenderSelectorType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#ScriptAppenderSelector -->
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <sequence>
+               <element name="Script" minOccurs="0">
+                  <complexType mixed="true">
+                     <sequence>
+                        <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                     </sequence>
+                     <anyAttribute processContents="lax" />
+                  </complexType>
+               </element>
+               <element name="AppenderSet" minOccurs="0">
+                  <complexType>
+                     <sequence>
+                        <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                     </sequence>
+                     <anyAttribute processContents="lax" />
+                  </complexType>
+               </element>
+            </sequence>
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="SocketAppenderType">
+      <!-- https://logging.apache.org/log4j/2.x/manual/appenders.html#RollingFileAppender -->
+      <complexContent>
+         <extension base="tns:AbstractAppenderType">
+            <sequence>
+               <element name="SocketOptions" minOccurs="0">
+                  <complexType>
+                     <sequence>
+                        <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                     </sequence>
+                     <anyAttribute processContents="lax" />
+                  </complexType>
+               </element>
+               <element name="Ssl" minOccurs="0">
+                  <complexType>
+                     <sequence>
+                        <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+                     </sequence>
+                     <anyAttribute processContents="lax" />
+                  </complexType>
+               </element>
+            </sequence>
+            <anyAttribute processContents="lax" />
+         </extension>
+      </complexContent>
+   </complexType>
+
+
+   <!--
+    ================================================================================================================================
+    TriggeringPolicy types
+    ================================================================================================================================
+    -->
+   <group name="TriggeringPolicyChoiceGroup">
+      <choice>
+         <element name="Policies">
+            <complexType>
+               <group ref="tns:TriggeringPolicyChoiceGroup" minOccurs="0" maxOccurs="unbounded" />
+            </complexType>
+         </element>
+         <element name="CronTriggeringPolicy" type="tns:CronTriggeringPolicyType" />
+         <element name="OnStartupTriggeringPolicy" type="tns:OnStartupTriggeringPolicyType" />
+         <element name="SizeBasedTriggeringPolicy" type="tns:SizeBasedTriggeringPolicyType" />
+         <element name="TimeBasedTriggeringPolicy" type="tns:TimeBasedTriggeringPolicyType" />
+      </choice>
+   </group>
+
+   <complexType name="CronTriggeringPolicyType">
+      <attribute name="schedule" type="string">
+         <annotation>
+            <documentation>The cron expression. The expression is the same as what is allowed in the Quartz scheduler.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="evaluateOnStartup" type="tns:BooleanType">
+         <annotation>
+            <documentation>
+               On startup the cron expression will be evaluated against the file's last modification timestamp. If the cron expression indicates a
+               rollover should have occurred between that time and the current time the file will be immediately rolled over.
+            </documentation>
+         </annotation>
+      </attribute>
+   </complexType>
+
+   <complexType name="OnStartupTriggeringPolicyType">
+      <attribute name="minSize" type="tns:IntegerType" default="1">
+         <annotation>
+            <documentation>
+               The minimum size the file must have to roll over. A size of zero will cause a roll over no matter what the file size is. The default
+               value is 1, which will prevent rolling over an empty file.
+            </documentation>
+         </annotation>
+      </attribute>
+   </complexType>
+
+   <complexType name="SizeBasedTriggeringPolicyType">
+      <attribute name="size" type="string" use="required">
+         <annotation>
+            <documentation>
+               The size can be specified in bytes, with the suffix KB, MB or GB, for example 20MB.
+            </documentation>
+         </annotation>
+      </attribute>
+   </complexType>
+
+   <complexType name="TimeBasedTriggeringPolicyType">
+      <attribute name="interval" type="tns:IntegerType" default="1">
+         <annotation>
+            <documentation>
+               How often a rollover should occur based on the most specific time unit in the date pattern.
+            </documentation>
+         </annotation>
+      </attribute>
+      <attribute name="modulate" type="tns:BooleanType" default="false">
+         <annotation>
+            <documentation>
+               Indicates whether the interval should be adjusted to cause the next rollover to occur on the interval boundary.
+            </documentation>
+         </annotation>
+      </attribute>
+      <attribute name="maxRandomDelay" type="tns:IntegerType" default="0">
+         <annotation>
+            <documentation>
+               Indicates the maximum number of seconds to randomly delay a rollover. By default, this is 0 which indicates no delay.
+            </documentation>
+         </annotation>
+      </attribute>
+   </complexType>
+
+
+   <!--
+    ================================================================================================================================
+    RolloverStrategy types
+    ================================================================================================================================
+    -->
+   <complexType name="DefaultRolloverStrategyType">
+      <choice minOccurs="0" maxOccurs="unbounded">
+         <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+      </choice>
+      <attribute name="compressionLevel" type="tns:IntegerType">
+         <annotation>
+            <documentation>
+               Sets the compression level, 0-9, where 0 = none, 1 = best speed, through 9 = best compression. Only implemented for ZIP files.
+            </documentation>
+         </annotation>
+      </attribute>
+      <attribute name="fileIndex" default="max">
+         <annotation>
+            <documentation>
+               If set to "max", files with a higher index will be newer than files with a smaller index.
+               If set to "min", file renaming and the
+               counter will follow the Fixed Window strategy described above.
+            </documentation>
+         </annotation>
+         <simpleType>
+            <restriction base="string">
+               <enumeration value="max" />
+               <enumeration value="nomax" />
+               <enumeration value="min" />
+            </restriction>
+         </simpleType>
+      </attribute>
+      <attribute name="max" type="tns:IntegerType" default="7">
+         <annotation>
+            <documentation>
+               The maximum value of the counter. Once this values is reached older archives will be deleted on subsequent rollovers.
+            </documentation>
+         </annotation>
+      </attribute>
+      <attribute name="min" type="tns:IntegerType" default="1">
+         <annotation>
+            <documentation>The minimum value of the counter.</documentation>
+         </annotation>
+      </attribute>
+      <attribute name="stopCustomActionsOnError" type="tns:BooleanType" />
+      <attribute name="tempCompressedFilePattern" type="string">
+         <annotation>
+            <documentation>The pattern of the file name of the archived log file during compression.</documentation>
+         </annotation>
+      </attribute>
+   </complexType>
+
+   <complexType name="DirectWriteRolloverStrategy">
+      <sequence>
+         <any processContents="lax" minOccurs="0" maxOccurs="unbounded" />
+      </sequence>
+      <attribute name="compressionLevel" type="tns:IntegerType">
+         <annotation>
+            <documentation>
+               Sets the compression level, 0-9, where 0 = none, 1 = best speed, through 9 = best compression. Only implemented for ZIP files.
+            </documentation>
+         </annotation>
+      </attribute>
+      <attribute name="maxFiles" type="tns:IntegerType" default="7">
+         <annotation>
+            <documentation>
+               The maximum number of files to allow in the time period matching the file pattern. If the number of files is exceeded the oldest file
+               will be deleted. If specified, the value must be greater than 1. If the value is less than zero or omitted then the number of files will not be
+               limited.
+            </documentation>
+         </annotation>
+      </attribute>
+      <attribute name="tempCompressedFilePattern" type="string">
+         <annotation>
+            <documentation>The pattern of the file name of the archived log file during compression.</documentation>
+         </annotation>
+      </attribute>
+   </complexType>
+
+
+   <!--
+    ================================================================================================================================
+    <Configuration><Loggers> type and related types
+    ================================================================================================================================
+    -->
+   <complexType name="LoggersType" mixed="true">
+      <choice minOccurs="0" maxOccurs="unbounded">
+         <element name="Root" type="tns:RootType" />
+         <element name="AsyncRoot" type="tns:AsyncRootType" />
+         <element name="Logger" type="tns:LoggerType" />
+         <element name="AsyncLogger" type="tns:AsyncLoggerType" />
+      </choice>
+   </complexType>
+
+   <complexType name="LoggerType">
+      <sequence>
+         <group ref="tns:FilterChoiceGroup" minOccurs="0" maxOccurs="1" />
+         <choice minOccurs="0" maxOccurs="unbounded">
+            <element name="Property" type="tns:PropertyType" />
+            <element name="AppenderRef" type="tns:AppenderRefType" />
+         </choice>
+      </sequence>
+      <attribute name="additivity" type="tns:BooleanType" />
+      <attribute name="level" type="string" />
+      <attribute name="name" type="string" use="required" />
+      <attribute name="includeLocation" type="tns:BooleanType" />
+   </complexType>
+
+   <complexType name="AsyncLoggerType">
+      <complexContent>
+         <extension base="tns:LoggerType"></extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="RootType">
+      <choice minOccurs="0" maxOccurs="unbounded">
+         <element name="Property" type="tns:PropertyType" />
+         <element name="AppenderRef" type="tns:AppenderRefType" />
+      </choice>
+      <attribute name="additivity" type="tns:BooleanType" />
+      <attribute name="level" type="string" />
+      <attribute name="includeLocation" type="tns:BooleanType" />
+   </complexType>
+
+   <complexType name="AsyncRootType">
+      <complexContent>
+         <extension base="tns:RootType"></extension>
+      </complexContent>
+   </complexType>
+
+   <complexType name="AppenderRefType">
+      <group ref="tns:FilterChoiceGroup" minOccurs="0" maxOccurs="1" />
+      <attribute name="level" type="string" />
+      <attribute name="ref" type="string" use="required" />
+   </complexType>
+
+
+   <!--
+    ================================================================================================================================
+    Reusable Simple Types for Attributes
+    ================================================================================================================================
+    -->
+   <complexType name="KeyValuePairType">
+      <simpleContent>
+         <extension base="string">
+            <attribute name="key" type="string" use="required" />
+            <attribute name="value" type="string" use="required" />
+         </extension>
+      </simpleContent>
+   </complexType>
+
+   <complexType name="PropertyType">
+      <simpleContent>
+         <extension base="string">
+            <attribute name="name" type="string" use="required" />
+            <attribute name="value" type="string" />
+         </extension>
+      </simpleContent>
+   </complexType>
+
+   <simpleType name="BooleanType">
+      <annotation>
+         <documentation>Allow boolean values or variable place holders in the form of ${variablename}</documentation>
+      </annotation>
+      <restriction base="string">
+         <pattern value="(true|false|\$\{[^{}]+\})" />
+      </restriction>
+   </simpleType>
+
+   <simpleType name="IntegerType">
+      <annotation>
+         <documentation>Allow long values or variable place holders in the form of ${variablename}</documentation>
+      </annotation>
+      <restriction base="string">
+         <pattern value="-?([0-9]+|\$\{[^{}]+\})" />
+      </restriction>
+   </simpleType>
+</schema>
diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
new file mode 100644
index 0000000..29fe9e6
--- /dev/null
+++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/config/xml/XmlSchemaTest.java
@@ -0,0 +1,132 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.core.config.xml;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.xml.XMLConstants;
+import javax.xml.transform.sax.SAXSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.mutable.MutableInt;
+import org.junit.Assert;
+import org.junit.Test;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.XMLFilterImpl;
+import org.xml.sax.helpers.XMLReaderFactory;
+
+public class XmlSchemaTest {
+
+    private static final String TARGET_NAMESPACE = "http://logging.apache.org/log4j/2.0/config";
+
+    private static final List<String> IGNORE_CONFIGS = Arrays.asList( //
+            "gcFreeLogging.xml", // has 2 <Pattern> tags defined
+            "legacy-plugins.xml", //
+            "logback", // logback configs
+            "log4j-xinclude", //
+            "log4j12", // log4j 1.x configs
+            "perf-CountingNoOpAppender.xml", // uses test-appender CountingNoOp
+            "reconfiguration-deadlock.xml", // uses test-appender UsesLoggingAppender
+            "XmlConfigurationSecurity.xml" //
+    );
+
+    private static String capitalizeTags(final String xml) {
+        final StringBuffer sb = new StringBuffer();
+        final Matcher m = Pattern.compile("([<][/]?[a-z])").matcher(xml);
+        while (m.find()) {
+            m.appendReplacement(sb, m.group(1).toUpperCase());
+        }
+        return m.appendTail(sb).toString();
+    }
+
+    private static String fixXml(String xml) {
+        xml = StringUtils.replace(xml, "JSONLayout", "JsonLayout");
+        xml = StringUtils.replace(xml, "HTMLLayout", "HtmlLayout");
+        xml = StringUtils.replace(xml, "XMLLayout", "XmlLayout");
+        xml = StringUtils.replace(xml, "appender-ref", "AppenderRef");
+        xml = StringUtils.replace(xml, " onmatch=", " onMatch=");
+        xml = StringUtils.replace(xml, " onMisMatch=", " onMismatch=");
+        xml = StringUtils.replace(xml, " onmismatch=", " onMismatch=");
+        xml = StringUtils.replace(xml, "<Marker ", "<MarkerFilter ");
+        xml = StringUtils.replace(xml, " Value=", " value=");
+        xml = capitalizeTags(xml);
+        return xml;
+    }
+
+    @Test
+    public void testXmlSchemaValidation() throws SAXException, IOException {
+        final SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
+        final Schema schema = factory.newSchema(new StreamSource(new File("src/main/resources/Log4j-config.xsd")));
+        final Validator validator = schema.newValidator();
+
+        final XMLFilterImpl namespaceAdder = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
+            @Override
+            public void startElement(final String namespace, final String localName, final String qName,
+                    final Attributes atts) throws SAXException {
+                super.startElement(TARGET_NAMESPACE, localName, qName, atts);
+            }
+        };
+
+        final MutableInt configs = new MutableInt();
+        final MutableInt failures = new MutableInt();
+
+        Files.list(Paths.get("src/test/resources")) //
+                .filter(filePath -> {
+                    final String fileName = filePath.getFileName().toString();
+                    if (!fileName.endsWith(".xml"))
+                        return false;
+                    for (final String ignore : IGNORE_CONFIGS) {
+                        if (fileName.contains(ignore))
+                            return false;
+                    }
+                    return true;
+                }) //
+                .forEach(filePath -> {
+                    System.out.println("Validating " + configs.incrementAndGet() + ". [" + filePath + "]...");
+                    System.out.flush();
+
+                    try {
+                        final String xml = fixXml(
+                                FileUtils.readFileToString(filePath.toFile(), Charset.defaultCharset()));
+                        validator.validate(new SAXSource(namespaceAdder,
+                                new InputSource(new ByteArrayInputStream(xml.getBytes()))), null);
+                    } catch (final Exception ex) {
+                        System.err.println(ex);
+                        System.err.flush();
+                        failures.increment();
+                    }
+                });
+
+        Assert.assertEquals(0, failures.intValue());
+    }
+}