Java日志系统log4j2的使用配置和异步日志使用

news2024/11/16 17:45:30

目录

  • 1. log4j2
    • 1.1 log4j2介绍
    • 1.2 Log4j2入门
      • 1.2.1 log4j2(日志门面 + 日志框架)使用
      • 1.2.2 slf4j + log4j2使用
    • 1.3 Log4j2配置
    • 1.4 Log4j2异步日志
      • 1.4.1 全局异步AsyncLogger
      • 1.4.2 混合异步AsyncLogger
      • 1.4.3 AsyncAppender

1. log4j2

1.1 log4j2介绍

Apache Log4j2是Log4j的升级版,参考了logback一些优秀的设计,并且修复了logback的一些问题,而且性能上也有了重大提升,主要有:

  • log4j2对Appender提供了一些异常处理机制
  • 参考了logback的设计,提供自动刷新参数配置,可以自动重载配置而不用重启应用
  • log4j2利用缓冲区和重用对象,几乎不会产生临时对象,从而实现无垃圾机制

1.2 Log4j2入门

虽然Log4j2既是日志门面,也是日志框架。但还是推荐使用流行的日志门面slf4j + 功能强大且性能优越的日志框架log4j2

1.2.1 log4j2(日志门面 + 日志框架)使用

在pom.xml添加依赖

        <!-- log4j2日志门面 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.18.0</version>
        </dependency>

        <!-- log4j2日志框架 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.18.0</version>
        </dependency>

程序如下:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


public class Log4j2Test {
    public static final Logger LOGGER = LogManager.getLogger(Log4j2Test.class);

    public static void main(String[] args) {

        // 默认只打印error及以上级别的日志
        LOGGER.fatal("fatal");
        LOGGER.error("error");
        LOGGER.warn("warn");
        LOGGER.info("info");
        LOGGER.debug("debug");
        LOGGER.trace("trace");

    }
}

运行程序,结果如下:

17:51:14.737 [main] FATAL Log4j2Test - fatal
17:51:14.744 [main] ERROR Log4j2Test - error

默认只打印error及以上级别的日志。后面可以通过log4j2.xml日志配置文件进行日志级别和日志输出格式的配置

1.2.2 slf4j + log4j2使用

在pom.xml添加依赖

        <!-- log4j2日志门面 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.18.0</version>
        </dependency>

        <!-- log4j2日志框架 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.18.0</version>
        </dependency>

        <!-- slf4j日志门面 -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.36</version>
        </dependency>

        <!--log4j2的适配器,为slf4j绑定日志框架 -->
        <!-- 依赖org.slf4j:slf4j-api:1.7.25 -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.18.0</version>
        </dependency>

程序如下:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class Log4j2Test {

    public final static Logger LOGGER = LoggerFactory.getLogger(Log4j2Test.class);

    public static void main(String[] args) {

        // 默认只打印error级别的日志
        LOGGER.error("error");
        LOGGER.warn("warn");
        LOGGER.info("info");
        LOGGER.debug("debug");
        LOGGER.trace("trace");

    }
}

运行程序,结果如下:

18:07:44.628 [main] ERROR Log4j2Test - error

默认只打印error级别的日志。后面可以通过log4j2.xml日志配置文件进行日志级别和日志输出格式的配置

1.3 Log4j2配置

