日志框架 log4j2 全解析

概述

logging翻译为日志记录

那问题是什么是日志?

日志实际上是日记的一种,用于记录某个时间点发生了什么事情,比如大学老师的教学日志,工作日志等

为什么要记录日志?

在实际生活中记录日志主要为了日后复查,

比如某个大学老师每天记录自己讲的什么内容,后面有学生某科成绩优异获奖了,校长想要奖励对应的老师,但由于每个老师教的班级都很多,并不一定记得是谁教的,这时候就可以查看教学日志来获取需要的信息了

再比如,工厂的生产日志,如果某个产品除了因为某个零件出现了故障,通过生成日志,可以找到与这个产品同批次的其他产品,进行返工,或是通过日志找到该零件的供应商,进行沟通解决!

程序中的日志

我们的程序开发完成后会被不同系统环境的用户下载使用,期间可能就会出现问题,直接把错误信息展示给用户看是没有任何意义的,用户看不懂也不会解决,那这时候就可以将用户执行的所有操作,以及代码运行的过程,记录到日志中,程序员通过分析日志内容,可以快速的定位问题

综上: 日志就是用来记录发生的事件的

日志并不会立即产生作用,而是当程序出现了问题时在去分析日志文件提取有用信息

java下的日志框架

门面

门面是Facade(外观模式)的实现,也称为门面模式,

是对内部多个子系统的封装,并对外提供一套统一的使用接口,从而屏蔽各个子系统在使用上的不同,大大降低了系统的使用难度,同时提高了系统的可维护性和扩展性;

实际上真正干活的还是是内部的子系统;就像给这些子系统加了一层装饰,Facede也得名于此;

图示:

因其性能优越性,实际开发中log4j是使用最多一个日志框架,也是我们需要掌握的目标;

官方性能对比:

log4j

日志级别:

日志级别其实指的就是日志信息应用场景,我们的程序会在不同的环境中运行,某些日志只有用在某些特殊场景中,例如:在开发阶段,我们为了检查错误,会输出一些调试信息,但是这些信息在生产环境下是不需要的,当然.我们可以在发布前删除这些调试代码,但这就显得非常low了,通过对日志信息区别对待,我们可以很方便的控制哪些日志在哪些场景下正常输出;
日志级别也在后续的问题定位中发挥着重要作用,当程序出现了问题,我们要根据日志来定位问题,这时便可以通过日志级别来快速过滤掉不需要的记录;

log4j日志级别:

log4j定义了8个级别,优先级从高到低依次为:

OFF>FATAL> ERROR> WARN> INFO> DEBUG> TRACE> ALL

  • ALL 最低等级的 用于打开所有日志记录
  • TRACE 很低的日志级别 一般不会使用
  • DEBUG 该级别信息对调试应用程序是非常有帮助的 主要用于开发过程中打印 一些运行信息
  • INFO 突出强调应用程序的运行过程。打印一些你感兴趣的或者重要的信息 可用于生产环境中输出程序运行的一些重要信息,但是不能滥用 避免打印过多的日志
  • WARN 表明会出现潜在错误的情形 有些信息不是错误信息 但是也要给程序员的一些提示
  • ERROR 指出虽然发生错误事件 但仍然不影响系统的继续运行。打印错误和异常信息 如果不想输出太多日志 太多数情况下可以使用这个级别
  • FATAL 指出严重的错误事件,将会导致应用程序的退出。
  • OFF 最高等级的,用于关闭所有日志记录

依赖包:

    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>2.5</version>
    </dependency>

配置文件:

2.x往后的版本不在支持properties作为配置文件,因其无法表达较为复杂的语法结构

log4j2会在classpath下查找配置文件,如果找不到则使用基础配置(输出到控制台),log4j支持 xml,json,jsn三种格式的配置文件,并可为测试环境和生产环境编写不同的配置文件;若有多个配置文件log4j将按照以下顺序读取:

  1. classpath下的名为log4j2-test.json 或者log4j2-test.jsn的文件.
  2. classpath下的名为log4j2-test.xml的文件.
  3. classpath下名为log4j2.json 或者log4j2.jsn的文件.
  4. classpath下名为log4j2.xml的文件.

示例log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!--   status="WARN" 用于设置log4j框架本身的日志级别-->
<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="all">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

测试代码:

@Test
    public void test1(){
        Logger myLogger = LogManager.getLogger("myLogger");
        myLogger.debug("debug msg");
    }

Appenders节点:

