logging-log4j-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gary Gregory <garydgreg...@gmail.com>
Subject Re: Log4j2 Appender attributes with strict xml config
Date Mon, 14 Oct 2013 14:17:42 GMT
Alexander ,

XML validation against the XML Schema is not fully baked because the
Log4j 2 XML Schema is incomplete. Due to the current dynamic nature of
the configuration file (it's schema is tied to the Java code and the
annotations used), we need to generate the XML Schema based on these
annotations in the same way that the annotations are currently
processed to create the metadata configuration.

Simone had proposed a different to do configuration, but that has not
gone anywhere yet, and I am not sure it dealt with XML validation.

Gary

On Mon, Oct 14, 2013 at 10:09 AM,  <Alexander.Rathai@materna.de> wrote:
> Hi,
> I'm using log4j2-beta9 and want to configure it using a log4j2.xml in strict mode. My
issue is: how do I specify attributes that are not in the shipped schema file? An Example:
> <?xml version="1.0" encoding="UTF-8" ?>
> <Configuration
>     status="DEBUG"
>     strict="true"
>     monitorInterval="5"
>     name="TestingAttributes"
>     verbose="true"
>     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>     xsi:noNamespaceSchemaLocation="Log4j-config.xsd">
>     <Properties>
>     </Properties>
>     <Appenders>
>         <Appender
>             type="Console"
>             name="SYSERR"
>             target="SYSTEM_ERR"> <!-- cvc-complex-type.3.2.2: Attribute 'target'
is not allowed to appear in element 'Appender'. -->
>             <Layout Type="PatternLayout">
>                 <Pattern>%date{dd.MM.yyyy HH:mm:ss,SSS} %5p %logger %m%n</Pattern>
>             </Layout>
>             <Filters>
>                 <Filter
>                     type="MarkerFilter"
>                     marker="FLOW"
>                     onMatch="DENY"
>
>                     onMismatch="NEUTRAL" />
>                 <Filter
>                     type="MarkerFilter"
>                     marker="EXCEPTION"
>                     onMatch="DENY"
>                     onMismatch="NEUTRAL" />
>             </Filters>
>         </Appender>
>     </Appenders>
>     <Loggers>
>         <Root level="debug">
>             <AppenderRef ref="SYSERR" />
>         </Root>
>     </Loggers>
> </Configuration>
> Notice that I want to set the appender to have the target SYSTEM_ERR but the attribute
is not allowed in strict mode.
> target="SYSTEM_ERR"> <!-- cvc-complex-type.3.2.2: Attribute 'target' is not allowed
to appear in element 'Appender'. -->
> I could always edit the Log4j-config.xsd and allow that attribute there but that would
be kind of wrong also because not all appenders have a target attribute.
> As searching the web didn't help me so far, I'm asking you: Is there anything I'm missing
in configuring Log4j2 in strict XML mode?
>
> I am for now using the following classes as a workaround:
>
>
>
>     import org.apache.logging.log4j.core.config.*;
>
>     import org.apache.logging.log4j.core.config.plugins.*;
>
>
>
>
>
>     /**
>
>      * Simple ConfigurationFactory that returns a {@link StrictXMLConfigurationFactory}
>
>      *
>
>      * @author <a href="mailto:Alexander.Rathai@Materna.DE">Alexander Rathai</a>
>
>      */
>
>     @Plugin(name = "StrictXMLConfigurationFactory", category = "ConfigurationFactory")
>
>     @Order(4)
>
>     public class StrictXMLConfigurationFactory extends ConfigurationFactory {
>
>
>
>             /**
>
>              * Valid file extensions for XML files.
>
>              */
>
>             public static final String[] SUFFIXES = new String[]{".xml"};
>
>
>
>
>
>             /**
>
>              * @see org.apache.logging.log4j.core.config.ConfigurationFactory#getConfiguration(org.apache.logging.log4j.core.config.ConfigurationFactory.ConfigurationSource)
>
>              */
>
>             @Override
>
>             public Configuration getConfiguration(ConfigurationSource source) {
>
>                     return new StrictXMLConfiguration(source);
>
>             }
>
>
>
>
>
>             /**
>
>              * @see org.apache.logging.log4j.core.config.ConfigurationFactory#getSupportedTypes()
>
>              */
>
>             @Override
>
>             public String[] getSupportedTypes() {
>
>                     return XMLConfigurationFactory.SUFFIXES;
>
>             }
>
>     }
>
>
>
> And
>
>
>
>     import java.util.*;
>
>
>
>     import org.apache.logging.log4j.core.config.*;
>
>     import org.apache.logging.log4j.core.config.ConfigurationFactory.ConfigurationSource;
>
>
>
>
>
>     /**
>
>      * Lets the base class {@link XMLConfiguration} do all the hard work and patch the
object tree before it is being used by {@link BaseConfiguration}
>
>      *
>
>      * @author <a href="mailto:Alexander.Rathai@Materna.DE">Alexander Rathai</a>
>
>      */
>
>     public class StrictXMLConfiguration extends XMLConfiguration {
>
>
>
>             /**
>
>              * @param configSource
>
>              */
>
>             public StrictXMLConfiguration(ConfigurationSource configSource) {
>
>                     super(configSource);
>
>             }
>
>
>
>
>
>             /**
>
>              * @see org.apache.logging.log4j.core.config.XMLConfiguration#setup()
>
>              */
>
>             @Override
>
>             public void setup() {
>
>                     super.setup();
>
>                     alterHierarchy(this.rootNode);
>
>             }
>
>
>
>
>
>             /**
>
>              * Recourses the object tree and puts replaces KeyValuePairs as attributes
in the parent object
>
>              *
>
>              * @param node the node to alter
>
>              */
>
>             private void alterHierarchy(final Node node) {
>
>                     final List<Node> children = node.getChildren();
>
>     //                final ArrayList<Node> usedChilds = new ArrayList<>();
>
>                     Map<String, String> attributes = node.getAttributes();
>
>                     for( Node child : children ) {
>
>                             if( "KeyValuePair".equalsIgnoreCase(child.getName()) ) {
>
>                                     String key = child.getAttributes().get("key");
>
>                                     String value = child.getValue();
>
>                                     attributes.put(key, value);
>
>     //                                usedChilds.add(child);
>
>                             }
>
>                             else {
>
>                                     alterHierarchy(child);
>
>                             }
>
>                     }
>
>     //                children.removeAll(usedChilds);
>
>             }
>
>     }
>
>
>
> And i patched the xsd a bit:
>
>
>
>     <?xml version="1.0" encoding="UTF-8"?>
>
>     <!--
>
>      Licensed to the Apache Software Foundation (ASF) under one or more
>
>      contributor license agreements.  See the NOTICE file distributed with
>
>      this work for additional information regarding copyright ownership.
>
>      The ASF licenses this file to You under the Apache License, Version 2.0
>
>      (the "License"); you may not use this file except in compliance with
>
>      the License.  You may obtain a copy of the License at
>
>
>
>           http://www.apache.org/licenses/LICENSE-2.0
>
>
>
>      Unless required by applicable law or agreed to in writing, software
>
>      distributed under the License is distributed on an "AS IS" BASIS,
>
>      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
>
>      See the License for the specific language governing permissions and
>
>      limitations under the License.
>
>
>
>      Altered by <a href="mailto:Alexander.Rathai@Materna.DE">Alexander Rathai</a>:
>
>      Tweaked minOccurs maxOccurs and some other things
>
>      Allowed KeyValuePairType to appear inside AppenderType
>
>
>
>     -->
>
>     <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
attributeFormDefault="unqualified">
>
>         <xs:element name="Configuration" type="ConfigurationType"/>
>
>         <xs:complexType name="ConfigurationType">
>
>             <xs:sequence>
>
>                 <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="dest" type="xs:string"/>
>
>             <xs:attribute name="advertiser" type="xs:string"/>
>
>             <xs:attribute name="monitorInterval" type="xs:int"/>
>
>             <xs:attribute name="name" type="xs:string"/>
>
>             <xs:attribute name="packages" type="xs:string"/>
>
>             <xs:attribute name="schema" type="xs:string"/>
>
>             <xs:attribute name="shutdownHook" type="xs:boolean"/>
>
>             <xs:attribute name="status" type="xs:string"/>
>
>             <xs:attribute name="strict" type="xs:string"/>
>
>             <xs:attribute name="verbose" type="xs:boolean"/>
>
>         </xs:complexType>
>
>         <xs:complexType name="PropertiesType">
>
>             <xs:sequence>
>
>                 <xs:element name="Property" type="PropertyType" minOccurs="1" maxOccurs="unbounded"/>
>
>             </xs:sequence>
>
>         </xs:complexType>
>
>         <xs:complexType name="AppenderType">
>
>             <xs:sequence>
>
>                 <xs:element name="KeyValuePair" type="KeyValuePairType" minOccurs="0"
maxOccurs="unbounded"/>
>
>                 <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="1" maxOccurs="unbounded"/>
>
>             </xs:sequence>
>
>         </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"/>
>
>             </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="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>
>
>
>
> Then I set the Systemproperty `log4j.configurationFactory` to the fully qualified classname
of the StrictXMLConfigurationFactory and it works really well!
>
> Best Regards,
> Alex
>
> Alexander Rathai
> ___________________________________________
> MATERNA GmbH Information & Communications
> Voßkuhle 37 * 44141 Dortmund * Germany
> Amtsgericht Dortmund * HRB 5839
> Geschäftsführer: Dr. Winfried Materna, Helmut an de Meulen, Ralph Hartwig
> Tel: +49 (231) 5599-8622
> http://www.materna.de<http://www.materna.de/>
>



-- 
E-Mail: garydgregory@gmail.com | ggregory@apache.org
Java Persistence with Hibernate, Second Edition
JUnit in Action, Second Edition
Spring Batch in Action
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-user-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-user-help@logging.apache.org


Mime
View raw message