在classpath,比如resources目录下,新建log4j2.xml日志配置文件。内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--  status="warn": 日志框架本身的输出日志级别, 默认是warn。日志框架本身的日志输出到控制台 -->
<!-- monitorInterval="5":自动加载log4j2.xml文件的时间间隔, -->
<Configuration status="warn" monitorInterval="5">

    <!-- 定义属性,供其它标签引用。引用方式${name} -->
    <properties>
        <property name="LOG_HOME">C:/Users/dell/Desktop/java11Test/logs</property>
    </properties>

    <!-- 日志处理器 -->
    <Appenders>
        <!-- 控制台输出appender。可选值:SYSTEM_OUT、SYSTEM_ERR -->
        <Console name="Console" target="SYSTEM_OUT">
            <!--
            %d{yyyy-MM-dd HH:mm:ss.SSS}: 日志日期及其格式
            %t/%thread: 日志执行的线程
            %-5level: 日志级别输出占5个字符,左对其
            %c{36}: 日志执行的类的全限定名, 深度为36
            %M: 日志执行的方法名
            %L: 日志执行的具体行号
            %l: 日志执行的位置信息
            %m/%msg: 日志的消息
            %n: 换行符
            -->
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] %l --- %msg%n" />
        </Console>

        <!-- 日志文件输出appender -->
        <File name="File" fileName="${LOG_HOME}/myFile.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] %l --- %msg%n" />
        </File>

        <!-- 使用随机读写流的日志文件输出appender,性能高 -->
        <RandomAccessFile name="RandomAccessFile" fileName="${LOG_HOME}/myAccessFile.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] %l --- %msg%n" />
        </RandomAccessFile>

        <!-- 按照一定规则拆分日志文件的appender -->
        <!-- filePattern: 拆分后的文件名。拆分规则如下:
        以天为单位,拆分成文件夹
        一天内按照分钟为单位生成一个日志文件。和policy的TimeBasedTriggeringPolicy对应
        日志文件到达指定大小,再按照指定大小进行拆分,文件序号从1开始递增。和policy的SizeBasedTriggeringPolicy对应
        -->
        <RollingFile name="RollingFile" fileName="${LOG_HOME}/myRollingFile.log" filePattern="${LOG_HOME}/$${date:yyyy-MM-dd}/myRollingFile-%d{yyyy-MM-dd-HH-mm}-%i.log">
            <!-- 日志级别过滤器。高于等于debug级别的(比如info)进行日志记录,低于debug级别的进行拦截 -->
            <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY" />
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] %l --- %msg%n" />
            <!-- 日志消息拆分的规则 -->
            <Policies>
                <!-- 在系统启动时,进行拆分,生成一个新的日志文件进行新日志消息的记录。原来的日志文件按照日志记录时间(非启动时间)归档成一个新的归档日志文件 -->
                <OnStartupTriggeringPolicy />
                <!-- 按照文件大小进行拆分 -->
                <SizeBasedTriggeringPolicy size="10 MB" />
                <!-- 按照时间间隔拆分,规则根据filePattern定义的 -->
                <TimeBasedTriggeringPolicy />
            </Policies>
            <!-- 在同一分钟下,文件的个数限定为30个,超过则进行滚动覆盖(文件序号最大为30) -->
            <DefaultRolloverStrategy max="30" />
        </RollingFile>
    </Appenders>

    <Loggers>
        <!-- 配置日志级别 -->
        <Root level="INFO">
            <!-- 指定日志输出appender。不指定File、RandomAccessFile、RollingFile,也会创建空日志文件 -->
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

1.4 Log4j2异步日志

同步日志处理流程图如下:

同步日志处理流程图异步日志处理流程图如下:

异步日志处理流程图log4j2的异步日志带来了很大的性能提升。为了实现异步日志需要在pom.xml添加如下依赖:

        <!-- org.apache.logging.log4j:log4j:2.18.0依赖com.lmax:disruptor:3.4.4 -->
        <!-- 异步日志依赖 -->
        <dependency>
            <groupId>com.lmax</groupId>
            <artifactId>disruptor</artifactId>
            <version>3.4.4</version>
        </dependency>

提供了两种异步日志实现方法,一个是AsyncLogger(对应Logger组件,推荐使用),一个是AsyncAppender(对应Appender组件)

log4j2的全局异步AsyncLogger性能最好,第二个是混合异步AsyncLogger,性能最差的是AsyncAppender(和同步日志相比没有什么性能提升。和logback性能一样)

如果使用异步日志,全局异步AsyncLogger、混合异步AsyncLogger、AsyncAppender,不要同时使用。否则会使用性能较低的一种异步方式

1.4.1 全局异步AsyncLogger

所有appender的所有日志级别的日志都异步的记录,不需要改动log4j2.xml配置文件。只需要在classpath,比如resources目录下,新建log4j2.component.properties配置文件。内容如下:

Log4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector

1.4.2 混合异步AsyncLogger

可以同时使用同步日志和异步日志,这使得日志的配置方式更加灵活

log4j2.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="5">

    <properties>
        <property name="LOG_HOME">C:/Users/dell/Desktop/java11Test/logs</property>
    </properties>

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] %l --- %msg%n" />
        </Console>
    </Appenders>

    <Loggers>
        <!-- 自定义异步logger对象, name必须是LoggerFactory.getLogger(Log4j2Test.class)对应 -->
        <!-- 如果设置includeLocation=true, 开启日志记录行号信息会急剧降低异步日志的性能,比同步日志还要慢 -->
        <!-- 这里设置includeLocation=false,则PatternLayout的%l将不会打印出来 -->
        <!-- additivity="false": 不再继承RootLogger对象. 这里建议强制设置成false -->
        <AsyncLogger name="Log4j2Test" level="WARN" includeLocation="false" additivity="false">
            <AppenderRef ref="Console"/>
        </AsyncLogger>

        <!-- RootLogger是同步的。除Log4j2Test外,其它名称的logger使用RootLogger进行输出 -->
        <Root level="INFO">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

输出如下:

2022-07-10 15:55:23.037 [main] [ERROR]  --- error
2022-07-10 15:55:23.039 [main] [WARN ]  --- warn

可以看到打印了WARN级别的日志,且没有打印日志执行的位置信息

1.4.3 AsyncAppender

log4j2.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" monitorInterval="5">

    <properties>
        <property name="LOG_HOME">C:/Users/dell/Desktop/java11Test/logs</property>
    </properties>

    <Appenders>
        <File name="File" fileName="${LOG_HOME}/myFile.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%-5level] %l --- %msg%n" />
        </File>

        <!-- AsyncAppender引用appender -->
        <Async name="Async">
            <AppenderRef ref="File"/>
        </Async>
    </Appenders>

    <Loggers>
        <Root level="INFO">
            <!-- 直接引用AsyncAppender -->
            <AppenderRef ref="Async" />
        </Root>
    </Loggers>
</Configuration>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/170734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IB地理学什么?适合什么人学习?

IB精选&#xff1a;IB地理学什么&#xff1f;快速搞懂自己适不适合修读地理&#xff01; 核心目的IB地理科是一个很特别的科目&#xff0c;目的是要帮助同学掌握一些认识和了解现实世界的技能。这个现实世界包括了两大部分。 第一个部分是自然环境&#xff0c;当中包括生态系统…

你还在恐惧指针吗?点进来,带你全方位深入了解指针

指针是什么&#xff1f; 指针也就是内存地址&#xff0c;指针变量是用来存放内存地址的变量。(存放在指针中的值都被当做地址处理) 对于32位的机器&#xff0c;假设有32根地址线&#xff0c;那么假设每根地址线在寻找地址的时候会产生高电平&#xff08;高电压&#xff09;和…

[ZJCTF 2019]NiZhuanSiWei

目录 信息收集 代码审计 第一层 第二层 第三层 信息收集 打开页面又是代码审计 代码如下 <?php $text $_GET["text"]; $file $_GET["file"]; $password $_GET["password"]; if(isset($text)&&(file_get_contents($text,…

React + TS + TDD 扫雷游戏学习心得

React TS TDD 扫雷游戏学习心得 试玩地址&#xff1a;https://goldenaarcher.com/minesweeper&#xff0c;stroybook 的地址&#xff1a;https://www.chromatic.com/build?appId63b2530f575ed5942cf105be&number1 测试主要使用 jest&#xff08;mock&#xff09; RTL …

Linux进程控制(进程替换)

目录 一、进程程序替换原理 二、进程替换函数 三、函数实现子进程进程替换 3.1 测试函数 3.2 写时拷贝保证替换后的进程独立性 四、自我实现一个简单的 shell 五、内置命令 5.1 pwd查询路径本质 5.2 内置命令概念 5.3 自我实现shell Pro 先见见进程替换&#xff1a; …

Unity学习笔记--如何在Unity中把自己的代码打包成dll给别人使用?(纯保姆式教学,看完还不会,今晚八点,来沙城砍我)

目录前言背景步骤一步骤二步骤三步骤四&#xff08;关键&#xff01;&#xff01;&#xff01;&#xff09;步骤五步骤六步骤七步骤八步骤九步骤十总结前言 最近公司放年假了&#xff0c;没什么事做&#xff0c;所以来公司学习&#xff08;蹭吃蹭喝ing&#xff09; 突然记起来…

CSS总结笔记+案例

此文章属于前端篇中的第二节CSS样式 继前期HTML标记语言 CSS总结笔记&#xff1a; 3.CSS样式 css&#xff0c;专门用来“美化”标签。 基础CSS&#xff0c;写简单页面&看懂&改。模块、调整和修改 3.1CSS应用方法 1.在标签上 - 高度和宽度样式&#xff1a; <i…

linux基本功系列之alias命令实战

本文目录 文章目录前言&#x1f680;&#x1f680;&#x1f680;一. alias命令介绍二. 语法格式及常用选项三. 参考案例3.1 查看系统已经存在的别名3.2 设置别名的操作3.3 取消别名3.4 alias的全局生效和当前用户生效四. 使用命令的注意事项总结前言&#x1f680;&#x1f680;…

行云洞见 | 为什么说云端IDE代表未来趋势?

原文作者&#xff1a;行云创新解决方案架构师 李楠 预知未来最可靠的方法是了解历史&#xff0c;让我们简单回顾下IDE的发展史。 所谓IDE&#xff0c;即集成开发环境&#xff0c;是软件开发人员在他们用于编程的计算机本地安装的应用程序。伴随着计算机编程语言从第一代机器语…

【NI Multisim 14.0虚拟仪器设计——放置虚拟仪器仪表(万用表)】

目录 序言 &#x1f34d;放置虚拟仪器仪表 &#x1f349;万用表 序言 NI Multisim最突出的特点之一就是用户界面友好。它可以使电路设计者方便、快捷地使用虚拟元器件和仪器、仪表进行电路设计和仿真。 首先启动NI Multisim 14.0&#xff0c;打开如图所示的启动界面&#x…

【虹科分享】虹科ATEasy软件,您的测试执行和开发专家!

测试和执行专家 虹科ATEasy是功能测试&#xff0c;自动测试系统&#xff0c;数据采集&#xff0c;过程控制和仪表系统的测试执行和快速应用开发框架。虹科ATEasy提供开发&#xff0c;部署和维护软件组件的所有必要工具&#xff0c;包括仪器驱动程序&#xff0c;测试程序&#x…

SGA与PGA的区别

前几天有被别人问到什么是SGA和PGA&#xff0c;说实在的&#xff0c;之前一直搞分布式&#xff0c;已经基本把单机里面的这两个概念忘记的差不多了&#xff0c;不过当时还是根据自己的一点数据库经验说了点七七八八&#xff0c;后来网上查了一下相关说明&#xff0c;发现自己的…

现货黄金与白银现货的区别

黄金与白银同为贵金属&#xff0c;二者均在人类货币史上担当过货币的功能&#xff0c;而现货黄金与白银现货作为其最重要的金融衍生品&#xff0c;都具备良好的收益性、流动性和的可操作性&#xff0c;都是比较理想的投资产品。那么和现货黄金和白银现货的区别在哪里呢?小编认…

C++初学者学习笔记

面向对象的程序设计 初步理解 相比较于面向过程的程序设计来说有更多的封装的函数可以使用&#xff0c;相比较来说会比较方便。但是如何去设计整个程序的思路也是需要一定的训练的。 C 简介 C 是一种静态类型的、编译式的、通用的、大小写敏感的、不规则的编程语言&#xf…

linux系统目录结构

在 Linux 或 Unix 操作系统中&#xff0c;所有的文件和目录都被组织成以一个根节点开始的倒置的树状结构。 文件系统的最顶层是由根目录开始的&#xff0c;系统使用 / 来表示根目录。在根目录之下的既可以是目录&#xff0c;也可以是文件&#xff0c;而每一个目录中又可以包含…

【荐书】C程序设计语言(第二版)

“在大多数人眼中&#xff0c;我是个一事无成、乖僻古怪、令人作呕的人。我毫无社会地位可言&#xff0c;也永远不会有。总之&#xff0c;我是底层人中的底层人。好吧&#xff0c;就算这些看法都完全正确&#xff0c;我也想有那么一天&#xff0c;通过我的作品向他们展示&#…

C++模板(函数模板,类模板)的基本使用与非类型模板参数与模板的特化

C模板模板初阶泛型编程函数模板函数模板概念函数模板格式函数模板的原理函数模板的实例化隐式实例化显式实例化&#xff1a;在函数名后的<>中指定模板参数的实际类型模板参数的匹配原则类模板类模板的定义格式类模板的实例化模板进阶非类型模板参数模板的特化概念函数模板…

【TypeScript】TS与Vue

TypeScript与Vue 文章目录TypeScript与VuedefineProps与TypescriptdefineEmits与Typescriptref与Typescriptreactive与Typescriptcomputed与Typescript事件处理与TypescriptTemplate Ref与Typescript可选链操作符非空断言参考链接&#xff1a;https://vuejs.org/guide/typescri…

【OpenGL学习】texture

纹理 一、什么是纹理&#xff1f; 引用百度百科的定义&#xff1a; 计算机图形学中的纹理既包括通常意义上物体表面的纹理即使物体表面呈现凹凸不平的沟纹&#xff0c;同时也包括在物体的光滑表面上的彩色图案&#xff0c;通常我们更多地称之为花纹。对于花纹而言&#xff0c…

ES6 课程概述⑦

文章目录Vuex_State安装使用State在 Vue 组件中获得 Vuex 状态mapState 辅助函数Vuex_Getter通过属性访问通过方法访问mapGetters 辅助函数Vuex_Mutation在组件中提交 Mutation提交载荷&#xff08;Payload&#xff09;对象风格的提交方式使用常量替代 Mutation 事件类型Mutati…