Log4j 2.x XSD的描述不完整
在博客文章JAXB和Log4j XML配置文件中 ,我討論了“與使用JAXB通過Java類處理[Log4j 1.x和Log4j 2.x] XML配置文件相關的細微差別。” 在本文中,我將探討另一個與通過Log4j 2.x XML Schema文件Log4j-config.xsd生成的JAXB對象生成Log4j 2.x配置XML相關的挑戰:它沒有完全指定Log4j 2.x組件的配置特點。
使用Log4j 2.x XML配置時 ,首先要做出的重要區別之一是要使用XML的“ 風味 ”(“簡潔”或“嚴格”)。 簡潔的格式可能更容易,因為XML元素的名稱對應于它們表示的Log4j 2組件,但是XSD僅支持嚴格格式。 這意味著從Log4j 2.x XSD生成的JAXB對象中編組的任何XML都必須具有“嚴格”格式,而不是“簡潔”格式。
不幸的是,當前與Log4j 2.x發行版一起提供的XSD( Log4j-config.xsd )不足以生成Log4j 2支持的完整“嚴格” XML配置。我在這里通過討論XSD定義的復雜類型來演示這一點。 “ AppenderType ”,因為它是受支持元素在XSD中缺少其潛在屬性規范的最極端情況之一。 從Log4j 2.6.2開始,下面的代碼清單顯示了Log4j-config.xsd中AppenderType的定義。
在Log4j 2.6.2的Log4j-config.xsd定義的AppenderType
<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>剛剛顯示的XSD的摘錄告訴我們,以XSD兼容的XML描述的附加器將只能具有三個屬性( type , name和fileName )中的一個或多個。 “ type ”屬性用于標識其附加器的類型(例如“ File ”,“ RollingFile ”,“ Console ”,“ Socket ”和“ Syslog ”)。 問題在于,每個追加程序的“類型”都有不同的屬性和特性,理想情況下,可以通過此AppenderType上的屬性來描述。
有關Appender的Log4j 2.x文檔列出了不同類型的附加程序的特征。 例如,此頁面指示ConsoleAppender具有七個參數: filter , layout , follow , direct , name , ignoreExceptions和target 。 該name是由一般所支持的屬性之一AppenderType復雜類型和filter和layout通過在嵌套的元件支撐AppenderType 。 但是,可用于ConsoleAppender的其他四個參數在XSD中沒有規定定義它們的機制。
甚至不考慮自定義Log4j 2.x附加程序 , 內置的Log4j 2.x附加程序不會共享相同的屬性和特征,并且大多數屬性具有比AppenderType指定的三個屬性和兩個嵌套元素更多的特征。 我討論的七個參數的控制臺追加程序以前和其他例子包括RollingFileAppender進行其12個參數( append , bufferedIO , bufferSize , filter , fileName , filePattern , immediateFlush , layout , name , policy , strategy , ignoreExceptions )的JDBCAppender與七個參數( name , ignoreExceptions , filter , bufferSize , connectionSource , tableName , columnConfigs )和JMSAppender及其十三個參數( factoryBindingName , factoryName , filter , layout , name , password , providerURL , destinationBindingName , securityPrincipalName , securityCredentials , ignoreExceptions , urlPkgPrefixes , userName )。
為了描述XSD中給定的附加器類型可用的每個參數,都需要XML Schema具備以下能力:編寫一組特定的可用屬性取決于AppenderType的type屬性的設置。 不幸的是,XML Schema不容易支持這種條件規范,在該條件規范中,給定復雜類型的可用屬性基于復雜類型的其他屬性之一而不同。
由于模式語言的局限性,想要使用JAXB生成對所有提供的附加程序均具有完全支持的對象的人將需要更改XSD。 一種方法是更改??XSD,以使AppenderType具有任何內置附加程序的所有可能屬性,這些附加屬性可用作元素的可選屬性。 最明顯的缺點是,即使該屬性不適用于特定的附加程序類型,XSD也會允許任何附加程序類型具有任何屬性。 但是,這種方法將允許JAXB生成的對象將給定附加類型的所有XML屬性編組起來。 下一個代碼段說明了如何開始。 此處指定了一些不同的追加器所需的其他屬性,但是即使更長的列表也不包含支持所有可能的內置追加器類型的屬性所需的所有可能的追加器屬性。
一些添加到AppenderType Appender屬性
<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"/><!-- Attributes specified below here are not in Log4j 2.x Log4j-config.xsd --><xs:attribute name="target" type="xs:string" use="optional"/><xs:attribute name="follow" type="xs:string" use="optional"/><xs:attribute name="append" type="xs:string" use="optional"/><xs:attribute name="filePattern" type="xs:string" use="optional"/><xs:attribute name="host" type="xs:string" use="optional"/><xs:attribute name="port" type="xs:string" use="optional"/><xs:attribute name="protocol" type="xs:string" use="optional"/><xs:attribute name="connectTimeoutMillis" type="xs:integer" use="optional"/><xs:attribute name="reconnectionDelayMillis" type="xs:string" use="optional"/><xs:attribute name="facility" type="xs:string" use="optional"/><xs:attribute name="id" type="xs:string" use="optional"/><xs:attribute name="enterpriseNumber" type="xs:integer" use="optional"/><xs:attribute name="useMdc" type="xs:boolean" use="optional"/><xs:attribute name="mdcId" type="xs:string" use="optional"/><xs:attribute name="mdcPrefix" type="xs:string" use="optional"/><xs:attribute name="eventPrefix" type="xs:string" use="optional"/><xs:attribute name="newLine" type="xs:boolean" use="optional"/><xs:attribute name="newLineEscape" type="xs:string" use="optional"/> </xs:complexType>更改Log4j 2.x XSD以完全支持所有內置附加程序的第二種方法是將XSD設計從具有由type屬性指定的特定類型的單個AppenderType更改為具有許多不同的復雜類型,每個復雜類型分別表示不同的XSD設計。內置的附加器類型。 使用這種方法,XSD可以強制執行任何給定附加程序的所有屬性,并且僅與該給定附加程序相關聯的屬性。 每個追加程序都具有元素類型的這種方法類似于“簡潔” XML格式的工作方式,但是當前沒有XSD支持。
請注意,我在這里有意專注于內置的附加器類型,因為可以期望靜態XSD能夠合理,充分且完全地支持它。 另外:可以通過為屬性指定任意的名稱/值對來支持此操作,就像對過濾器或參數進行的操作一樣 ,但是這還導致能夠指定多余的甚至是無用的屬性,而架構沒有任何能力來捕獲這些屬性。 支持自定義類型的第三種方法是不使用靜態XSD描述語法,而是使用生成的XSD。 可以根據文檔中Log4j 2.x組件的描述來手寫這樣的XSD,但是更好的方法可能是利用Log4j 2.x中使用的@PluginFactory , @PluginElement和@PluginAttribute注釋。源代碼。 接下來的兩個代碼清單來自Apache Log4j 2.6.2代碼庫,并演示了這些注釋如何描述給定類型的元素和屬性。
ConsoleAppender.createAppender()簽名
@PluginFactory public static ConsoleAppender createAppender(@PluginElement("Layout") Layout layout,@PluginElement("Filter") final Filter filter,@PluginAttribute(value = "target", defaultString = "SYSTEM_OUT") final String targetStr,@PluginAttribute("name") final String name,@PluginAttribute(value = "follow", defaultBoolean = false) final String follow,@PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) final String ignore)SysLogAppender.createAppender()簽名
@PluginFactory public static SyslogAppender createAppender(// @formatter:off@PluginAttribute("host") final String host,@PluginAttribute(value = "port", defaultInt = 0) final int port,@PluginAttribute("protocol") final String protocolStr,@PluginElement("SSL") final SslConfiguration sslConfig,@PluginAttribute(value = "connectTimeoutMillis", defaultInt = 0) final int connectTimeoutMillis,@PluginAliases("reconnectionDelay") // deprecated@PluginAttribute(value = "reconnectionDelayMillis", defaultInt = 0) final int reconnectionDelayMillis,@PluginAttribute(value = "immediateFail", defaultBoolean = true) final boolean immediateFail,@PluginAttribute("name") final String name,@PluginAttribute(value = "immediateFlush", defaultBoolean = true) final boolean immediateFlush,@PluginAttribute(value = "ignoreExceptions", defaultBoolean = true) final boolean ignoreExceptions,@PluginAttribute(value = "facility", defaultString = "LOCAL0") final Facility facility,@PluginAttribute("id") final String id,@PluginAttribute(value = "enterpriseNumber", defaultInt = Rfc5424Layout.DEFAULT_ENTERPRISE_NUMBER) final int enterpriseNumber,@PluginAttribute(value = "includeMdc", defaultBoolean = true) final boolean includeMdc,@PluginAttribute("mdcId") final String mdcId,@PluginAttribute("mdcPrefix") final String mdcPrefix,@PluginAttribute("eventPrefix") final String eventPrefix,@PluginAttribute(value = "newLine", defaultBoolean = false) final boolean newLine,@PluginAttribute("newLineEscape") final String escapeNL,@PluginAttribute("appName") final String appName,@PluginAttribute("messageId") final String msgId,@PluginAttribute("mdcExcludes") final String excludes,@PluginAttribute("mdcIncludes") final String includes,@PluginAttribute("mdcRequired") final String required,@PluginAttribute("format") final String format,@PluginElement("Filter") final Filter filter,@PluginConfiguration final Configuration config,@PluginAttribute(value = "charset", defaultString = "UTF-8") final Charset charsetName,@PluginAttribute("exceptionPattern") final String exceptionPattern,@PluginElement("LoggerFields") final LoggerFields[] loggerFields, @PluginAttribute(value = "advertise", defaultBoolean = false) final boolean advertise)這種方法需要幾個步驟,因為一個人需要使用Log4j 2.x體系結構的主要組成部分的知識以及注釋處理來動態生成XSD,然后使用JAXB生成能夠封送綜合Log4j 2.x的Java類。 XML。
要考慮的另一種選擇是使用“簡潔的” XML或另一種形式的Log4j 2.x配置 (例如JSON或屬性文件 ),而不使用XSD生成用于編組Log4j 2.x配置的JAXB對象。 值得注意的是,用于Log4j 2.x且具有“ strict”格式的XML配置文件顯然不需要針對Log4j-config.xsd進行驗證,否則XML的“ strict”形式將無法完全指定Log4j2組態。 這意味著即使擁有XSD,剩下的價值還是供我們自己的工具或腳本使用,以便在與Log4j 2.x結合使用之前先使用它來驗證我們的XML配置,或者用于編組/解編Log4j2.x。帶有JAXB的XML。
結論
Log4j2發行版隨附的Log4j-config.xsd不足以驗證“嚴格” XML配置中的所有Log4j 2.x構造,同樣不足以生成用于封送Log4j2嚴格XML的JAXB對象。 希望使用XSD進行驗證或JAXB類生成的開發人員將需要手動更改XSD或從Log4j2源代碼生成XSD。
這些參考文獻已在上面的文章中鏈接到內聯,但此處出于強調目的而列出。
- 在Log4j2中,如何將XML模式與log4j2.xml關聯?
- [LOG4J2-170] Log4J-V2.0.xsd發生架構驗證失敗
- [LOG4J2-411] 對鏈接到配置文件的XSD / DTD的支持
- logging- log4j- 用戶郵件列表 :“ Log4j2 Appender屬性具有嚴格的xml配置 ”
- 從注釋生成XSD?
翻譯自: https://www.javacodegeeks.com/2016/08/log4j-2-x-xsd-not-fully-descriptive.html
總結
以上是生活随笔為你收集整理的Log4j 2.x XSD的描述不完整的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 教你如何查看电脑配置如何快速查看电脑配置
- 下一篇: 万国觉醒亚历山大涅夫斯基天赋图(80射击