日志(常用的日志框架)

常用日志框架

Log4j

Log4j是Apache的一个Java的日志库,通过使用Log4j,我们可以控制日志信息输送的目的地(控制台、文件、数据库等);我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。

Logback

Logback,一个“可靠、通用、快速而又灵活的Java日志框架”。logback当前分成三个模块:logback-core,logback- classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日志系统,如log4j或JDK14 Logging。logback-access模块与Servlet容器(如Tomcat和Jetty)集成,以提供HTTP访问日志功能。请注意,您可以在logback-core之上轻松构建自己的模块。

Log4j2

Apache Log4j 2是对Log4j的升级,它比其前身Log4j 1.x提供了重大改进,并提供了Logback中可用的许多改进,同时修复了Logback架构中的一些问题。

现在最优秀的Java日志框架是Log4j2,没有之一。根据官方的测试表明,在多线程环境下,Log4j2的异步日志表现更加优秀。在异步日志中,Log4j2使用独立的线程去执行I/O操作,可以极大地提升应用程序的性能。

三个框架性能比较:

在这里插入图片描述

作用

调试

在Java项目调试时,查看栈信息可以方便地知道当前程序的运行状态,输出的日志便于记录程序在之前的运行结果。如果你大量使用System.out或者System.err,这是一种最方便最有效的方法,但显得不够专业。

错误定位

不要以为项目能正确跑起来就可以高枕无忧,项目在运行一段时候后,可能由于数据问题,网络问题,内存问题等出现异常。这时日志可以帮助开发或者运维人员快速定位错误位置,提出解决方案。

数据分析

大数据的兴起,使得大量的日志分析成为可能,ELK也让日志分析门槛降低了很多。日志中蕴含了大量的用户数据,包括点击行为,兴趣偏好等,用户画像对于公司下一步的战略方向有一定指引作用。

Log4j2

Apache Log4j 2是对Log4j的升级,它比其前身Log4j 1.x提供了重大改进,并提供了Logback中可用的许多改进,同时修复了Logback架构中的一些问题。是目前最优秀的Java日志框架,没有之一。

特征

API分离

Log4j的API与实现分开,使应用程序开发人员可以清楚地了解可以使用哪些类和方法,同时确保向前兼容性。这使Log4j团队能够以安全且兼容的方式进行改进。

性能提升

Log4j 2包含基于LMAX Disruptor库的下一代异步记录器。在多线程场景中,异步记录器的吞吐量比Log4j 1.x和Logback高18倍,延迟低。

自动重新加载配置

与Logback一样,Log4j 2可以在修改时自动重新加载其配置。与Logback不同,它会在重新配置发生时不会丢失日志事件。

高级过滤

与Logback一样,Log4j 2支持基于Log事件中的上下文数据,标记,正则表达式和其他组件进行过滤。此外,过滤器还可以与记录器关联。与Logback不同,您可以在任何这些情况下使用通用的Filter类。

插件架构

Log4j使用插件模式配置组件。因此,您无需编写代码来创建和配置Appender,Layout,Pattern Converter等。在配置了的情况下,Log4j自动识别插件并使用它们。

无垃圾机制

在稳态日志记录期间,Log4j 2 在独立应用程序中是无垃圾的,在Web应用程序中是低垃圾。这减少了垃圾收集器的压力,并且可以提供更好的响应性能。

使用

引用依赖

要注意,同时引入spring-boot-starter和spring-boot-starter-web依赖时,需要在spring-boot-starter中排除spring-boot-starter-logging依赖,因为spring-boot-starter-web依赖于spring-boot-starter,根据Maven依赖关系,在spring-boot-starter中排除spring-boot-starter-logging依赖才能排除成功。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <!-- 排除spring boot默认日志logback -->
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<!-- 引入log4j2依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
添加配置文件

默认情况下,Log4j2在classpath下查找名为log4j2.xml的配置文件。你也可以使用Java启动命令指定配置文件的全路径。-Dlog4j.configurationFile=opt/demo/log4j2.xml,你还可以使用Java代码指定配置文件路径:

public static void main(String[] args) {

    LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
    File file = new File("opt/demo/log4j2.xml");
    loggerContext.setConfigLocation(file.toURI());

}
异步配置文件

Log4j-2.9及更高版本在类路径上需要disruptor-3.3.4.jar或更高版本。在Log4j-2.9之前,需要disruptor-3.0.0.jar或更高版本

