Uploaded image for project: 'logback'
  1. logback
  2. LOGBACK-934

Fix inconsistencies in XML syntax for logback.xml

    XMLWordPrintable

Details

    • Icon: Improvement Improvement
    • Resolution: Unresolved
    • Icon: Major Major
    • None
    • 1.0.13
    • logback-core
    • None

    Description

      For my local work I have created a namespace aware XSD schema describing almost the full syntax of logback.xml configuration files (to be able to use my IDE's auto-completion and validation features when editing logback.xml configuration files).

      My XSD schema does explicitly NOT include all the bean properties for already existing Appender, Encoder, ... implementations, because this would be inconsistent as soon as I add my own Appender and Encoder implementations with totally different properties.

      However, while writing the XSD I've found a subtle problem:

      Some XML elements (appender, encoder, layout, ...) take a "class" attribute to specify the implementing class, and additional XML child elements to specify the values for the JavaBeans properties which are valid for these impl classes.

      This approach is not bad at all, but at least for the "appender" element your current syntax description raises a problem. Take the following scenario:

      public class ClusteredAppender implements Appender {
        private String layout; // can be "LOADBALANCED or "ROUNDROBIN"
        public void setLayout(String layout) { ... };
        public String getLayout() { ... };
        ...
      }
      <appender name="my" class="ClusteredAppender">
        <layout>ROUNDROBIN</layout>
      </appender>

      According to your description of the XML syntax, an XML parser has no chance to know if this layout XML element is meant to be "your" layout element (refering to a layout implementation class), or if it means to be a bean property of my own ClusteredAppender implementation.

      With the currently provided standard implementations for layouts, encoders, appenders etc. this problem does not occur (because there are no problematic bean property names), but what if I want to create my own implementations? I do not want to take care of bean property names that I must not use because of naming conflicts...

      You could argue that I should not use bean names that conflict with other pre-defined XML elements, but:

      • This would be a very stupid limitation, because when I introduce my own bean property "maxProcessingTime", it would cause naming conflicts as soon as you introduce the same XML element one day.
      • When creating the XML schema representing your current syntax description, the XML schema processor immediately finds the ambiguity and complains about it:
        <xsd:complexType name="appender">
          <xsd:sequence>
            <xsd:element name="layout" type="layout" minOccurs="0" />
            <xsd:element name="encoder" type="encoder" minOccurs="0" maxOccurs="unbounded" />
            <xsd:element name="filter" type="filter" minOccurs="0" maxOccurs="unbounded" />
            <xsd:any processContents="skip" minOccurs="0" maxOccurs="unbounded" />
          </xsd:sequence>
          <xsd:attribute name="name" type="xsd:ID" use="required" />
          <xsd:attribute name="class" type="className" use="required" />
        </xsd:complexType>
      >> cos-nonambig: "http://logback.qos.ch/":layout and WC[##any] (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.

      For my local work I have found a workaround for this by introducing a separate namespace for all the bean properties, which eventually leads to a slightly modified XSD schema file and the following form of configuration files:

      <?xml version="1.0" encoding="UTF-8"?>
      <configuration xmlns="http://logback.qos.ch/"
                     xmlns:attr="http://logback.qos.ch/beanAttributes"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://logback.qos.ch/ logback.xsd">
        <appender name="CLUSTER" class="ClusteredAppender">
          <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>...</pattern>
          </layout>
          <attr:layout>ROUNDROBIN</attr:layout>
        </appender>
        ...
      </configuration>

      Note the "attr:" prefix for my own layout element. This way I can distinguish a "layout" element that is part of your common XSD schema from "layout" elements that contains a value for an attribute of the my appender class.

      However, this isn't a nice workaround, and I would propose a different syntax for logback.xml to define class specific properties, maybe something like this:

      <?xml version="1.0" encoding="UTF-8"?>
      <configuration xmlns="http://logback.qos.ch/"
                     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                     xsi:schemaLocation="http://logback.qos.ch/ logback.xsd">
        <appender name="CLUSTER" class="ClusteredAppender">
          <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>...</pattern>
          </layout>
          <beanProperties>
            <layout>ROUNDROBIN</layout>
          </beanProperties>
        </appender>
        ...
      </configuration>

      This way all impl-class specific XML elements are children of the beanProperties element, so there are no ambiguities anymore. The XSD schema description for this construct will also be absolutely valid.

      Of course this does not only apply to the Appender / Layout example, but to all the XML elements where custom bean properties can be defined via XML child elements.

      Attachments

        Activity

          People

            logback-dev Logback dev list
            spalme Stefan Palme
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: