log4j与log4j不同:log4j是通过Logger的静态方法getLogger()获取Logger对象,而log4j2是通过LogManager的静态方法getLogger()获取Logger对象。

log4j2配置系列之1

1. log4j2原理

  使用log4j 2 api的应用程序将从LogManager请求具有特定名称的记录器。LogManager将找到适当的LoggerContext,然后从中获取记录器。如果必须创建记录器,它将与LoggerConfig关联,loggerconfig包含a)与记录器相同的名称,b)父包的名称,或c)根LoggerConfig。LoggerConfig对象是从配置中的记录器声明创建的。LoggerConfig与实际传递logevents的appender相关联。

2.logger等级制度

  与普通的system.out.println相比,任何日志api的首要优势在于它能够禁用某些日志语句,同时允许其他人不受阻碍地打印。此功能假定日志空间(即所有可能的日志语句的空间)是根据某些开发人员选择的条件进行分类的。在log4j 1.x中,记录器层次结构是通过记录器之间的关系来维护的。在log4j 2中,这种关系不再存在。相反,层次结构是在loggerconfig对象之间的关系中维护的。

loggers和loggerconfigs是命名实体。记录器名称区分大小写,并遵循分层命名规则:

Nameed HierchaHierarchy
A LoggerConfig is said to be an ancestor of another LoggerConfig if its name followed by a dot is a prefix of the descendant logger name.
A LoggerConfig is said to be a parent of a child LoggerConfig if there are no ancestors between itself and the descendant LoggerConfig.

For example, the LoggerConfig named "com.foo" is a parent of the LoggerConfig named"com.foo.Bar".

Root LoggerConfig位于LoggerConfig层次结构的顶部。它是例外,因为它总是存在的,它是每一个层次的一部分。直接链接到root LoggerConfig的记录器可以按如下方式获取:

Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

还有更简单的一种获取方式:

Logger logger = LogManager.getRootLogger();

对于所有其他类型的记录器,可以通过LogManager的静态方法getLogger获取。具体用法请查阅log4j2 API。

3.LoggerContext

loggercontext充当日志系统的定位点。但是,根据具体情况,应用程序中可能有多个活动loggercontext。有关loggercontext的更多详细信息,请参阅日志分离部分。

4.Configuration

每个loggercontext都有一个活动配置。配置包含所有的appender、上下文范围的Filters、loggerconfigs和对strsubstitutor的引用。在重新配置期间,将存在两个配置对象。一旦所有的记录器被重定向到新配置,旧配置将被停止并丢弃。

5.Logger

如前所述,通过调用logmanager.getlogger创建记录器。记录器本身不执行任何直接操作。它只是有一个名称,并且与loggerconfig相关联。它扩展了AbstractLogger并实现了所需的方法。当配置被修改时,记录器可能与不同的loggerconfig相关联,从而导致其行为被修改。

例如:x和y引用确切的指向相同的Logger对象。

Logger x = LogManager.getLogger("wombat");
Logger y = LogManager.getLogger("wombat");

log4j环境的配置通常在应用程序初始化时完成。首选方法是读取配置文件。

log4j使按软件组件命名记录器变得很容易。这可以通过在每个类中实例化记录器来实现,记录器名称等于类的完全限定名。这是定义记录器的一种有用而直接的方法。由于日志输出带有生成日志的名称,此命名策略使识别日志消息的来源变得容易。然而,这只是一种可能的(尽管很常见)命名记录器的策略。log4j不限制可能的记录器集。开发人员可以根据需要自由命名记录器。由于以拥有的类命名日志记录器是一种常见的习惯用法,因此提供了方便的方法LogManager.getLogger()来自动使用调用类的完全限定类名作为日志记录器名称。不过,以日志记录器所在的类命名日志记录器似乎是目前已知的最佳策略。

6.LoggerConfig

loggerconfig对象是在日志配置中声明日志记录器时创建的。loggerconfig包含一组筛选器,这些筛选器必须允许logevent在传递给任何附加程序之前进行传递。它包含对应用于处理事件的附加程序集的引用。

6.1 log levels

loggerConfigs将被分配一个日志级别。内置级别集包括trace、debug、info、warn、error和fatal。log4j 2还支持自定义日志级别。另一种获得更多粒度的机制是使用标记。

log4j 1.x和logback都有“级别继承”的概念。在log4j 2中,loggers和loggerconfigs是两个不同的对象,所以这个概念的实现方式不同。每个记录器都引用适当的loggerconfig。

7.Filter

