log4j 1.x
https://logging.apache.org/log4j/1.2/manual.html
1. log4j.dtd 在哪里?
log4j.jar 包中 org.apache.log4j.xml 下
<?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.
-->
<!-- Authors: Chris Taylor, Ceki Gulcu. -->
<!-- Version: 1.2 -->
<!-- A configuration element consists of optional renderer
elements,appender elements, categories and an optional root
element. -->
<!ELEMENT log4j:configuration (renderer*, throwableRenderer?,
appender*,plugin*, (category|logger)*,root?,
(categoryFactory|loggerFactory)?)>
<!-- The "threshold" attribute takes a level value below which -->
<!-- all logging statements are disabled. -->
<!-- Setting the "debug" enable the printing of internal log4j logging -->
<!-- statements. -->
<!-- By default, debug attribute is "null", meaning that we not do touch -->
<!-- internal log4j logging settings. The "null" value for the threshold -->
<!-- attribute can be misleading. The threshold field of a repository -->
<!-- cannot be set to null. The "null" value for the threshold attribute -->
<!-- simply means don't touch the threshold field, the threshold field -->
<!-- keeps its old value. -->
<!ATTLIST log4j:configuration
xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/"
threshold (all|trace|debug|info|warn|error|fatal|off|null) "null"
debug (true|false|null) "null"
reset (true|false) "false"
>
<!-- renderer elements allow the user to customize the conversion of -->
<!-- message objects to String. -->
<!ELEMENT renderer EMPTY>
<!ATTLIST renderer
renderedClass CDATA #REQUIRED
renderingClass CDATA #REQUIRED
>
<!-- throwableRenderer allows the user to customize the conversion
of exceptions to a string representation. -->
<!ELEMENT throwableRenderer (param*)>
<!ATTLIST throwableRenderer
class CDATA #REQUIRED
>
<!-- Appenders must have a name and a class. -->
<!-- Appenders may contain an error handler, a layout, optional parameters -->
<!-- and filters. They may also reference (or include) other appenders. -->
<!ELEMENT appender (errorHandler?, param*,
rollingPolicy?, triggeringPolicy?, connectionSource?,
layout?, filter*, appender-ref*)>
<!ATTLIST appender
name CDATA #REQUIRED
class CDATA #REQUIRED
>
<!ELEMENT layout (param*)>
<!ATTLIST layout
class CDATA #REQUIRED
>
<!ELEMENT filter (param*)>
<!ATTLIST filter
class CDATA #REQUIRED
>
<!-- ErrorHandlers can be of any class. They can admit any number of -->
<!-- parameters. -->
<!ELEMENT errorHandler (param*, root-ref?, logger-ref*, appender-ref?)>
<!ATTLIST errorHandler
class CDATA #REQUIRED
>
<!ELEMENT root-ref EMPTY>
<!ELEMENT logger-ref EMPTY>
<!ATTLIST logger-ref
ref CDATA #REQUIRED
>
<!ELEMENT param EMPTY>
<!ATTLIST param
name CDATA #REQUIRED
value CDATA #REQUIRED
>
<!-- The priority class is org.apache.log4j.Level by default -->
<!ELEMENT priority (param*)>
<!ATTLIST priority
class CDATA #IMPLIED
value CDATA #REQUIRED
>
<!-- The level class is org.apache.log4j.Level by default -->
<!ELEMENT level (param*)>
<!ATTLIST level
class CDATA #IMPLIED
value CDATA #REQUIRED
>
<!-- If no level element is specified, then the configurator MUST not -->
<!-- touch the level of the named category. -->
<!ELEMENT category (param*,(priority|level)?,appender-ref*)>
<!ATTLIST category
class CDATA #IMPLIED
name CDATA #REQUIRED
additivity (true|false) "true"
>
<!-- If no level element is specified, then the configurator MUST not -->
<!-- touch the level of the named logger. -->
<!ELEMENT logger (param*,level?,appender-ref*)>
<!ATTLIST logger
class CDATA #IMPLIED
name CDATA #REQUIRED
additivity (true|false) "true"
>
<!ELEMENT categoryFactory (param*)>
<!ATTLIST categoryFactory
class CDATA #REQUIRED>
<!ELEMENT loggerFactory (param*)>
<!ATTLIST loggerFactory
class CDATA #REQUIRED>
<!ELEMENT appender-ref EMPTY>
<!ATTLIST appender-ref
ref CDATA #REQUIRED
>
<!-- plugins must have a name and class and can have optional parameters -->
<!ELEMENT plugin (param*, connectionSource?)>
<!ATTLIST plugin
name CDATA #REQUIRED
class CDATA #REQUIRED
>
<!ELEMENT connectionSource (dataSource?, param*)>
<!ATTLIST connectionSource
class CDATA #REQUIRED
>
<!ELEMENT dataSource (param*)>
<!ATTLIST dataSource
class CDATA #REQUIRED
>
<!ELEMENT triggeringPolicy ((param|filter)*)>
<!ATTLIST triggeringPolicy
name CDATA #IMPLIED
class CDATA #REQUIRED
>
<!ELEMENT rollingPolicy (param*)>
<!ATTLIST rollingPolicy
name CDATA #IMPLIED
class CDATA #REQUIRED
>
<!-- If no priority element is specified, then the configurator MUST not -->
<!-- touch the priority of root. -->
<!-- The root category always exists and cannot be subclassed. -->
<!ELEMENT root (param*, (priority|level)?, appender-ref*)>
<!-- ==================================================================== -->
<!-- A logging event -->
<!-- ==================================================================== -->
<!ELEMENT log4j:eventSet (log4j:event*)>
<!ATTLIST log4j:eventSet
xmlns:log4j CDATA #FIXED "http://jakarta.apache.org/log4j/"
version (1.1|1.2) "1.2"
includesLocationInfo (true|false) "true"
>
<!ELEMENT log4j:event (log4j:message, log4j:NDC?, log4j:throwable?,
log4j:locationInfo?, log4j:properties?) >
<!-- The timestamp format is application dependent. -->
<!ATTLIST log4j:event
logger CDATA #REQUIRED
level CDATA #REQUIRED
thread CDATA #REQUIRED
timestamp CDATA #REQUIRED
time CDATA #IMPLIED
>
<!ELEMENT log4j:message (#PCDATA)>
<!ELEMENT log4j:NDC (#PCDATA)>
<!ELEMENT log4j:throwable (#PCDATA)>
<!ELEMENT log4j:locationInfo EMPTY>
<!ATTLIST log4j:locationInfo
class CDATA #REQUIRED
method CDATA #REQUIRED
file CDATA #REQUIRED
line CDATA #REQUIRED
>
<!ELEMENT log4j:properties (log4j:data*)>
<!ELEMENT log4j:data EMPTY>
<!ATTLIST log4j:data
name CDATA #REQUIRED
value CDATA #REQUIRED
>
2. category和logger ,priority和level 区别?
This class has been deprecated and replaced by the Logger subclass.
Level class instead.<!ATTLIST logger
name CDATA #REQUIRED
additivity (true | false) "true"
>
当匹配的一个最合适的logger(最具体的),同过additivity 控制是否向上蔓延,默认true
4. 继承
Level Inheritance
The inherited level for a given logger C, is equal to the first non-null level in the logger hierarchy, starting at C and proceeding upwards in the hierarchy towards the root logger.
从最具体的匹配开始,如果没有指定level则会继承第一个非空的祖先的level
Example 1
| Logger name | Assigned level | Inherited level |
|---|---|---|
| root | Proot | Proot |
| X | none | Proot |
| X.Y | none | Proot |
| X.Y.Z | none | Proot |
In example 1 above, only the root logger is assigned a level. This level value, Proot, is inherited by the other loggers X, X.Y and X.Y.Z.
Example 2
| Logger name | Assigned level | Inherited level |
|---|---|---|
| root | Proot | Proot |
| X | Px | Px |
| X.Y | Pxy | Pxy |
| X.Y.Z | Pxyz | Pxyz |
In example 2, all loggers have an assigned level value. There is no need for level inheritence.
Example 3
| Logger name | Assigned level | Inherited level |
|---|---|---|
| root | Proot | Proot |
| X | Px | Px |
| X.Y | none | Px |
| X.Y.Z | Pxyz | Pxyz |
In example 3, the loggers root, X and X.Y.Z are assigned the levels Proot, Px and Pxyz respectively. The logger X.Y inherits its level value from its parent X.
| Logger name | Assigned level | Inherited level |
|---|---|---|
| root | Proot | Proot |
| X | Px | Px |
| X.Y | none | Px |
| X.Y.Z | none | Px |
5. 具体例子
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
log4j.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="false"> <!-- fileAppender --> <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender"> <param name="File" value="logs/test.log" /> <param name="Append" value="true" /> <param name="MaxFileSize" value="5000KB" /> <param name="MaxBackupIndex" value="10" /> <param name="encoding" value="UTF-8" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{MM/dd HH:mm:ss,SSS} [%c:%M:%-3L]-[%-5p] %m%n" /> </layout> </appender> <logger name="a" additivity="true"> <level value="INFO" /> <appender-ref ref="fileAppender" /> </logger> <logger name="a.b" additivity="true"> <level value="DEBUG" /> <appender-ref ref="fileAppender" /> </logger> <root> <level value="ERROR" /> <appender-ref ref="fileAppender" /> </root> </log4j:configuration>
package a; import org.apache.log4j.Logger; public class A { private static final Logger logger = Logger.getLogger(A.class); public void ff(){ logger.trace(logger.getLevel()); logger.debug(logger.getLevel()); logger.info(logger.getLevel()); logger.warn(logger.getLevel()); logger.error(logger.getLevel()); } }
package a.b; import org.apache.log4j.Logger; public class AB { private static final Logger logger = Logger.getLogger(AB.class); public void ff(){ logger.trace(logger.getLevel()); logger.debug(logger.getLevel()); logger.info(logger.getLevel()); logger.warn(logger.getLevel()); logger.error(logger.getLevel()); } }
import a.A; import a.b.AB; public class Test { public static void main(String[] args) { new A().ff(); new AB().ff(); } }
打印结果:
02/07 12:16:20,033 [a.A:ff:11 ]-[INFO ] 02/07 12:16:20,033 [a.A:ff:11 ]-[INFO ] 02/07 12:16:20,036 [a.A:ff:12 ]-[WARN ] 02/07 12:16:20,036 [a.A:ff:12 ]-[WARN ] 02/07 12:16:20,036 [a.A:ff:13 ]-[ERROR] 02/07 12:16:20,036 [a.A:ff:13 ]-[ERROR] 02/07 12:16:20,036 [a.b.AB:ff:10 ]-[DEBUG] 02/07 12:16:20,036 [a.b.AB:ff:10 ]-[DEBUG] 02/07 12:16:20,036 [a.b.AB:ff:10 ]-[DEBUG] 02/07 12:16:20,036 [a.b.AB:ff:11 ]-[INFO ] 02/07 12:16:20,036 [a.b.AB:ff:11 ]-[INFO ] 02/07 12:16:20,036 [a.b.AB:ff:11 ]-[INFO ] 02/07 12:16:20,036 [a.b.AB:ff:12 ]-[WARN ] 02/07 12:16:20,036 [a.b.AB:ff:12 ]-[WARN ] 02/07 12:16:20,036 [a.b.AB:ff:12 ]-[WARN ] 02/07 12:16:20,038 [a.b.AB:ff:13 ]-[ERROR] 02/07 12:16:20,038 [a.b.AB:ff:13 ]-[ERROR] 02/07 12:16:20,038 [a.b.AB:ff:13 ]-[ERROR]
6. 开启自身内部的调试信息
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true">
打印结果:
log4j: reset attribute= "false".
log4j: Threshold ="null".
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [a] additivity to [true].
log4j: Level value for a is [INFO].
log4j: a level set to INFO
log4j: Class name: [org.apache.log4j.RollingFileAppender]
log4j: Setting property [file] to [logs/test.log].
log4j: Setting property [append] to [true].
log4j: Setting property [maxFileSize] to [5000KB].
log4j: Setting property [maxBackupIndex] to [10].
log4j: Setting property [encoding] to [UTF-8].
log4j: Parsing layout of class: "org.apache.log4j.PatternLayout"
log4j: Setting property [conversionPattern] to [%d{MM/dd HH:mm:ss,SSS} [%c:%M:%-3L]-[%-5p] %m%n].
log4j: setFile called: logs/test.log, true
log4j: setFile ended
log4j: Adding appender named [fileAppender] to category [a].
log4j: Retreiving an instance of org.apache.log4j.Logger.
log4j: Setting [a.b] additivity to [true].
log4j: Level value for a.b is [DEBUG].
log4j: a.b level set to DEBUG
log4j: Adding appender named [fileAppender] to category [a.b].
log4j: Level value for root is [ERROR].
log4j: root level set to ERROR
log4j: Adding appender named [fileAppender] to category [root].
浙公网安备 33010602011771号