log4j2日志框架配置+日志记录写入数据库

log4j2日志框架配置+日志记录写入数据库

第一步配置pom文件依赖与 application.properties 配置文件

我用的是spring-boot-starter-log4j2的日志依赖;

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
    <version>3.0.0</version>
</dependency>

配置好pom文件后 配置 [application.properties] 文件 在该文件里加入这个config路径就行。

logging.config=classpath:log4j2.xml

第二步 配置 [log4j2.xml] 文件

话不多说 具体解释都在配置文件的注释里,配置详情如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="INFO" monitorInterval="30">
    <!--先定义所有的appender-->
    <appenders>
        <!--这个输出控制台的配置-->
        <console name="Console" target="SYSTEM_OUT">
            <!--输出日志的格式-->
            <PatternLayout
                    pattern="%highlight{[%d{HH:mm:ss.SSS}] [%level] --- [%t] %logger{36} : %msg%n}{FATAL=red blink, ERROR=red, WARN=yellow bold, INFO=green, DEBUG=gray bold, TRACE=white bold}"/>
            <!--            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight{%-5level} [%t] %highlight{%c{1.}.%M(%L)}: %msg%n" />-->
        </console>
        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
        <File name="log" fileName="./log/liziSpark-test.log" append="false">
            <!--            <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>-->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
        </File>
        <!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
        <RollingFile name="RollingFileInfo" fileName="./liziSparkLogs/logs/liziSpark-info.log"
                     filePattern="liziSparkLogs/logs/$${date:yyyy-MM}/dream-order-info-%d{yyyy-MM-dd}-%i.log">
            <!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <!--            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>-->
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>

            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
        </RollingFile>
        <!--        error日志-->
        <RollingFile name="RollingFileError" fileName="./liziSparkLogs/logs/liziSpark-error.log"
                     filePattern="liziSparkLogs/logs/$${date:yyyy-MM}/dream-order-error-%d{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>

            <Policies>
                <TimeBasedTriggeringPolicy/>
                <SizeBasedTriggeringPolicy size="100 MB"/>
            </Policies>
        </RollingFile>

        <JDBC name="databaseAppender" bufferSize="20" tableName="blog_lizi_log">
            <ConnectionFactory class="com.spark.common.log.ConnectionFactory" method="getDatabaseConnection"/>
            <Column name="event_id" pattern="%X{id}"/>
            <Column name="event_date" isEventTimestamp="true"/>
            <Column name="thread" pattern="%t %x"/>
            <Column name="class" pattern="%C"/>
            <Column name="function_name" pattern="%M,%line"/>
            <Column name="message" pattern="%m"/>
            <Column name="exception" pattern="%ex{full}"/>
            <Column name="level" pattern="%level"/>
            <Column name="time" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}"/>
        </JDBC>
    </appenders>
    <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
    <loggers>
        <!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
        <logger name="org.springframework" level="INFO"></logger>
        <logger name="org.mybatis" level="INFO"></logger>
        <logger name="com.baomidou.mybatisplus" level="DEBUG"></logger>
        <!-- 根日志级别设为INFO,并关联多个Appender -->
        <root level="all">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
            <appender-ref ref="RollingFileError"/>
            <!-- 添加数据库日志Appender -->
            <appender-ref ref="databaseAppender"/>
        </root>
    </loggers>
</configuration>

单独说一下 的配置内容:

这段配置是Log4j或Log4j2框架中的一部分,用于定义一个JDBC Appender(数据库日志记录器),即使用JDBC连接将日志事件写入数据库。下面是对各部分的详细解释:

  • <JDBC name="databaseAppender" bufferSize="20" tableName="blog_lizi_log">: 这里定义了一个名为databaseAppender的JDBC Appender。bufferSize="20"指定了日志事件在批量写入数据库之前可以在内存中缓存的最大数量。tableName="blog_lizi_log"指定了日志将被写入的数据库表名。
  • <ConnectionFactory class="com.spark.common.log.ConnectionFactory" method="getDatabaseConnection"/>: 指定了用于获取数据库连接的工厂类及其方法。这里的com.spark.common.log.ConnectionFactory是自定义的连接工厂类,getDatabaseConnection是获取数据库连接的方法。
  • <Column>标签定义了日志事件如何映射到数据库表的各个列:
    • <Column name="event_id" pattern="%X{id}"/>: 表示event_id列的值将使用MDC(Mapped Diagnostic Context)中的id属性填充。%X是MDC的占位符,{id}是MDC中的键名。
    • <Column name="event_date" isEventTimestamp="true"/>: 表示event_date列自动使用事件发生的时间戳填充,因为isEventTimestamp="true"
    • <Column name="thread" pattern="%t %x"/>: 将线程名称和NDC(Nested Diagnostic Context)信息填充到thread列。
    • <Column name="class" pattern="%C"/>: 使用记录事件的类名填充class列。
    • <Column name="function_name" pattern="%M,%line"/>: 使用记录方法名和行号(%M)填充function_name列,但注意这里的格式可能不正确,通常%line不直接与%M一起使用,需要确认具体日志框架的配置指南。
    • <Column name="message" pattern="%m"/>: 记录的消息内容填充message列。
    • <Column name="exception" pattern="%ex{full}"/>: 异常堆栈信息(完整堆栈)填充exception列。
    • <Column name="level" pattern="%level"/>: 日志级别填充level列。
    • <Column name="time" pattern="%d{yyyy-MM-dd HH:mm:ss.SSS}"/>: 自定义的时间格式(年月日 时分秒 毫秒)填充time列。

总之,这段配置指示Log4j在处理日志时,将按照定义的格式提取日志信息,然后通过com.spark.common.log.ConnectionFactory获取数据库连接,并将这些信息写入到blog_lizi_log表中相应的列。


第三步数据库表的建立,与db配置文件。

CREATE TABLE `blog_lizi_log` (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `event_id` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `event_date` datetime DEFAULT NULL,
  `thread` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `class` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `function_name` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `message` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `exception` text CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci,
  `level` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL,
  `time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=360 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC;

表的字段与xml中的jdbc的Column name要一一对应

db.properties 文件配置:

druid.url=jdbc:mysql://localhost:3306/bloglizi?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
druid.username=root
druid.password=123123
druid.driverClassName=com.mysql.cj.jdbc.Driver
druid.maxActive=10
druid.minIdle=5

注意时区与格式编码,这会影响插入数据的有可能时间不对或中文乱码


最后一步 也是最重要的一部 配置单例模式的数据库连接工厂方法

package com.spark.common.log;

import com.alibaba.druid.pool.DruidDataSource;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @className: ConnectionFactory
 * @description: TODO 单例模式数据库连接工厂方法
 * @author: albert_luo
 * @date: 2024/05/17 18:18
 * @Company: Copyright© 2024/5/17 by LuoTao
 **/
public class ConnectionFactory {
    private static final DataSource dataSource;
    private static final String DB_PROPERTIES_PATH = "/db.properties";

    static {
        Properties properties = new Properties();
        try (InputStream stream = ConnectionFactory.class.getResourceAsStream(DB_PROPERTIES_PATH)) {
            if (stream == null) {
                throw new ExceptionInInitializerError("Unable to find " + DB_PROPERTIES_PATH + " on classpath");
            }
            properties.load(stream);

            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.configFromPropety(properties);

            // 验证数据源配置是否正确,尝试获取连接
            try (Connection testConnection = druidDataSource.getConnection()) {
                if (testConnection != null) {
                    dataSource = druidDataSource;
                } else {
                    throw new ExceptionInInitializerError("DataSource configuration failed, cannot obtain a valid connection.");
                }
            }
        } catch (IOException | SQLException e) {
            throw new ExceptionInInitializerError("Failed to initialize DataSource: " + e.getMessage() + e);
        }
    }

    /**
     * 获取数据库连接。
     *
     * @return 数据库连接对象
     * @throws SQLException 连接数据库失败时抛出
     */
    public static Connection getDatabaseConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

实现效果:

image-20240517233736285

如果觉得对你有用的话 点个关注+收藏吧!

  • 13
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
可以的,以下是Java代码实现log4j2日志写入MySQL数据库的示例: 1. 首先,需要在pom.xml文件中添加以下依赖: ``` <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.14.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.14.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.14.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency> ``` 2. 在log4j2.xml文件中配置MySQL数据库的Appender: ``` <?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <JDBC name="databaseAppender" tableName="logs"> <ConnectionFactory class="com.mysql.cj.jdbc.MysqlDataSource"> <param name="url" value="jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC"/> <param name="user" value="root"/> <param name="password" value="123456"/> </ConnectionFactory> <Column name="timestamp" isEventTimestamp="true"/> <Column name="level" pattern="%level"/> <Column name="logger" pattern="%logger"/> <Column name="message" pattern="%message"/> </JDBC> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="databaseAppender"/> </Root> </Loggers> </Configuration> ``` 3. 在Java代码中使用log4j2记录日志: ``` import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class Main { private static final Logger logger = LogManager.getLogger(Main.class); public static void main(String[] args) { logger.info("Hello, log4j2!"); } } ``` 4. 最后,在MySQL数据库中创建表logs: ``` CREATE TABLE logs ( id INT NOT NULL AUTO_INCREMENT, timestamp TIMESTAMP NOT NULL, level VARCHAR(10) NOT NULL, logger VARCHAR(100) NOT NULL, message TEXT NOT NULL, PRIMARY KEY (id) ); ``` 这样,log4j2就会将日志记录到MySQL数据库中的logs表中。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kokotao

你的鼓励就是的创作的最大动力,

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值