精华内容
下载资源
问答
  • Log4j2

    千次阅读 2019-02-28 16:41:47
    目录一 简介二 简单使用 一 简介 历史上出现了很多的日记框架,如: Log4j:Apache Log4j是一个基于Java的日志记录...Log4j 2:Apache Log4j 2是apache开发的一款Log4j的升级产品。 Commons Logging:Apache基金...

    一 简介

    历史上出现了很多的日记框架,如:

    • Log4j:Apache Log4j是一个基于Java的日志记录工具。它是由Ceki Gülcü首创的,现在则是Apache软件基金会的一个项目。 Log4j是几种Java日志框架之一。
    • Log4j 2:Apache Log4j 2是apache开发的一款Log4j的升级产品。
    • Commons Logging:Apache基金会所属的项目,是一套Java日志接口,之前叫Jakarta Commons Logging,后更名为Commons Logging。
    • Slf4j:类似于Commons Logging,是一套简易Java日志门面,本身并无日志的实现。(Simple Logging Facade for Java,缩写Slf4j)。
    • Logback:一套日志组件的实现(Slf4j阵营)。
    • Jul(Java Util Logging):自Java1.4以来的官方日志实现。

    由于java官方日记框架Jul出现较晚,因此没能统一日记接口。slf4j和commons-loggings都只定义了接口,为了桥接其他日记框架,需要额外的jar包。使用日记接口,可以方便的在不同日记框架间切换(为了灵活性的同时也付出了一定代价),于是形成了两大阵容:
    在这里插入图片描述
    一般常见的使用组合为:slf4j与logback,commons logging与log4j。但是我选择使用Log4j2,它重写了log4j,具有Logback的全部特性,是log4j的升级版,却不兼容log4j。log4j2将接口(log4j-api)和实现(log4j-core)分开来,提供了桥接其他日记实现的可能(log4j-core被适配器替换)。log4j2提供了与Jul、Slf4j、commons logging桥接的jar包,因此log4j2即使不兼容log4j,也能通过commons logging桥接包使用它。与slf4j的桥接如下:
    在这里插入图片描述
    除此之外,log4j2还有很多特性,如异步输出(降低io负担),自动加载配置(避免重启应用),自定义日记级别(感觉不常用)等等。

    二 架构

    2.1 主要组件

    log4j中使用的类大致如下:
    在这里插入图片描述

    如果看不懂UML,请参考UML类图

    Logger是最常使用的类,用于打印日记的接口,通过LogManager类指定名字获得。LogManager定位LoggerContext并从它那获得Logger。如果Logger被创建,Logger会被关联一个LoggerConfig,该LoggerConfig可能与Logger同名,或同父package名或为root LoggerConfig(涉及Level Inheritance)。

    使用Logger可以打印不同级别的日记,这些日记会被包装为LogEvent。LogEvent会被派送到LoggerConfig上。LoggerConfig在xml配置文件中由Logger元素配置的,LoggerConfig含有日记级别(Log Level)信息,对应0到多个Appender。LoggerConfig根据自己的日记级别配置与LogEvent的级别,决定是否允许进一步的处理。如果NO则丢弃,如果Yes则传给Appender。

    LoggerConfig中的日记级别只是一个种定义好了的过滤器(Filter),还可以在Logger元素中为LoggerConfig配置过滤器,进行更细致的控制。

    Appender负责将LogEvent派送到目的地,可以有很多目的地,如console,文件、远程服务器或数据库等等。一个loggerConfig可以对应很多Appender,loggerConfig含有父(或祖先)loggerConfig的引用。因此loggerConfig不仅将LogEvent发送给自己的所有Appender,还发给它的父(或祖先)LoggerConfig的appender,然后递归向上,这种行为被称为Additivity

    举个例子,名为"com.foo"的loggerConfig是名为"com.foo.Bar"的父亲。com.foo配置输出到文件中,com.foo.Bar配置输出到console,那么对应com.foor.Bar的loggerConfig的Logger打印日记时,会同时打印到文件和控制台中。

    appender只关心如何将LogEvent送到目的地,而Layout负责格式化LogEvent。log4j中含有不同种Layout,用于不同的用途,如JSON,XML,HTML等等。

    比如默认使用PatternLayout,使用类似c语言printf的转化模式(conversion pattern)。例如,一个模式%r [%t] %-5p %c - %m%n会输入如下信息:
    176 [main] INFO org.foo.Bar - Located nearest gas station.
    分别对应:项目开始到现在的毫秒;打印日记的线程;日记级别;日记对应的Logger名;日记信息

    至于LoggerContext和Configuration。LoggerContext是真正产生Logger的地方,在日记系统中扮演很重要的角色。Configuration是一个配置类,如果没有给出配置,则会使用默认Configuration。如果有配置文件,并且在运行时改变该配置文件,log4j会检测到,并生成新的Configuration,所有的Logger都被重定向到新Configuration中的内容,老的Configuration被丢弃。

    2.2 层次结构

    每个Logger都有自己的名字,通常使用Logger所处类的全限定名作为Logger的名字。LoggerConfig也是一个命名的实体,通常名字与Logger对应。因此log4j中有两个名字层级结构。

    如果两者完全匹配,则Logger关联到匹配的LoggerConfig上,使用它的配置。如果没有完全匹配的,Logger会在名字空间上寻找最近匹配的LoggerConfig,并关联它。

    在log4j中必定存在root LoggerConfig,即使没有手动配置,也会使用默认的,保证Logger能够关联到LoggerConfig。

    2.3 日记级别

    LoggerConfig需要配置日记级别,用于筛选某个范围的所有日记。下面给出每种级别的日记是否能够通过不同LoggerConfig的表格:
    在这里插入图片描述

    三 配置

    3.1 查找配置

    log4j在初始化时会自动查找配置,然后配置自己。支持各种方式、各种类型的配置,检查过程如下:

    1. 系统属性log4j.configurationFile指定的文件
    2. classpath下log4j2-test.properties
    3. classpath下log4j2-test.yamllog4j2-test.jsonlog4j2-test.xml
    4. classpath下log4j2.properties
    5. classpath下log4j2.yamllog4j2.jsonlog4j2.xml
    6. 默认配置被使用

    3.2 简单配置

    如果不配置时,log4j会使用默认配置,默认配置对应的xml配置如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
      <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
          <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="Console"/>
        </Root>
      </Loggers>
    </Configuration>
    
    • 其中Loggers元素中的子元素Root、Logger都是在配置LoggerConfig,因此会配置有0个或多个appender。
    • log4j 的xml语法格式不太严格,参考:XML Syntax

    上面配置了Root LoggerConfig,和输出到console的appender。可以为具体的Logger配置一个LoggerConfig,有不同的日记级别:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
      <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
          <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Logger name="com.foo.Bar" level="trace">
        </Logger>
        <Root level="error">
          <AppenderRef ref="Console"/>
        </Root>
      </Loggers>
    </Configuration>
    

    由于additivity,com.foo.Bar的LoggerConfig会使用祖先root LoggerConfig的appender,即输出到console中。

    3.3 Configuration

    Configuration元素一些重要的属性如下:

    • status:log4j框架内部要输出到console的LogEvent的级别。可选值:trace", “debug”, “info”, “warn”, “error” and “fatal”。貌似默认warn。
    • dest:输出到console具体的流。可选值:“err”,“out”,文件或url。默认out。
    • monitorInterval:多少秒扫描一下配置文件

    参考:Configuration

    3.4 其他配置链接

    配置方式官方文档说的很详细,这里直接贴出链接。。。阅读时记住,xml配置的语法很松懈。

    ConsoleAppender是比较常用的appender

    PatternLayout是一个比较常用的layout。这里要注意使用charset属性日记乱码,PatternLayout默认使用系统编码。

    四 使用

    使用例子如下:

    public class WXTest {
        //声明为静态字段,避免浪费计算资源
        private static final Logger logger=LogManager.getLogger();//无参数构造函数,默认类的全限定名作为Logger名
        @Test
        public void test()  {
            try {
                log(1);
            } catch (Exception e) {
                logger.catching(e);
            }
        }
        public void log(int p) throws Exception {
            logger.info("进入log方法");
            if(p==1){
                throw new Exception("出现异常");
            }
            logger.info("正常退出log方法");
        }
    }
    

    输出:

    16:32:45.976 [main] INFO  com.luo.WXShop.test.WXTest - 进入log方法
    16:32:46.006 [main] ERROR com.luo.WXShop.test.WXTest - Catching
    java.lang.Exception: 出现异常
    	at com.luo.WXShop.test.WXTest.log(WXTest.java:35) ~[test-classes/:?]
    	at com.luo.WXShop.test.WXTest.test(WXTest.java:27) [test-classes/:?]
    

    五 其他

    5.1 日记级别使用情景

    • ALL 最低等级的,用于打开所有日志记录。
    • TRACE 很低的日志级别,一般不会使用。
    • DEBUG 指出细粒度信息事件对调试应用程序是非常有帮助的,主要用于开发过程中打印一些运行信息。
    • INFO 消息在粗粒度级别上突出强调应用程序的运行过程。这个可以用于生产环境中输出程序运行的一些重要信息。
    • WARN 表明会出现潜在错误的情形,有些信息不是错误信息,但是也要给开发者的一些提示。
    • ERROR 指出发生错误的信息,可能会导致系统出错或是宕机等,必须要避免
    • FATAL 指出每个严重的错误事件将会导致应用程序的退出。这个级别比较高了。重大错误,这种级别你可以直接停止程序了。
    • OFF 最高等级,用于关闭所有日志记录。

    参考

    展开全文
  • log4j2 实际使用详解

    万次阅读 多人点赞 2017-05-12 19:31:07
    日志框架简单比较(slf4j、log4j、logback、log4j2log4j2基础知识 log4j2实用配置 实战部分 slf4j + log4j2 实际使用 二、日志框架比较(slf4j、log4j、logback、log4j2 ) 日志接口(slf4j) slf4j是对所有日志...

    分享一个朋友的人工智能教程(请以“右键”->"在新标签页中打开连接”的方式访问)。比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看。

    一、目录简介

    • 基础部分
      • 日志框架简单比较(slf4j、log4j、logback、log4j2 )
      • log4j2基础示例
      • log4j2配置文件
    • 实战部分
      • slf4j + log4j2 实际使用

    二、日志框架比较(slf4j、log4j、logback、log4j2 )

    • 日志接口(slf4j)
      slf4j是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如log4j、logback)

    • 日志实现(log4j、logback、log4j2)

      • log4j是apache实现的一个开源日志组件
      • logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现
      • Log4j2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活,官网地址: http://logging.apache.org/log4j/2.x/manual/configuration.html
    • 为什么需要日志接口,直接使用具体的实现不就行了吗?

      接口用于定制规范,可以有多个实现,使用时是面向接口的(导入的包都是slf4j的包而不是具体某个日志框架中的包),即直接和接口交互,不直接使用实现,所以可以任意的更换实现而不用更改代码中的日志相关代码。

      比如:slf4j定义了一套日志接口,项目中使用的日志框架是logback,开发中调用的所有接口都是slf4j的,不直接使用logback,调用是 自己的工程调用slf4j的接口,slf4j的接口去调用logback的实现,可以看到整个过程应用程序并没有直接使用logback,当项目需要更换更加优秀的日志框架时(如log4j2)只需要引入Log4j2的jar和Log4j2对应的配置文件即可,完全不用更改Java代码中的日志相关的代码logger.info(“xxx”),也不用修改日志相关的类的导入的包(import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;)

      使用日志接口便于更换为其他日志框架。

      log4j、logback、log4j2都是一种日志具体实现框架,所以既可以单独使用也可以结合slf4j一起搭配使用)


    三、log4j2基础示例

    1. 创建maven web 项目, 结构如下
      这里写图片描述

    2. 配置pom.xml,引入log4j2必要的依赖(log4j-api、log4j-core)

    <properties>
      	<junit.version>3.8.1</junit.version>
      	<log4j.version>2.5</log4j.version>
    </properties>
    
    <!-- 使用aliyun镜像 -->
    <repositories>
      <repository>
          <id>aliyun</id>
          <name>aliyun</name>
          <url>http://maven.aliyun.com/nexus/content/groups/public</url>
      </repository>
    </repositories>
    
    <dependencies>
    	<dependency>  
            <groupId>org.apache.logging.log4j</groupId>  
            <artifactId>log4j-api</artifactId>  
            <version>${log4j.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.logging.log4j</groupId>  
            <artifactId>log4j-core</artifactId>  
            <version>${log4j.version}</version>  
        </dependency>  
    </dependencies>
    

    3、 使用Main方法简单测试
    这里写图片描述

    测试说明:

    1. 工程中只引入的jar并没有引入任何配置文件,在测试的时候可以看到有ERROR输出:“ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console.”

    2. 输出logger时可以看到只有error和fatal级别的被输出来,是因为没有配置文件就使用默认的,默认级别是error,所以只有error和fatal输出来

    3. 引入的包是log4j本身的包(import org.apache.logging.log4j.LogManager)


    四:log2j 配置文件详解

    配置文件的格式和位置

    配置文件的格式:log2j配置文件可以是xml格式的,也可以是json格式的,
    配置文件的位置:log4j2默认会在classpath目录下寻找log4j2.xml、log4j.json、log4j.jsn等名称的文件,如果都没有找到,则会按默认配置输出,也就是输出到控制台,也可以对配置文件自定义位置(需要在web.xml中配置),一般放置在src/main/resources根目录下即可
    这里写图片描述

    纯Java方式:

    public static void main(String[] args) throws IOException {  
        File file = new File("D:/log4j2.xml");  
        BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));  
        final ConfigurationSource source = new ConfigurationSource(in);  
        Configurator.initialize(null, source);  
          
        Logger logger = LogManager.getLogger("myLogger");  
    } 
    

    Web工程方式:

    <context-param>  
        <param-name>log4jConfiguration</param-name>  
        <param-value>/WEB-INF/conf/log4j2.xml</param-value>  
    </context-param>  
      
    <listener>  
        <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>  
    </listener> 
    

    示例一:简单配置(使用根控制器输出到控制台上)

    log4j2.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">  
        <Appenders>  
            <Console name="Console" target="SYSTEM_OUT">  
                <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />  
            </Console>  
        </Appenders>  
        
        <Loggers>  
            <Root level="info">  
                <AppenderRef ref="Console" />  
            </Root>  
        </Loggers>  
    </Configuration>
    

    示例结果:

    这里写图片描述

    结果解释:
    日志管理器获取的是根日志器LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
    对应的log4j2.xml中的Loggers节点下的Root,因为该根日志器的level=“info”,所以输出的info级别以上的日志


    示例二:File Logger

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">  
        <Appenders>  
            <Console name="Console" target="SYSTEM_OUT">  
                <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />  
            </Console>
            
            <File name="FileAppender" fileName="D:/logs/app.log">  
                <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />  
            </File>  
            
            <!-- 发现Async 好像PatternLayout的输出格式配置的和输出的格式不一样,不用异步就完全一样  -->
            <Async name="AsyncAppender">
    	    <AppenderRef ref="FileAppender"/>
        	</Async>
        </Appenders>  
        
        <Loggers>  
        	<Logger name="AsyncFileLogger" level="trace" additivity="true">  
    	        <AppenderRef ref="AsyncAppender" />  
    		</Logger>
            <Root level="info">  
                <AppenderRef ref="Console" />  
            </Root>  
        </Loggers>  
    </Configuration>
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class Log4j2Test {
    
    	public static void main(String[] args) {
    		Logger logger = LogManager.getLogger("AsyncFileLogger"); // Logger的名称
    		
    		logger.trace("trace level");
    		logger.debug("debug level");
    		logger.info("info level");
    		logger.warn("warn level");
    		logger.error("error level");
    		logger.fatal("fatal level");
    	}
    }
    
    

    AsyncFileLogger的additivity的值如果为false的话,就不会在控制台上输出或者为该Logger再增加一个输出源Consloe

    <Logger name="AsyncFileLogger" level="trace" additivity="false">  
    	<AppenderRef ref="AsyncAppender" />  
    	<AppenderRef ref="Console" />  
    </Logger>
    

    示例三: RollingRandomAccessFile

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN"> 
    	<properties>
    		<property name="LOG_HOME">D:/logs</property>
    		<property name="FILE_NAME">mylog</property>
    	</properties>
    	
    	 
        <Appenders>  
            <Console name="Console" target="SYSTEM_OUT">  
                <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />  
            </Console>
            
            <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
            	<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
            	<Policies>
            		<TimeBasedTriggeringPolicy interval="1"/>
            		<SizeBasedTriggeringPolicy size="10 MB"/>
            	</Policies>
            	<DefaultRolloverStrategy max="20"/>
            </RollingRandomAccessFile>
            
            <Async name="AsyncAppender">
            	<AppenderRef ref="RollingRandomAccessFile"/>
        	</Async>
        </Appenders>  
        
        <Loggers>  
        	<Logger name="RollingRandomAccessFileLogger" level="info" additivity="false">  
    	        <AppenderRef ref="AsyncAppender" />  
    	        <AppenderRef ref="Console" />  
    	    </Logger>
        </Loggers>  
    </Configuration>
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class Log4j2Test {
    
    	public static void main(String[] args) {
    		
    	    Logger logger = LogManager.getLogger("RollingRandomAccessFileLogger");  
    	    for(int i = 0; i < 50000; i++) {  
    	        logger.trace("trace level");  
    	        logger.debug("debug level");  
    	        logger.info("info level");  
    	        logger.warn("warn level");  
    	        logger.error("error level");  
    	        logger.fatal("fatal level");  
    	    }  
    	    
    	    try {  
    	        Thread.sleep(1000 * 61);  
    	    } catch (InterruptedException e) {}  
    	    
    	    logger.trace("trace level");  
    	    logger.debug("debug level");  
    	    logger.info("info level");  
    	    logger.warn("warn level");  
    	    logger.error("error level");  
    	    logger.fatal("fatal level"); 
    	}
    }
    
    

    这里写图片描述

    RollingRandomAccessFile 会根据命名规则当文件满足一定大小时就会另起一个新的文件


    五:log4j2配置文件详解

    log4j2.xml文件的配置大致如下:

    • Configuration
      • properties
      • Appenders
        • Console
          • PatternLayout
        • File
        • RollingRandomAccessFile
        • Async
      • Loggers
        • Logger
        • Root
          • AppenderRef

    • Configuration:为根节点,有status和monitorInterval等多个属性

      • status的值有 “trace”, “debug”, “info”, “warn”, “error” and “fatal”,用于控制log4j2日志框架本身的日志级别,如果将stratus设置为较低的级别就会看到很多关于log4j2本身的日志,如加载log4j2配置文件的路径等信息
      • monitorInterval,含义是每隔多少秒重新读取配置文件,可以不重启应用的情况下修改配置
    • Appenders:输出源,用于定义日志输出的地方
      log4j2支持的输出源有很多,有控制台Console、文件File、RollingRandomAccessFile、MongoDB、Flume 等

      • Console:控制台输出源是将日志打印到控制台上,开发的时候一般都会配置,以便调试

      • File:文件输出源,用于将日志写入到指定的文件,需要配置输入到哪个位置(例如:D:/logs/mylog.log)

      • RollingRandomAccessFile: 该输出源也是写入到文件,不同的是比File更加强大,可以指定当文件达到一定大小(如20MB)时,另起一个文件继续写入日志,另起一个文件就涉及到新文件的名字命名规则,因此需要配置文件命名规则
        这种方式更加实用,因为你不可能一直往一个文件中写,如果一直写,文件过大,打开就会卡死,也不便于查找日志。

        • fileName 指定当前日志文件的位置和文件名称
        • filePattern 指定当发生Rolling时,文件的转移和重命名规则
        • SizeBasedTriggeringPolicy 指定当文件体积大于size指定的值时,触发Rolling
        • DefaultRolloverStrategy 指定最多保存的文件个数
        • TimeBasedTriggeringPolicy 这个配置需要和filePattern结合使用,注意filePattern中配置的文件重命名规则是${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i,最小的时间粒度是mm,即分钟
        • TimeBasedTriggeringPolicy指定的size是1,结合起来就是每1分钟生成一个新文件。如果改成%d{yyyy-MM-dd HH},最小粒度为小时,则每一个小时生成一个文件
      • NoSql:MongoDb, 输出到MongDb数据库中

      • Flume:输出到Apache Flume(Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集、聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据;同时,Flume提供对数据进行简单处理,并写到各种数据接受方(可定制)的能力。)

      • Async:异步,需要通过AppenderRef来指定要对哪种输出源进行异步(一般用于配置RollingRandomAccessFile)

      PatternLayout:控制台或文件输出源(Console、File、RollingRandomAccessFile)都必须包含一个PatternLayout节点,用于指定输出文件的格式(如 日志输出的时间 文件 方法 行数 等格式),例如 pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"

        %d{HH:mm:ss.SSS} 表示输出到毫秒的时间
        %t 输出当前线程名称
        %-5level 输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补0
        %logger 输出logger名称,因为Root Logger没有名称,所以没有输出
        %msg 日志文本
        %n 换行
      
        其他常用的占位符有:
        %F 输出所在的类文件名,如Log4j2Test.java
        %L 输出行号
        %M 输出所在方法名
        %l 输出语句所在的行数, 包括类名、方法名、文件名、行数
      
    • Loggers:日志器
      日志器分根日志器Root和自定义日志器,当根据日志名字获取不到指定的日志器时就使用Root作为默认的日志器,自定义时需要指定每个Logger的名称name(对于命名可以以包名作为日志的名字,不同的包配置不同的级别等),日志级别level,相加性additivity(是否继承下面配置的日志器), 对于一般的日志器(如Console、File、RollingRandomAccessFile)一般需要配置一个或多个输出源AppenderRef;

      每个logger可以指定一个level(TRACE, DEBUG, INFO, WARN, ERROR, ALL or OFF),不指定时level默认为ERROR

      additivity指定是否同时输出log到父类的appender,缺省为true。

    <Logger name="rollingRandomAccessFileLogger" level="trace" additivity="true">  
    	<AppenderRef ref="RollingRandomAccessFile" />  
    </Logger>
    
    • properties: 属性
      使用来定义常量,以便在其他配置的时候引用,该配置是可选的,例如定义日志的存放位置
      D:/logs

    【实战部分】

    1. 引入slf4j和log4j需要的依赖
    <properties>
      	<junit.version>3.8.1</junit.version>
      	<log4j.version>2.5</log4j.version>
      </properties>
      
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>${junit.version}</version>
          <scope>test</scope>
        </dependency>
        
        <!-- slf4j + log4j2 begin -->
        <dependency>
    	    <groupId>org.slf4j</groupId>
    	    <artifactId>slf4j-api</artifactId>
    	    <version>1.7.10</version>
    	</dependency>
    	
    	<dependency> <!-- 桥接:告诉Slf4j使用Log4j2 -->
    	    <groupId>org.apache.logging.log4j</groupId>
    	    <artifactId>log4j-slf4j-impl</artifactId>
    	    <version>2.2</version>
    	</dependency>
    	<dependency> <!-- 桥接:告诉commons logging使用Log4j2 -->
    	    <groupId>org.apache.logging.log4j</groupId>
    	    <artifactId>log4j-jcl</artifactId>
    	    <version>2.2</version>
    	</dependency>
        
        <dependency>  
            <groupId>org.apache.logging.log4j</groupId>  
            <artifactId>log4j-api</artifactId>  
            <version>${log4j.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.logging.log4j</groupId>  
            <artifactId>log4j-core</artifactId>  
            <version>${log4j.version}</version>  
        </dependency>  
        <!-- log4j end-->
      </dependencies>
      
      <!-- 使用aliyun镜像 -->
      <repositories>
        <repository>
            <id>aliyun</id>
            <name>aliyun</name>
            <url>http://maven.aliyun.com/nexus/content/groups/public</url>
        </repository>
      </repositories>
    

    2、配置log2.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN"> 
    	<properties>
    		<property name="LOG_HOME">D:/logs</property>
    		<property name="FILE_NAME">mylog</property>
    		<property name="log.sql.level">info</property>
    	</properties>
    	
    	 
        <Appenders>  
            <Console name="Console" target="SYSTEM_OUT">  
                <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %msg%n" />  
            </Console>
            
            <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="${LOG_HOME}/${FILE_NAME}.log" filePattern="${LOG_HOME}/$${date:yyyy-MM}/${FILE_NAME}-%d{yyyy-MM-dd HH-mm}-%i.log">
            	<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %l - %msg%n"/>
            	<Policies>
            		<TimeBasedTriggeringPolicy interval="1"/>
            		<SizeBasedTriggeringPolicy size="10 MB"/>
            	</Policies>
            	<DefaultRolloverStrategy max="20"/>
            </RollingRandomAccessFile>
        </Appenders>  
        
        <Loggers>  
        	<Root level="info">  
        		<AppenderRef ref="Console" />  
    	        <AppenderRef ref="RollingRandomAccessFile" />  
    	    </Root>
    	    
    	    <Logger name="com.mengdee.dao" level="${log.sql.level}" additivity="false">
                 <AppenderRef ref="Console" />
            </Logger>
        </Loggers>  
    </Configuration>
    

    3、 Java

    package com.mengdee.manage;
    
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    public class Log4j2Test {
    
    	// Logger和LoggerFactory导入的是org.slf4j包
    	private final static Logger logger = LoggerFactory.getLogger(Log4j2Test.class);
    	public static void main(String[] args) {
    		long beginTime = System.currentTimeMillis();
    		
    		for(int i = 0; i < 100000; i++) {  
    			logger.trace("trace level");  
    		    logger.debug("debug level");  
    		    logger.info("info level");  
    		    logger.warn("warn level");  
    		    logger.error("error level");
    		}
    		
    		try {  
    	        Thread.sleep(1000 * 61);  
    	    } catch (InterruptedException e) {}  
    	      
    	    
    	    logger.info("请求处理结束,耗时:{}毫秒", (System.currentTimeMillis() - beginTime));    //第一种用法
    	    logger.info("请求处理结束,耗时:" + (System.currentTimeMillis() - beginTime)  + "毫秒");    //第二种用法
    
    	}
    }
    

    4、运行结果
    这里写图片描述

    这里写图片描述

    这里写图片描述

    持续完善中。。。

    分享一个朋友的人工智能教程(请以“右键”->"在新标签页中打开连接”的方式访问)。比较通俗易懂,风趣幽默,感兴趣的朋友可以去看看。

    我的微信公众号

    这里写图片描述

    展开全文
  • log4j与log4j2性能对比及log4j升级至log4j2方案

    千次阅读 多人点赞 2019-06-16 11:03:53
    1.前言 之前某个服务在压测环境中出现了问题,分析之后得知是log4jLogger对象争用厉害,很多线程阻塞在此。...关于log4j与log4j2的性能对比文章有很多,本文不过多描述,给出几张结论图及原文链接,作为参考...

    1.前言

    • 之前某个服务在压测环境中出现了问题,分析之后得知是log4jLogger对象争用厉害,很多线程阻塞在此。

    • 以上问题证明log4j在高并发高QPS情况下,是存在性能问题的。

    • 之后把log4j升级成了log4j2,并采取异步日志模式,解决了因日志造成的性能问题。

    2.性能对比

    关于log4j与log4j2的性能对比文章有很多,本文不过多描述,给出几张结论图及原文链接,作为参考。

    1. Log4j1、Logback 以及 Log4j2 性能测试对

      在这里插入图片描述
      上述图片由原文作者【ksfzhaohui】提供,特此感谢!

    2. logback log4j log4j2 性能实测

      在这里插入图片描述
      上述图片由原文作者【专注服务端】提供,特此感谢!

    3. 高性能队列——Disruptor

      在这里插入图片描述
      上述图片由原文作者【宫铭】提供,特此感谢!

    3.相关知识

    • 和日志相关的概念有:log4j、log4j2、logback、commons-logging、slf4j
    • 其中,log4j、log4j2、logback、commons-logging都是日志的具体实现包。
    • 其中,slf4j是一个门面,一个适配器,所有的日志代码都可以用slf4j来写,它会根据项目具体依赖的日志实现包进行日志操作。
    • 通过slf4j写日志的好处是,当更换日志的实现方案时,无需修改日志代码,只需修改pom.xml即可。
    • 推荐:通过slf4j写日志。
    • 推荐:通过lombok的@Slf4j注解写日志。

    4.log4j升级至log4j2

    4.1.排除旧的日志实现包

    • 因为每个项目的pom.xml多种多样,所以无法总结统一的排除方案,这里只汇总需要排除的包。

    • 也就是说,如果你的项目里有以下包,应该排除。

    <exclusions>
        <!-- log4j 相关包 -->
        <exclusion>
            <artifactId>log4j</artifactId>
            <groupId>log4j</groupId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
        <!-- log4j 的springboot starter -->
        <exclusion>
            <artifactId>spring-boot-starter-log4j</artifactId>
            <groupId>org.springframework.boot</groupId>
        </exclusion>
     
        <!-- logback 相关包 -->
        <exclusion>
            <artifactId>logback-classic</artifactId>
            <groupId>ch.qos.logback</groupId>
        </exclusion>
        <exclusion>
            <artifactId>logback-core</artifactId>
            <groupId>ch.qos.logback</groupId>
        </exclusion>
     
        <!-- slf4j 相关包 -->
        <exclusion>
            <artifactId>slf4j-log4j12</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
         <exclusion>
            <artifactId>log4j-to-slf4j</artifactId>
            <groupId>org.apache.logging.log4j</groupId>
        </exclusion>
        <exclusion>
            <artifactId>slf4j-api</artifactId>
            <groupId>org.slf4j</groupId>
        </exclusion>
    </exclusions>
    

    4.2.增加log4j2的依赖包

    <!-- log4j2的api、core和web包 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.11.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.11.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-web</artifactId>
        <version>2.11.1</version>
    </dependency>
    <!-- slf4j与log4j2的连接包 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>2.11.1</version>
    </dependency>
    <!-- log4j与log4j2的连接包 -->
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-1.2-api</artifactId>
        <version>2.11.1</version>
    </dependency>
    <!-- log4j2支撑完全异步模式的关键api -->
    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>3.4.2</version>
    </dependency>
    <!-- slf4j本身的api -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
    </dependency>
    

    4.3.修复编译报错

    • 如果之前代码中日志都是直接通过log4j编写的,则可能需要修改import路径。
    • 在log4j版本,Logger的包路径是org.apache.log4j
    • 在log4j2版本,Logger的包路径是org.apache.logging.log4j

    4.4.替换日志配置文件

    • 在log4j版本,配置文件为log4j.xml或者log4j.properties。

    • 在log4j2版本,配置文件为log4j2.xml。

    • 在log4j2版本,支持三种异步方式:Sync(同步)、Async Appender(混合异步)和Loggers All Async(全异步),其性能优势依次递增。

    • 下面给出一份全异步的参考配置。

      <?xml version="1.0" encoding="UTF-8"?>
      <configuration status="error" monitorInterval="30">
          <Properties>
              <Property name="baseDir">log</Property>
          </Properties>
          <!--先定义所有的appender-->
          <appenders>
              <!--这个输出控制台的配置-->
              <Console name="Console" target="SYSTEM_OUT">
                  <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                  <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY"/>
                  <PatternLayout pattern="%d %5p %c:%L - %m %throwable{}%n"/>
              </Console>
              <!--异步日志配置,指向配置引用AppenderRef-->
              <Async name="ASYNC" bufferSize="262144" includeLocation="true">
                  <AppenderRef ref="RollingFile"/>
              </Async>
              <!--日志文件配置,filePattern为日志文件名称的格式-->
              <RollingFile name="RollingFile" fileName="${baseDir}/info.log" filePattern="${baseDir}/info.log.%d{yyyy-MM-dd}">
                  <!--日志内容格式-->
                  <PatternLayout pattern="%d %5p %c:%L - %m %throwable{separator( --> )}%n"/>
                  <!--依据时间创建新的日志文件:1d-->
                  <TimeBasedTriggeringPolicy interval="1"/>
                  <DefaultRolloverStrategy>
                      <!-- 在轮转时,删除7天之前的,命名符合规则的文件 -->
                      <Delete basePath="${baseDir}">
                          <IfFileName glob="info.log.*"/>
                          <IfLastModified age="7d"/>
                      </Delete>
                  </DefaultRolloverStrategy>
              </RollingFile>
          </appenders>
          <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
          <loggers>
              <root level="INFO">
                  <appender-ref ref="Console"/>
                  <appender-ref ref="RollingFile"/>
              </root>
              <!--这里配置 过滤日志 -->
              <logger name="org.hibernate.validator" level="ERROR"/>
          </loggers>
      </configuration>
      
    展开全文
  • Log4j2使用总结

    万次阅读 2013-09-08 22:32:59
    Log4j 2 包含了基于LMAX 分离库的下一代的异步日志系统,在多线程环境下,异步日志系统比 Log4j 1.x 和Logback 提高了10倍性能提升(吞吐量和延迟率 )。

    Log4j 2 包含了基于LMAX 分离库的下一代的异步日志系统,在多线程环境下,异步日志系统比 Log4j 1.x 和Logback 提高了10倍性能提升(吞吐量和延迟率 )。原文如下:

    Log4j 2 contains next-generation Asynchronous Loggers based on the LMAX Disruptor library. In multi-threaded scenarios Asynchronous Loggers have 10 times higher throughput and orders of magnitude lower latency than Log4j 1.x and Logback. 

    Log4j2目前已经出到了beta8版本,估计beta9在最近一周将放出,试用了下,感觉还不错,做如下总结!

    我是从logback迁移到log4j2,

     

    删除掉原有的包 log4j-over-slf4j-1.6.4.jar logback-classic-1.0.7.jar logback-core-1.0.7.jar slf4j-api-1.6.4.jar

    增添以下的包 log4j-over-slf4j-1.7.5.jar log4j-api-2.0-beta8.jar log4j-core-2.0-beta8.jar  log4j-slf4j-impl-2.0-beta8.jar

     

    由于作者推荐,为了性能考虑,尽量不要使用slf4j,但我依赖的第三方框架比如spring有对slf4j使用,所以对JAR包做了以上的取舍,所以原有代码中要做如下的改动

     

    改动前:import org.slf4j.Logger;
          import org.slf4j.LoggerFactory;

         private static final Logger logger = LoggerFactory.getLogger(OOXX.class);

     

    改动后:iimport org.apache.logging.log4j.LogManager;
          import org.apache.logging.log4j.Logger;

         private static final Logger logger = LogManager.getLogger(OOXX.class);

    配置文件log4j2.xml如下:

     

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- status=debug 可以查看log4j的装配过程 -->
    <configuration status="off" monitorInterval="1800">
    	<properties>
    		<property name="LOG_HOME">/log/fish</property>
    		<!-- 日志备份目录 -->
    		<property name="BACKUP_HOME">{LOG_HOME}/backup</property>
    		<property name="STAT_NAME">stat</property>
    		<property name="SERVER_NAME">global</property>
    	</properties>
    	<appenders>
    		<!-- 定义控制台输出 -->
    		<Console name="Console" target="SYSTEM_OUT" follow="true">
    			<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />
    		</Console>
    		<!-- 程序员调试日志 -->
    		<RollingRandomAccessFile name="DevLog" fileName="${LOG_HOME}/${SERVER_NAME}"
    			filePattern="${LOG_HOME}/${SERVER_NAME}.%d{yyyy-MM-dd-HH}.log">
    			<PatternLayout pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />
    			<Policies>
    				<TimeBasedTriggeringPolicy interval="1" modulate="true" />
    			</Policies>
    		</RollingRandomAccessFile>
    		<!-- 游戏产品数据分析日志 -->
    		<RollingRandomAccessFile name="ProductLog"
    			fileName="${LOG_HOME}/${SERVER_NAME}_${STAT_NAME}"
    			filePattern="${LOG_HOME}/${SERVER_NAME}_${STAT_NAME}.%d{yyyy-MM-dd-HH}.log">
    			<PatternLayout
    				pattern="%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%thread][%file:%line] - %msg%n" />
    			<Policies>
    				<TimeBasedTriggeringPolicy interval="1"
    					modulate="true" />
    			</Policies>
    		</RollingRandomAccessFile>
    	</appenders>
    	<loggers>
    		<!-- 3rdparty Loggers -->
    		<logger name="org.springframework.core" level="info">
    		</logger>
    		<logger name="org.springframework.beans" level="info">
    		</logger>
    		<logger name="org.springframework.context" level="info">
    		</logger>
    		<logger name="org.springframework.web" level="info">
    		</logger>
    		<logger name="org.jboss.netty" level="warn">
    		</logger>
    		<logger name="org.apache.http" level="warn">
    		</logger>
    		<logger name="com.mchange.v2" level="warn">
    		</logger>
    		<!-- Game Stat  logger -->
    		<logger name="com.u9.global.service.log" level="info"
    			additivity="false">
    			<appender-ref ref="ProductLog" />
    		</logger>
    		<!-- Root Logger -->
    		<root level="DEBUG" includeLocation="true">
    			<appender-ref ref="DevLog" />
    			<appender-ref ref="Console" />
    		</root>
    	</loggers>
    </configuration>

     

     TimeBased Triggering Policy

     

    基于时间的触发策略。该策略主要是完成周期性的log文件封存工作。有两个参数:

    interval,integer型,指定两次封存动作之间的时间间隔。单位:以日志的命名精度来确定单位,比如yyyy-MM-dd-HH 单位为小时,yyyy-MM-dd-HH-mm 单位为分钟

    modulate,boolean型,说明是否对封存时间进行调制。若modulate=true,则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00,。。。

     

     

     

     

    存在问题:在Eclipse下一切运行正常,如果把应用打包成jar包发布后,cmd命令行模式下,即使Console开着的情况下,也没法输出,文件输出也没有任何日志。

     

    问题已经解决,需要在MANIFEST.MF文件里Class-Path 最前加个'.',目的是让与jar包平级的配置文件log4j2.xml加载进来。

    比如

    Class-Path: . lib/antlr-2.7.6.jar lib/other.jar

    这样,就把包含了log4j2.xml的路径放到了classpath,因此,log4j2能读取这个文件。感谢老外Jacob Kjome的回复!

    log4j2 在Web的应用,把log4j2.xml放在src根目录下,不需要任何在代码级别的设置,直接类似JAVA应用一样使用,但把servlet改成了servlet3.0,因为官网上描述如下:

     

    The Short Story
    Log4j 2 "just works" in Servlet 3.0 and newer web applications. It is capable of automatically starting when the application deploys and shutting down when the application undeploys.Important Note! For performance reasons, containers often ignore certain JARs known not to contain TLDs or ServletContainerInitializers and do not scan them for web-fragments and initializers. Importantly, Tomcat 7 <7.0.43 ignores all JAR files named log4j*.jar, which prevents this feature from working. This has been fixed in Tomcat 7.0.43, Tomcat 8, and later. In Tomcat 7 <7.0.43 you will need to change catalina.properties and remove "log4j*.jar" from the jarsToSkip property. You may need to do something similar on other containers if they skip scanning Log4j JAR files.

     

     

    但发现在eclipse下servlet2.0 也可以用的,并且不用修改catalina.properties文件。我用的是apache-tomcat-7.0.42,很奇怪!

     

    有时候,为了同一份log4j文件要支持写到不同的log中(否则会导致打印的内容被覆盖,其中一个进程写不进log等问题),需要在载入的时候对内容进行动态修改,比如根据server id分别生成game1.log,game2.log

    可以代码进行加载log4文件

     

    File file = new File("log4j2.xml");
    		BufferedInputStream in = null;
    		try {
    			in = new BufferedInputStream(new FileInputStream(file));
    <span style="white-space:pre">			</span><strong><span style="color:#33cc00;">//TODO 先进行文本修改</span></strong>
    			final ConfigurationSource source = new ConfigurationSource();
    			source.setInputStream(in);
    			Configurator.initialize(null, source);
    		} catch (FileNotFoundException e) {
    			e.printStackTrace();
    		}

     

    要使用异步写日志的功能,必须引入Disruptor

     

    <asyncRoot> or <asyncLogger>

    官方建议一般程序员查看的日志改成异步方式,一些运营日志改成同步

     

    Asynchronous Appenders 和 Asynchronous Loggers 区别:

    在</appenders> 节点里添加

      <Async name="Async">
          <AppenderRef ref="MyFile"/>
        </Async>

    Asynchronous Appenders 性能比同步快,比Asynchronous Loggers慢

    在loggers节点添加

        <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
          <AppenderRef ref="RandomAccessFile"/>
        </AsyncLogger>

    或者添加

    <!-- Root Logger -->
    <asyncRoot level="DEBUG">
    <appender-ref ref="DevLog" />
    <appender-ref ref="Console" />
    </asyncRoot>

    为logger async 用的是无锁并发技术,必须引入Disruptor

    测试了下,单线程异步比同步效率提高了1倍。线程越多性能提高越明显。

    如果要加上位置信息比如哪个类,第几行,需要设置 includeLocation="true" 但默认不设置好像也是true,

    location 主要包含了如下:

    If one of the layouts is configured with a location-related attribute like HTML locationInfo, or one of the patterns %C or $class%F or %file%l or %location%L or %line%M or %method, Log4j will take a snapshot of the stack, and walk the stack trace to find the location information.

    ====================

    log4j2最终输出点

    AbstractOutputStreamAppender .append(final LogEvent event)

     

    ====================

    以下要翻译

    shutdownHook="disable"

    log4j也有ShutdownHook的程序,并且提前执行了,导致提前关闭了日志。

    log4j可以配置不开启ShutdownHook

     

    immediateFlush boolean

    When set to true - the default, each write will be followed by a flush. This will guarantee the data is written to disk but could impact performance.

    Flushing after every write is only useful when using this appender with synchronous loggers. Asynchronous loggers and appenders will automatically flush at the end of a batch of events, even if immediateFlush is set to false. This also guarantees the data is written to disk but is more efficient.

    bufferSize int The buffer size, defaults to 262,144 bytes (256 * 1024).If an integer greater than 0, this causes the appender to buffer log events and flush whenever the buffer reaches this size.
    AsyncLogger.RingBufferSize 256 * 1024 Size (number of slots) in the RingBuffer used by the asynchronous logging subsystem. Make this value large enough to deal with bursts of activity. The minimum size is 128. The RingBuffer will be pre-allocated at first use and will never grow or shrink during the life of the system.

     

     

     

    Making All Loggers Asynchronous

     

    Requires disruptor-3.0.0.jar or higher on the classpath.

    This is simplest to configure and gives the best performance. To make all loggers asynchronous, add the disruptor jar to the classpath and set the system property Log4jContextSelector toorg.apache.logging.log4j.core.async.AsyncLoggerContextSelector.

    By default, location is not passed to the I/O thread by asynchronous loggers. If one of your layouts or custom filters needs location information, you need to set "includeLocation=true" in the configuration of all relevant loggers, including the root logger.

    A configuration that does not require location might look like:

    
     
    1. <?xml version="1.0" encoding="UTF-8"?>
    2.  
    3. <!-- Don't forget to set system property
    4. -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
    5. to make all loggers asynchronous. -->
    6.  
    7. <Configuration status="WARN">
    8. <Appenders>
    9. <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
    10. <RandomAccessFile name="RandomAccessFile" fileName="async.log" immediateFlush="false" append="false">
    11. <PatternLayout>
    12. <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
    13. </PatternLayout>
    14. </RandomAccessFile>
    15. </Appenders>
    16. <Loggers>
    17. <Root level="info" includeLocation="false">
    18. <AppenderRef ref="RandomAccessFile"/>
    19. </Root>
    20. </Loggers>
    21. </Configuration>

    When AsyncLoggerContextSelector is used to make all loggers asynchronous, make sure to use normal <root> and <logger> elements in the configuration. The AsyncLoggerContextSelector will ensure that all loggers are asynchronous, using a mechanism that is different from what happens when you configure <asyncRoot> or <asyncLogger>. The latter elements are intended for mixing async with sync loggers. If you use both mechanisms together you will end up with two background threads, where your application passes the log message to thread A, which passes the message to thread B, which then finally logs the message to disk. This works, but there will be an unnecessary step in the middle.

    There are a few system properties you can use to control aspects of the asynchronous logging subsystem. Some of these can be used to tune logging performance.

     

     

     

    展开全文
  • log4j2模板,log4j模板,log4j相关属性

    千次阅读 多人点赞 2020-10-16 17:34:32
    log4j2模板1.1 `pom.xml`依赖1.2 `log4j2.xml`配置文件1.3 java中使用2. log4j模板2.1 `pom.xml`依赖2.2 `log4j.properties` 源配置2.3 `log4j.properties` 配置解释【***】2.4 java中使用学习参考地址 1. log4j2...
  • log4j2

    千次阅读 2017-03-10 15:53:53
    1 log4j自定义日志级别 项目上遇到获取前端请求,在请求第三方系统,担心这个性能问题 所以需要打印出请求花费的时间,好做分析。 一开始想用log4j info级别输出,结果发现info日志打印的太多了,会将打印的时间打乱...
  • Log4j2-Log4j 2介绍及使用

    万次阅读 2017-07-15 11:08:39
    Log4j 2 官网https://logging.apache.org/log4j/2.x/Log4j 2简介Log4j的1.x版本已经被广泛使用于很多应用程序中。然而,它这些年的发展已经放缓。它变得越来越难以维护,因为它需要严格遵循很老的Java版本,并在2015...
  • Java Log4j和Log4j2的区别

    千次阅读 2019-06-28 19:01:56
    Java Log4j和Log4j2的区别 一、核心JAR包 log4j核心包:log4j:log4j:[version] 而log4j2的核心包有2个: org.apache.logging.log4j:log4j-core:[version] org.apache.logging.log4j:log4j-api:[version] 二、...
  • log4j升级至log4j2

    千次阅读 2018-06-11 17:30:33
    本文主要内容包含:实现log4j升级至log4j2,并实现日志自动删除的操作步骤以及注意事项。 一、升级原因: log4j存在天然缺陷: log4j采用同步输出模式,当遇到高并发&amp;日志输出过多情况,可能导致线程...
  • log4j,log4j2冲突问题

    2019-01-17 16:25:00
    项目中使用了log4j2,而第三方jar包使用了log4j,可以通过引入log4j-1.2-api包,将log4j的日志桥接到log4j2,从而解决日志冲突问题 转载于:https://www.cnblogs.com/yjcblog/p/10282945.html...
  • slf4j与log4j、log4j2

    2018-11-15 17:53:01
    最近公司项目系统需要将日志从log4j+slf4j升级为log4j2,然后彻彻底底的把它们研究了一遍,在网上查找相关资源,发现并没有一篇文章能够很完整的把它们之间的关联和区别写出来,所以我在这里做一个总结。log4j  ...
  • Log4j2官方文档翻译--欢迎使用Log4j2

    千次阅读 2018-09-19 17:07:30
    官网原文标题《Welcome to Log4j 2!》 ... 译者:本文介绍了Log4j的发展历史。...读者在学习log4j2前建议最先阅读此文 后续阅读:《Log4j2官方文档翻译--架构》 介绍 几乎所有大型应用都有它自己的log或者tracing A...
  • Spring Boot系列教程六:日志输出配置log4j2

    万次阅读 热门讨论 2017-01-11 21:21:21
    spring boot支持的日志框架有,logback,Log4j2,Log4j和Java Util Logging,默认使用的是logback日志框架,笔者一直在使用log4j2,并且看过某博主写的一篇这几个日志框架的性能比对,决定仍使用log4j2,本文章主要...
  • Log4j无缝升级到Log4j2+Slf4j

    千次阅读 2019-05-07 17:21:13
    Step1: 修改maven项目的pom.xml 移除原有项目log4j的依赖内容模块 加入以下内容,属性部分加入 ...--设置Log4j2 跟 slfj0--> <log4j.version>2.11.2</log4j.version> <slf4j.ver...
  • log4j2配置文件log4j2.xml配置详解

    万次阅读 2017-04-07 15:14:04
    log4j2配置文件log4j2.xml配置详解
  • log4j2 日志的 log4j2.component.properties 文件内容 此文件会随着时间不断更新 log4j2.loggerContextFactory=org.apache.logging.log4j.core.impl.Log4jContextFactory log4j.configurationFile=log4j/log4...
  • 文章目录常用日志框架Log4jLogbackLog4j 2Log4j1/Logback/Log4j2性能比较日志门面SLF4J 常用日志框架 Log4j Log4j是Apache的一个Java的日志库,通过使用Log4j,我们可以控制日志信息输送的目的地(控制台、文件、...
  • log4j2配置文件log4j2.xml

    千次阅读 2017-03-11 14:51:23
    log4j2 + slf4j
  • Log4j日志配置详解(Log4j2)

    万次阅读 2018-07-26 10:48:44
    一、Log4j升级Log4j2 首先来说一下日志升级,log4j配置的变化,配置文件从log4j.xml变成了log4j2.xml,配置文件的内容也有很大不同,log file现在可以同时支持时间和文件大小分割。而且log4j2支持log的动态变化加载...
  • Log4j和Log4j2的区别

    千次阅读 2017-11-22 09:06:55
    log4j是Apache的一个开源项目,log4j2和log4j是一个作者,只不过log4j2是重新架构的一款日志组件,他抛弃了之前log4j的不足,以及吸取了优秀的logback的设计重新推出的一款新组件。log4j2的社区活跃很频繁而且更新的...
  • log4j和log4j2怎么动态加载配置文件

    千次阅读 2018-12-26 01:37:00
    当项目在运行时,我们如果需要修改log4j 1.X或者log4j2的配置文件,一般来说我们是不能直接将项目停止运行再来修改文件重新部署的。于是就有这样一个问题:如何在不停止当前项目的运行的情况下,让系统能够自动地...
  • log4j2配置文件log4j2.xml解析

    千次阅读 2017-04-26 18:11:37
    转载网址:http://www.cnblogs.com/hafiz/p/6170702.html一、背景 最近由于项目的需要,我们把log4j 1.x的版本全部迁移成log4j 2.x 的版本,那随之而来的slf4j整合log4j的配置...本文就专门来讲解下log4j2.xml配置
  • Slf4j与log4j及log4j2的关系及使用方法

    千次阅读 2018-10-11 13:08:31
    Slf4j与log4j及log4j2的关系及使用方法   slf4j slf4j仅仅是一个为Java程序提供日志输出的统一接口,并不是一个具体的日志实现方案,就比如JDBC一样,只是一种规则而已,所以单独的slf4j是不能工作的,必须搭配...
  • Log_Log4j2_Log4j2 的 Appenders

    千次阅读 2017-02-06 19:06:11
    前言  Appender按网络释义,有“输出目的地”之意。官网给出的定义是:“Appenders are...Log4j2为使用者提供了13种非常实用的Appenders,使用者可用方便的调用这13种Appender来控制日志的输出。 摘要  Log4j2的Ap
  • 关于Log4j 1.x 升级Log4j 2.x 那些事

    千次阅读 2019-09-20 12:35:37
    log4j 1.x 升级log4j 2.x 踩坑攻略

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 31,229
精华内容 12,491
关键字:

log4j2