The current idea I have is that the XML Schema would reflect exactly the code that is running. We should start with that. AFAIK, the current code we have does not allow open-ended XML fragments, but I could be wrong...
Gary On Mon, Oct 14, 2013 at 10:25 AM, <alexander.rat...@materna.de> wrote: > So basically when you want strict validation you want it really strict, i.e. > not only for the base types like appenders, filters but also their attributes? > As far as I understand that would result in a bigger schema where each type > is defined in the schema and the config looks more like the non-strict > version. > User supplied types would be impossible then, unless they are defined as a > generic type in the schema which allows for KeyValuePairs or such (like I did > in the edited schema below). > > Best Regards, > Alex > > > > -----Ursprüngliche Nachricht----- > Von: Gary Gregory [mailto:garydgreg...@gmail.com] > Gesendet: Montag, 14. Oktober 2013 16:18 > An: Log4J Users List > Betreff: Re: Log4j2 Appender attributes with strict xml config > > 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.rat...@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.rat...@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#getConfigura >> tion(org.apache.logging.log4j.core.config.ConfigurationFactory.Configu >> rationSource) >> >> */ >> >> @Override >> >> public Configuration getConfiguration(ConfigurationSource >> source) { >> >> return new StrictXMLConfiguration(source); >> >> } >> >> >> >> >> >> /** >> >> * @see >> org.apache.logging.log4j.core.config.ConfigurationFactory#getSupported >> Types() >> >> */ >> >> @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.Configuratio >> nSource; >> >> >> >> >> >> /** >> >> * 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.rat...@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.rat...@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: garydgreg...@gmail.com | ggreg...@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-unsubscr...@logging.apache.org > For additional commands, e-mail: log4j-user-h...@logging.apache.org > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: log4j-user-unsubscr...@logging.apache.org > For additional commands, e-mail: log4j-user-h...@logging.apache.org > -- E-Mail: garydgreg...@gmail.com | ggreg...@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-unsubscr...@logging.apache.org For additional commands, e-mail: log4j-user-h...@logging.apache.org