该节点配置日志信息的输出目的地,可以是控制台,文件,邮件或数据库,控制台和文件是表常用的两个目的地;

上述案例既将日志信息输出到控制台,其子节点PatternLayout用于设置日志输出的字符传格式;

PatternLayout可用的格式化字符:

%d{HH:mm:ss.SSS}    表示输出到毫秒的时间
%t              输出当前线程名称
%-5level    输出日志级别,-5表示左对齐并且固定输出5个字符,如果不足在右边补空格
%logger     输出logger名称,因为Root Logger没有名称
%msg            日志文本
%n              换行
%F              输出所在的类文件名,如Client.java
%L              输出行号
%M              输出所在方法名
%C                          产生log事件的java完全限定类名
%l              输出语句所在的行数, 包括类名、方法名、文件名、行数

输出到文件:

<?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 - %msg%n"/>
        </Console>
        <File name="fileAppender" fileName="logs/app.log" append="false"><!--默认以当前项目为相对路径-->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger - %msg%n"/>
        </File>

    </Appenders>
    <Loggers>
        <Root level="all">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="fileAppender"/><!--一个logger可配置对个appender输出到不同位置-->
        </Root>
    </Loggers>
</Configuration>
<!--File属性:
name用于给appender指定名字,以便logger引用
fileName默认以当前项目为相对路径
append参数表示是否将是追加到文件末尾 默认为true  为false即直接覆盖原文件-->

上面的配置会将所有日志输出到同一个文件,随着时间的推移该文件会越来越大,甚至无法打开,但是实际有用的日志都是近期的产生的,太久远的日志大多数是无用的,这就用到了滚动日志,其可以帮助我们实现日志文件的切割,以及无用日志的删除操作;