默认情况下,异步记录器不会将位置传递给I / O线程。如果您的某个布局或自定义过滤器需要位置信息,则需要在所有相关记录器的配置中设置“includeLocation = true”,包括根记录器。

  1. 引入disruptor依赖

    <dependency>
        <groupId>com.lmax</groupId>
        <artifactId>disruptor</artifactId>
        <version>3.4.2</version>
    </dependency>
    
  2. 在src/java/resources目录添加log4j2.component.properties配置文件

    # 设置异步日志系统属性
    log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
    
  3. 配置如下所示:

    通过log.info(“是否为异步日志:{}”, AsyncLoggerContextSelector.isSelected());可以查看是否为异步日志。

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
    
        <Properties>
            <!-- 日志输出级别 -->
            <Property name="LOG_INFO_LEVEL" value="info"/>
            <!-- error级别日志 -->
            <Property name="LOG_ERROR_LEVEL" value="error"/>
            <!-- 在当前目录下创建名为log目录做日志存放的目录 -->
            <Property name="LOG_HOME" value="./log"/>
            <!-- 档案日志存放目录 -->
            <Property name="LOG_ARCHIVE" value="./log/archive"/>
            <!-- 模块名称, 影响日志配置名,日志文件名,根据自己项目进行配置 -->
            <Property name="LOG_MODULE_NAME" value="spring-boot"/>
            <!-- 日志文件大小,超过这个大小将被压缩 -->
            <Property name="LOG_MAX_SIZE" value="100 MB"/>
            <!-- 保留多少天以内的日志 -->
            <Property name="LOG_DAYS" value="15"/>
            <!--输出日志的格式:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度, %msg:日志消息,%n是换行符 -->
            <Property name="LOG_PATTERN" value="%d [%t] %-5level %logger{0} - %msg%n"/>
            <!--interval属性用来指定多久滚动一次-->
            <Property name="TIME_BASED_INTERVAL" value="1"/>
        </Properties>
    
        <Appenders>
            <!-- 控制台输出 -->
            <Console name="STDOUT" target="SYSTEM_OUT">
                <!--输出日志的格式-->
                <PatternLayout pattern="${LOG_PATTERN}"/>
                <!--控制台只输出level及其以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
                <ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
            </Console>
    
            <!-- 这个会打印出所有的info级别以上,error级别一下的日志,每次大小超过size或者满足TimeBasedTriggeringPolicy,则日志会自动存入按年月日建立的文件夹下面并进行压缩,作为存档-->
            <!--异步日志会自动批量刷新,所以将immediateFlush属性设置为false-->
            <RollingRandomAccessFile name="RollingRandomAccessFileInfo"
                                     fileName="${LOG_HOME}/${LOG_MODULE_NAME}-infoLog.log"
                                     filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-infoLog-%d{yyyy-MM-dd}-%i.log.gz"
                                     immediateFlush="false">
                <Filters>
                    <!--如果是error级别拒绝,设置 onMismatch="NEUTRAL" 可以让日志经过后续的过滤器-->
                    <ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="DENY" onMismatch="NEUTRAL"/>
                    <!--如果是info\warn输出-->
                    <ThresholdFilter level="${LOG_INFO_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
                </Filters>
                <PatternLayout pattern="${LOG_PATTERN}"/>
                <Policies>
                    <!--interval属性用来指定多久滚动一次,根据当前filePattern设置是1天滚动一次-->
                    <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                    <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
                </Policies>
                <!-- DefaultRolloverStrategy属性如不设置,则默认同一文件夹下最多保存7个文件-->
                <DefaultRolloverStrategy max="${LOG_DAYS}"/>
            </RollingRandomAccessFile>
    
            <!--只记录error级别以上的日志,与info级别的日志分不同的文件保存-->
            <RollingRandomAccessFile name="RollingRandomAccessFileError"
                                     fileName="${LOG_HOME}/${LOG_MODULE_NAME}-errorLog.log"
                                     filePattern="${LOG_ARCHIVE}/${LOG_MODULE_NAME}-errorLog-%d{yyyy-MM-dd}-%i.log.gz"
                                     immediateFlush="false">
                <Filters>
                    <ThresholdFilter level="${LOG_ERROR_LEVEL}" onMatch="ACCEPT" onMismatch="DENY"/>
                </Filters>
                <PatternLayout pattern="${LOG_PATTERN}"/>
                <Policies>
                    <TimeBasedTriggeringPolicy interval="${TIME_BASED_INTERVAL}"/>
                    <SizeBasedTriggeringPolicy size="${LOG_MAX_SIZE}"/>
                </Policies>
                <DefaultRolloverStrategy max="${LOG_DAYS}"/>
            </RollingRandomAccessFile>
    
        </Appenders>
    
        <Loggers>
            <!-- 开发环境使用 -->
            <!--<Root level="${LOG_INFO_LEVEL}">
                <AppenderRef ref="STDOUT"/>
            </Root>-->
    
            <!-- 测试,生产环境使用 -->
            <Root level="${LOG_INFO_LEVEL}" includeLocation="false">
                <AppenderRef ref="RollingRandomAccessFileInfo"/>
                <AppenderRef ref="RollingRandomAccessFileError"/>
            </Root>
        </Loggers>
    
    </Configuration>
    

在这里插入图片描述

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值