除了如前一节所述进行的自动日志级筛选之外,log4j还提供了可以在控件传递给任何LoggerConfig之前、控件传递给LoggerConfig之后、调用任何appender之前、控件传递给l之后应用的筛选器。但在调用特定的appender之前,以及在每个appender上。以一种与防火墙过滤器非常相似的方式,每个过滤器可以返回三个结果之一,接受、拒绝或中立。accept的响应表示不应调用其他筛选器,事件应继续。拒绝响应意味着应该立即忽略该事件,并将控制权返回给调用方。中性响应表示该事件应传递给其他筛选器。如果没有其他筛选器,则将处理事件。

虽然筛选器可以接受事件,但仍可能不记录该事件。当事件被预loggerconfig筛选器接受,但随后被loggerconfig筛选器拒绝或被所有附加程序拒绝时,可能会发生这种情况。

8.appender

  基于日志记录程序有选择地启用或禁用日志记录请求的能力只是图片的一部分。log4j允许将日志记录请求打印到多个目的地。在log4j speak中,输出目的地称为appender。目前,控制台、文件、远程套接字服务器、apache flume、jms、远程unix syslog守护进程和各种数据库api都有附加程序。有关可用的各种类型的详细信息,请参阅附录部分。一个记录器可以连接多个附加程序。

  可以通过调用当前配置的addLoggerAppender方法将追加程序添加到记录器。如果与记录器名称匹配的loggerconfig不存在,将创建一个loggerconfig,附加程序将附加到它,然后通知所有记录器更新其loggerconfig引用。

  为给定记录器启用的每个日志记录请求都将转发给该记录器的loggerconfig中的所有附加程序以及loggerconfig父级的附加程序。换句话说,appender是从loggerconfig层次结构中附加继承的。例如,如果将控制台附加程序添加到根日志记录器,则所有启用的日志记录请求将至少在控制台上打印。如果另外在loggerconfig(比如c)中添加了一个文件追加器,那么对c和c的子级启用的日志记录请求将在文件和控制台中打印。可以重写此默认行为,以便通过在配置文件中的记录器声明上设置additivity=“false”,不再对appender累加。

关于appender可加性的规则总结如下。

8.log4j 1.x Migration

1.Using the Log4j 1.x bridge

也许最简单的转换为使用log4j 2的方法是用log4j2的log4j-1.2-api.jar替换log4j 1.xjar文件。但是,要成功使用此应用程序,必须满足以下要求:

1.它们不能访问log4j 1.x实现内部的方法和类,如Appenders、LoggerRepository或Category的callAppenders方法。

2.它们不能以编程方式配置log4j。

3.它们不能通过调用类DomConfigurator或PropertyConfigurator进行配置。

2.Converting to the Log4j 2 API

在大多数情况下,从log4j 1.x api到log4j 2的转换应该相当简单。许多日志语句不需要修改。但是,如有必要,必须进行以下更改:

1.版本1中的主包是org.apache.log4j,版本2中的主包是org.apache.logging.log4j

2.对org.apache.log4j.Logger.getLogger()的调用必须修改为org.apache.logging.log4j.LogManager.getLogger()。

3.对org.apache.log4j.Logger.getRootLogger()或org.apache.log4j.LogManager.getRootLogger()的调用必须替换为org.apache.logging.log4j.LogManager.getRootLogger()。

4.调用org.apache.log4j.Logger.getLogger接受LoggerFactory必须删除org.apache.log4j.spi.LoggerFactory并使用log4j 2的其他扩展机制之一。

5.将对org.apache.log4j.Logger.getEffectiveLevel()的调用替换为org.apache.logging.log4j.Logger.getLevel()。

6.删除对org.apache.log4j.LogManager.shutdown()的调用,在版本2中不需要它们,因为log4j核心现在会在启动时自动添加一个jvm关闭挂钩来执行任何核心清理。

  从log4j 2.1开始,您可以指定一个自定义的shutdownCallbackRegistry来覆盖默认的jvm shutdown hook策略。

  从log4j 2.6开始,现在可以使用org.apache.logging.log4j.LogManager.shutdown()手动启动关闭。

7.API不支持对org.apache.log4j.Logger.setLevel()或类似方法的调用。应用程序应该删除这些。log4j 2实现类中提供了等效的功能,请参见org.apache.logging.log4j.core.config.Configurator.setLevel(),但可能会使应用程序易受log4j2内部更改的影响。

8.在适当的情况下,应用程序应该转换为使用参数化消息,而不是字符串连接。

9.org.apache.log4j.MDC和org.apache.log4j.NDC已被线程上下文替换。

3.configuring Log4j2

尽管log4j 2配置语法不同于log4j 1.x,但大多数(如果不是全部)相同的功能都是可用的。

注意,通过${foo}语法进行的系统属性插值已经扩展,允许从许多不同的源进行属性查找。有关详细信息,请参阅查找文档。例如,在log4j 1.x中使用名为catalina.base的系统属性查找,语法将是${catalina.base}。在log4j 2中,语法是${sys:catalina.base}。

log4j 1.x有一个与log4j 2中的xmlayout不同的xmlayout,log4j-1.2-api模块包含一个log4j1xmlayout,它以log4j 1.x中的格式生成输出。log4j 1.x simplelayout可以用patternlayout%level-%m%n进行模拟。log4j 1.x ttcclayout可以用patternlayout“%r[%t]%p%c%notempty{%ndc}-%m%n”模拟。

log4j 1.x中的patternLayout和enhancedPatternLayout都可以替换为log4j 2中的patternLayout。log4j-1.2-api模块包含两个模式转换“%ndc”和“%properties”,可用于模拟log4j 1.x patternlayout中的“%x”和“%x”(log4j 2中的%x和%x的格式略有不同)。

下面是log4j 1.x及其在log4j 2中的对应配置示例:

Sample 1 - Simple configuration using a Console Appender

Log4j 1.x XML configuration

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<category name="org.apache.log4j.xml">
<priority value="info" />
</category>
<Root>
<priority value ="debug" />
<appender-ref ref="STDOUT" />
</Root>
</log4j:configuration>

Log4j 2 XML configuration

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="info"/>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>

Sample 2 - Simple configuration using a File Appender, XMLLayout and SimpleLayout

Log4j 1.x XML configuration

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="A1" class="org.apache.log4j.FileAppender">
<param name="File" value="A1.log" />
<param name="Append" value="false" />
<layout class="org.apache.log4j.xml.XMLLayout" />
</appender>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.SimpleLayout" />
</appender>
<category name="org.apache.log4j.xml">
<priority value="debug" />
<appender-ref ref="A1" />
</category>
<root>
<priority value ="debug" />
<appender-ref ref="STDOUT" />
</Root>
</log4j:configuration>

Log4j 2 XML configuration

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="A1" fileName="A1.log" append="false">
<Log4j1XmlLayout />
</File>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%level - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug">
<AppenderRef ref="A1"/>
</Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>

Sample 3 - SocketAppender

Log4j 1.x XML configuration. This example from Log4j 1.x is misleading. The SocketAppender does not actually use a Layout. Configuring one will have no effect.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="A1" class="org.apache.log4j.net.SocketAppender">
<param name="RemoteHost" value="localhost"/>
<param name="Port" value="5000"/>
<param name="LocationInfo" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/>
</layout>
</appender>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<category name="org.apache.log4j.xml">
<priority value="debug"/>
<appender-ref ref="A1"/>
</category>
<root>
<priority value="debug"/>
<appender-ref ref="STDOUT"/>
</Root>
</log4j:configuration>

Log4j 2 XML configuration

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Socket name="A1" host="localHost" port="5000">
<PatternLayout pattern="%t %-5p %c{2} - %m%n"/>
</Socket>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug">
<AppenderRef ref="A1"/>
</Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>

Sample 4 - AsyncAppender and TTCCLayout

Log4j 1.x XML configuration using the AsyncAppender.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" configDebug="true">
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="TEMP"/>
</appender>
<appender name="TEMP" class="org.apache.log4j.FileAppender">
<param name="File" value="temp"/>
<layout class="org.apache.log4j.TTCCLayout">
<param name="ThreadPrinting" value="true"/>
<param name="CategoryPrefixing" value="true"/>
<param name="ContextPrinting" value="true"/>
</layout>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="ASYNC"/>
</Root>
</log4j:configuration>

Log4j 2 XML configuration.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<File name="TEMP" fileName="temp">
<PatternLayout pattern="%r [%t] %p %c %notEmpty{%ndc }- %m%n"/>
</File>
<Async name="ASYNC">
<AppenderRef ref="TEMP"/>
</Async>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="ASYNC"/>
</Root>
</Loggers>
</Configuration>

Sample 5 - AsyncAppender with Console and File

Log4j 1.x XML configuration using the AsyncAppender.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" configDebug="true">
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="TEMP"/>
<appender-ref ref="CONSOLE"/>
</appender>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<appender name="TEMP" class="org.apache.log4j.FileAppender">
<param name="File" value="temp"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="ASYNC"/>
</Root>
</log4j:configuration>

Log4j 2 XML configuration. Note that the Async Appender should be configured after the appenders it references. This will allow it to shutdown properly.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
<File name="TEMP" fileName="temp">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</File>
<Async name="ASYNC">
<AppenderRef ref="TEMP"/>
<AppenderRef ref="CONSOLE"/>
</Async>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="ASYNC"/>
</Root>
</Loggers>
</Configuration>

Log4j2日志配置详解(1)的更多相关文章

  1. Log4j2日志配置详解(2)

    Log4j2日志配置系列之2 1.Configuration 在应用程序代码中插入日志请求需要相当多的计划和工作.观察显示,大约4%的代码用于日志记录.因此,即使是中等大小的应用程序也会在其代码中嵌入 ...

  2. SpringBoot—整合log4j2入门和log4j2.xml配置详解

    关注微信公众号:CodingTechWork,一起学习进步. 引言   对于一个线上程序或者服务而言,重要的是要有日志输出,这样才能方便运维.而日志的输出需要有一定的规划,如日志命名.日志大小,日志分 ...

  3. Log4J日志配置详解

    一.Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使 ...

  4. Apache日志配置详解(rotatelogs LogFormat)

    logs/error_logCustomLog logs/access_log common--默认为以上部分 修改为如下: ErrorLog "|/usr/sbin/rotatelogs ...

  5. (转)Log4J日志配置详解

    http://www.cnblogs.com/ITtangtang/p/3926665.html 一.Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源 ...

  6. java Log4j日志配置详解大全

    一.Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使 ...

  7. Spark log4j日志配置详解(转载)

    一.spark job日志介绍    spark中提供了log4j的方式记录日志.可以在$SPARK_HOME/conf/下,将 log4j.properties.template 文件copy为 l ...

  8. Log4J日志配置详解[转]

    一.Log4j简介 Log4j有三个主要的组件:Loggers(记录器),Appenders (输出源)和Layouts(布局).这里可简单理解为日志类别,日志要输出的地方和日志以何种形式输出.综合使 ...

  9. SpringBoot日志配置(详解) 涉及控制台输出日志、生成日志文件、日志级别修改、hibernate日志不输出

    写在前面 本篇主要讲述日志配置,看完本篇可以解决下述问题, 控制台输出日志.生成日志文件.日志级别修改.hibernate日志不输出 Git Demo Path:https://github.com/ ...

随机推荐

  1. Linux+CLion+树莓派远程编译时,Cmake编译出现undefined reference to `vtable for MainWindow'的解决办法

    在win+CLion上进行远程qt开发时碰到以下错误: 错误提示: undefined reference to `vtable for MainWindow' 原因:源文件的目录结构有问题?? 解决 ...

  2. 解决vscode打开空白的问题

    环境 :win7,最新vscode 问题:打开后窗口全黑,但是原按钮对应位置还有触摸手势,显示tag等,卸载重装等无效,如上图 最终方案: 启动方式后加 --disable-gpu 解决思路(其余参考 ...

  3. Vbox中多台虚拟机搭建简单子网

    一.目标拓扑结构: 要使192.168.31.1和192.168.32.1互相ping通. 二.步骤及问题: 1.路由器配置 SEED_Router配置IP并开启路由转发协议: ifconfig et ...

  4. shell 拾遗

    1, 按照行读取文件 while read line do echo ${line} done < ${filename} 2.循环中使用命令输出 while read line do echo ...

  5. P3951 小凯的疑惑

    P3951 小凯的疑惑 题解 题意也就是求解不能用 ax+by 表示的最大数 ans(a,b,x,y,都是正整数) 给定 a ( =7 ) ,  b ( =3 ) 我们可以把数轴非负半轴上的数按照a的 ...

  6. Android RecyclerView实现加载多种条目类型

    今天咱们是用RecyclerView来实现这个多种Item的加载. 其实最关键的是要复写RecyclerView的Adapter中的getItemViewType()方法 这个方法就根据条件返回条目的 ...

  7. Python的并行求和例子

    先上一个例子,这段代码是为了评估一个预测模型写的,详细评价说明在 https://www.kaggle.com/c/how-much-did-it-rain/details/evaluation, 它 ...

  8. 深度学习之Faster-R-CNN

    哎!还是看大神博客吧 https://blog.csdn.net/liuxiaoheng1992/article/details/81843363

  9. 在Android初次的前期学习中的二个小例子(2)

    Hello13:SQLite数据库 一.简述SQLite的概念和主要特性 SQLite是一个轻量级的关系型数据库,运算速度快,占用资源少,使用非常方便,支持SQL语法标准和数据库事务原则. 相对于Sh ...

  10. 数组setArray和addObjectsFromArray的区别

    -setArray:用另一个数组中的所有对象来替换当前数组中的所有对象 -addObjectsFromArray:在原数组最后添加另一个数组的全部对象 NSArray *arr = @["] ...