滚动日志配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <!--自定义属性信息-->
    <properties>
        <property name="LOG_HOME">logs</property>
        <property name="FILE_NAME">applog</property>
    </properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <!--滚动日志配置
            filePattern用于设置滚动文件的命名规则
                        若以.zip为结尾则会自动归档日志文件 也支持其他的格式.gz, .zip, .bz2, 等-->
        <RollingRandomAccessFile name="RollingAppender"
                                 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{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
            <Policies>
                <!--滚动时间间隔 该参数需结合filePattern中的时间格式 此时表示为1分钟更换一个新文件
                    若时间格式为%d{yyyy-MM-dd HH}则表示每小时更换一个新文件-->
                <TimeBasedTriggeringPolicy interval="1"/>
                <!--单个日志文件最大容量                -->
                <SizeBasedTriggeringPolicy size="1 MB"/>
            </Policies>
            <!--最大保留的日志文件个数  默认为7个          -->
            <DefaultRolloverStrategy max="20"/>
        </RollingRandomAccessFile>
    </Appenders>
    <Loggers>
        <Root level="all">
            <AppenderRef ref="RollingAppender"/>
        </Root>
    </Loggers>
</Configuration>

上述配置的整体含义:统一使用rootLogger,所有级别日志都会被记录到文件中,文件位于项目目录下的logs中,当单个文件超过1MB或是时间超过1分钟后则更换日志文件,最多保存20个日志文件;

补充:RollingFile也是做滚动日志的,但是据官方说效率没有RollingRandomAccessFile高;

Loggers节点:

需求:某个类或模块中产生的需要同时输出到控制台和文件,其他模块则仅输出到控制台,当遇到类似需求时,就需要定义不同的logger了,然后在程序中根据名称获取所需的logger

如果在配置中找不到名称匹配的logger时使用rootLogger;

logger配置:

注意:appender使用的还是上面的例子中的

<Loggers>
    <Root level="all">
        <AppenderRef ref="Console" />
    </Root>
    <Logger name="fileAndConsole" level="all" additivity="false">
        <AppenderRef ref="Console" />
        <AppenderRef ref="RollingAppender" />
    </Logger>
</Loggers>
<!-- additivity表示是否将日志传递给root继续输出 默认为true-->

测试代码:

@Test
public void test1(){
    Logger myLogger = LogManager.getLogger("myLogger");//rootlogger
    Logger myLogger2 = LogManager.getLogger("fileAndConsole");//fileAndConsole

    for (int i = 0;i < 50;i++){
        myLogger.debug("debug msg1");
    }
    for (int i = 0;i < 50;i++){
        myLogger2.debug("debug msg2");
    }
}

msg1将只出现在控制台,而msg2同时出现在控制台和日志文件;

Filter节点:

Filter用于对日志进行过滤,一些情况下我们可能需要对日志进行更加个性化的限制,

例如:

输出日志消息包含某个字符串的

按照时间不同输出到不同文件

日志的生命周期 :

一个日志事件(LogEvent)产生后到最终输出到目的地会经过以下环节:

全局过滤器 -> logger过滤器 -> logger -> appender过滤器 -> appender->输出

无论哪个环节的过滤器,每个过滤器在匹配或是不匹配时都要明确该日志事件的处理方式,包含三种:

  • ACCEPT接受(继续传递该LogEvent)
  • DENY拒绝(直接丢弃该LogEvent)
  • NEUTRAL中立(不清楚该怎么办继续往后传递LogEvent)

全局过滤器:评估结果为接受时,其他全局过滤器将不会再对该事件进行评估,且不再交给Logger过滤器评估

Logger过滤器:评估为拒绝时不再交给Appdener过滤器

Appdener过滤器:最终决定改日志是否输出

通常需要根据实际需求来配置过滤器:

下例配置列出了三种过滤器的示例(无实意义):

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="TRACE" monitorInterval="5" packages="com.kanq.extend.cat.log4j2">
    <Filters>
        <!-- 全局级别Filter -->
        <BurstFilter level="INFO" rate="16" maxBurst="100"/>
    </Filters>
    <Appenders>
        <RollingFile name="RollingFile" fileName="logs/app.log"
                     filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
            <!-- Appender级别的Filter -->
            <BurstFilter level="INFO" rate="16" maxBurst="100"/>
            <PatternLayout>
                <pattern>%d %p %c{1.} [%t] %m%n</pattern>
            </PatternLayout>
            <TimeBasedTriggeringPolicy />
        </RollingFile>
    </Appenders>
    <Loggers>
        <!-- Logger级别的Filter -->
        <Root level="error">
            <BurstFilter level="INFO" rate="16" maxBurst="100"/>
            <AppenderRef ref="RollingFile"/>
        </Root>
    </Loggers>
</Configuration>

过滤器案例:

通过时间过滤器实现将白天和夜晚的是指写入不同位置:

<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="DayAppender" fileName="logs/appDay.log" append="true">
            <TimeFilter start="06:00:00" end="24:00:00" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger - %msg%n"/>
        </File>
        <File name="NightAppender" fileName="logs/appNight.log" append="true">
            <TimeFilter start="24:00:00" end="06:00:00" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger - %msg%n"/>
        </File>
    </Appenders>
    <Loggers>
        <Root level="all">
            <AppenderRef ref="Console" />
            <AppenderRef ref="DayAppender" />
            <AppenderRef ref="NightAppender" />
        </Root>
    </Loggers>
</Configuration>

当然官网还有其他的过滤器,如正则过滤等,大家根据需求选择即可;地址:官方手册

web项目中的使用

web环境下需要额外的依赖包:

<!-- web容器中需要添加log4j-web -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-web</artifactId>
    <version>2.5</version>
</dependency>

controller中的使用:

@Controller
@RequestMapping("/customer")
public class CustomerController {
//为controller添加属性 用于获取一个日志记录器(Logger)
private Logger logger = LogManager.getLogger(this.getClass().getPackage().getName());
@RequestMapping("/list")
    public String getCustomerList(Model model, SearchInfo searchInfo){
        logger.info("request this /list interface");
        //...
    }
}

若配置文件名称不是默认的跨域通过以下代码来加载:

File file = new File("/Users/jerry/LOGfj/src/main/resources/log4j3.xml");
BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
ConfigurationSource source = new ConfigurationSource(in);
Configurator.initialize(null, source);

原文地址:https://www.cnblogs.com/yangyuanhu/p/12336999.html

时间: 2024-08-26 09:23:29

日志框架 log4j2 全解析的相关文章

Android图片加载框架最全解析(二),从源码的角度理解Glide的执行流程

转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/53939176 本文同步发表于我的微信公众号,扫一扫文章底部的二维码或在微信搜索 郭霖 即可关注,每天都有文章更新. 在本系列的上一篇文章中,我们学习了Glide的基本用法,体验了这个图片加载框架的强大功能,以及它非常简便的API.还没有看过上一篇文章的朋友,建议先去阅读 Android图片加载框架最全解析(一),Glide的基本用法 . 在多数情况下,我们想要在界面上加载并展示一

IDEA整合日志框架Log4j2+Slf4j详细配置过程

日志框架这么多,他们之间到底是什么关系呢?笼统的讲就是slf4j是一系列的日志接口,而log4j2.logback是具体实现了接口功能的日志框架.现在的主流日志接口都使用slf4j,而日志的实现就见仁见智了,至于他们的关系请自行百度,此处选择log4j2作为实现框架.网上看到的教程要么对代码没有解释,对新手不友好:要么时间比较久远,跟不上时代.这里使用新版本并结合大量注释,力求简洁明了,有什么问题欢迎留言交流. 运行环境: log4j2 2.8.1 + slf4j 1.7.25 IntelliJ

从零打造在线网盘系统之Struts2框架配置全解析

欢迎浏览Java工程师SSH教程从零打造在线网盘系统系列教程,本系列教程将会使用SSH(Struts2+Spring+Hibernate)打造一个在线网盘系统,本系列教程是从零开始,所以会详细以及着重地阐述SSH三个框架的基础知识,第四部分将会进入项目实战,如果您已经对SSH框架有所掌握,那么可以直接浏览第四章,源码均提供在GitHub/ssh-network-hard-disk上供大家参阅 要想学好一个框架,就必须要学好如何配置好这个框架,下面让我们大体上来一起来了解一下Struts2的相关配

Spring Boot + Log4j2 日志框架配置 (Maven)

参考Spring Boot官方文档 日志部分 Spring Boot默认情况下,当使用"Starters" 使用Logback输出日志, 还包括适当的Logback路由, 确保其他的日志框架(Java Util Logging, Commons Logging, Log4j, SLF4J)都能正常使用 Sping Boot文档的 26.5 Custom Log Configuration 章节,说明了自定义日志配置方法 多样的日志系统可以通过 添加适当的日志框架库到classpath

Java日志框架研究及常见配置

按照基本的定义,日志即是对程序运行过程中关键事件的记录:大体日志分为运行日志和开发日志,运行日志在业务层面记录一些关键事件,为后面的跟踪运行提供帮助,而开发日志大多数时候是调试日志,根据事件流的输出来调试程序:因为开发人员本身的关注领域,运行日志可能制作的比较少,难以达到跟踪业务流的作用,而即使是开发日志,因为开发的调试有各种技巧,即使是跟踪事件流,使用println也比日志配置简单多了,这是一个投资回报的问ti,而人经常性的是短视的,调试可能在这些人眼里根本不需要认真对待,没有前期的事件记录规

MySQL慢日志查询全解析:从参数、配置到分析工具【转】

转自: MySQL慢日志查询全解析:从参数.配置到分析工具 - MySQL - DBAplus社群——围绕数据库.大数据.PaaS云,运维圈最专注围绕“数据”的学习交流和专业社群http://dbaplus.cn/news-11-694-1.html 一.慢查询日志概念 MySQL的慢查询日志是MySQL提供的一种日志记录,它用来记录在MySQL中响应时间超过阀值的语句,具体指运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中.long_query_time的默认值为

log4j2使用入门(二)——与不同日志框架的适配

在上方中已经指出log4j2可以与不同的日志框架进行适配,这里举一些实际应用进行说明: 1.比如我们在项目中使用了log4j2作为日志器,使用了log4j-api2.6.2.jar和log4j-core2.6.2.jar.但项目中引用了一些中间件(例如activemq),而由于activemq用到了slf4j,这样我们项目目前将不能输出activemq中的日志.解决方法如下:在项目中加入log4j2提供的log4j-slf4j-impl2.6.2.jar就可以了.此处要注意的是,不要误用了log

springboot整合log4j2日志框架

springboot依赖中默认引入spring-boot-starter-logging,若要使用log4j2日志框架,则需要先将spring-boot-starter-logging排除. 方法: 在依赖关系图中找到spring-boot-starter-logging,单击右键选择exclude将其排除出去. pom文件中引入: <dependency> <groupId>org.springframework.boot</groupId> <artifact

JAVAEE——SpringBoot日志篇:日志框架SLF4j、日志配置、日志使用、切换日志框架

Spring Boot 日志篇 1.日志框架(故事引入) 小张:开发一个大型系统: ? 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件? ? 2.框架来记录系统的一些运行时信息:日志框架 : zhanglogging.jar: ? 3.高大上的几个功能?异步模式?自动归档?xxxx? zhanglogging-good.jar? ? 4.将以前框架卸下来?换上新的框架,重新修改之前相关的API:zhanglogging-prefect.ja