有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Spring Boot中的java Log4j 2:JDBC appender不会将日志消息写入数据库的列

最近,我尝试使用log4j2创建和配置JDBC日志appender

其主要思想是,每次我们访问特定端点(Spring service)时,都会发送一个日志,并将来自日志的Hibernate SQL查询直接放入GDPR_日志数据库表中的OPERATION_DESCRIPTION列

以下是我迄今为止为实现这一目标所做的工作:

  • 我在Gradle中排除了“logback classic”和“spring boot starter logging”依赖项
  • 我添加了“log4japi”、“log4j core”和“spring-boot-starter-log4j2”依赖项

我现在的身材。gradle看起来像这样:


    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'org.springframework.boot:spring-boot-gradle-plugin:1.5.7.BUILD-SNAPSHOT'
        }
    }
    
    plugins {
        id "org.springframework.boot" version "1.5.7.RELEASE"
    }
    
    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'war'
    
    war {
        baseName = 'CprUI'
        version =  '1.0.0-SNAPSHOT'
    }
    
    repositories {
        mavenLocal()
        mavenCentral()
        jcenter()
        maven { url "http://repo.spring.io/libs-snapshot" }
    }
    
    sourceCompatibility = 1.8
    targetCompatibility = 1.8
    
    dependencies {
        compile("org.springframework.boot:spring-boot-starter-web")
        compile("org.springframework.boot:spring-boot-starter-actuator")
        compile("org.springframework.boot:spring-boot-starter-security")
        compile("org.springframework.ldap:spring-ldap-core")
        compile("org.springframework.security:spring-security-ldap")
        compile("org.springframework:spring-tx")
        compile("com.unboundid:unboundid-ldapsdk")
        compile("org.springframework.boot:spring-boot-starter-log4j2")
        compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version: '1.5.7.RELEASE'
        compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '1.5.7.RELEASE'
        compile group: 'org.springframework.boot', name: 'spring-boot-starter-parent', version: '1.5.7.RELEASE', ext: 'pom'
        compile("com.oracle:ojdbc6:11.2.0.3")
        compile("org.apache.any23:apache-any23-encoding:2.0")
        compile("org.apache.commons:commons-csv:1.5")
        compile group: 'org.thymeleaf.extras', name: 'thymeleaf-extras-springsecurity4', version: '3.0.2.RELEASE'
        compile("org.springframework.boot:spring-boot-starter-web")
        providedRuntime("org.springframework.boot:spring-boot-starter-tomcat")
        testCompile("org.springframework.boot:spring-boot-starter-test")
        testCompile("org.springframework.security:spring-security-test")
        compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.7'
        compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.7'
        compile group: 'org.springframework.boot', name: 'spring-boot-starter-log4j2', version: '2.3.1.RELEASE'
        compile group: 'org.apache.commons', name: 'commons-dbcp2', version: '2.7.0'
        compile group: 'mysql', name: 'mysql-connector-java', version: '8.0.20'
        compile group: 'org.apache.maven.plugins', name: 'maven-compiler-plugin', version: '3.8.1'
    }
    
    configurations.all {
        exclude module: 'spring-boot-starter-logging'
        exclude module: 'logback-classic'
    }

  • 接下来,我创建了log4j2。属性文件,并将其置于/resources目录下。该文件如下所示:

    appenders = console, db
    appender.console.type = Console
    appender.console.name = STDOUT
    appender.console.layout.type = PatternLayout
    appender.console.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
    
    appender.db.type = JDBC
    appender.db.name = JDBC
    appender.db.layout.type = PatternLayout
    appender.db.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
    appender.db.connectionSource.type= DriverManager
    appender.db.connectionSource.connectionString = my_connection_string
    appender.db.connectionSource.username = my_username
    appender.db.connectionSource.password = my_password
    appender.db.connectionSource.driverClassName = oracle.jdbc.driver.OracleDriver
    appender.db.tableName = GDPR_LOG
    
    appender.db.columnConfigs[0].type = Column
    appender.db.columnConfigs[0].name = OPERATION_DESCRIPTION
    appender.db.columnConfigs[0].pattern =%msg
    appender.db.columnConfigs[0].isUnicode =false
    
    logger.db.name = eu.unicredit.mtr.cpr.logging
    logger.db.level = debug
    logger.db.additivity = false
    logger.db.appenderRef.db.ref = JDBC
    
    rootLogger.level = debug
    rootLogger.appenderRefs = stdout
    rootLogger.appenderRef.stdout.ref = STDOUT

  • 然后我更新了我的申请。Spring Boot中的属性:

    # LOGGING
    logging.level.org.hibernate.SQLQuery=debug
    logging.level.org.hibernate.type.descriptor.sql=trace
    logging.level.org.springframework.web=${LOG_LEVEL_SPRING:info}
    logging.level.org.hibernate=${LOG_LEVEL_SPRING:debug}
    logging.level.web=${LOG_LEVEL_SPRING:info}
    logging.config=classpath:log4j2.properties
    
    spring.datasource.url=my_datasource
    spring.datasource.username=my_user
    spring.datasource.password=my_password
    spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
    
    server.context-path=/CprUI

现在,我只想将Hibernate查询发送到db表中的一个特定列。其余的列由Spring服务方法设置。下面是我的实体类和服务的方法的样子:


    @Entity
    @Table(name = "GDPR_LOG")
    public class Log {
    
        @Id
        @SequenceGenerator(name="DWH_ID_SEQ_GEN", sequenceName="DIM_CPR_COUNTERPARTY_ID", allocationSize=10)
        @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="DWH_ID_SEQ_GEN")
        @Column(name = "ITEM_ID")
        private Long id;
        @Column(name = "CREATION_TIME")
        private String creation_time;
        @Column(name = "LOG_ID")
        private String log_id;
        @Column(name = "USER_ID")
        private String user_id;
        @Column(name = "WORKSTATION_ID")
        private String workstation_id;
        @Column(name = "SESSION_ID")
        private String session_id;
        @Column(name = "OPERATION_DESCRIPTION")
        private String operation_description;
        @Column(name = "APPLICATION_CODE")
        private String app_code;
        @Column(name = "LEGAL_ENTITY")
        private String entity;
    
    //getters, setters


    @Transactional
        public void saveLogForGetAll(Log log) {
            log.setCreation_time(formatDateTime);
            log.setLog_id("SecLog");
            log.setUser_id(checkUser());
            log.setWorkstation_id(checkIP());
            log.setSession_id(session_string);
            log.setApp_code("QRP");
            log.setEntity("AG");
            logsRepository.save(log);
        }

你们能告诉我我做错了什么吗

尽管我在log4j2中指定了字段和值。属性文件,但我在那里只得到null,并且没有将Hibernate查询保存到数据库中。 我在春季是一个初学者,我已经为这个话题挣扎了两周,所以我非常感谢在这方面的任何帮助

提前谢谢

干杯


共 (1) 个答案

  1. # 1 楼答案

    你混合了两个不同的概念。要么让log4j将日志事件写入数据库,要么实现自己的与log4j无关的记录器

    第一部分显示您将使用log4j。好的但是,您不需要使用相同表的JPA实体。类Log,方法saveLogForGetAll(Log log)只是不需要。Log4j将把日志事件保存到数据库中

    log4j的思想是,代码不应该知道日志事件将如何持久化(在文件系统、数据库、通过消息队列可访问的远程设备等中)

    第二部分,类Log和方法saveLogForGetAll(Log log),表明您希望直接持久化日志事件,而不需要log4j。那么,在log4j中定义数据库appender的目的是什么

    两者都不是对的或错的。但是有两个独立的日志机制没有多大意义。但是实现自己的日志记录可能是一项相当复杂的任务:考虑性能、异步持久性、按类和包配置日志记录级别、检索有关当前线程和方法的信息等等

    这就是为什么我建议您选择一个log4j(或logback),配置并使用它。只有当你发现你不能用log4j意识到一些真正重要的事情时,才抛弃log4j,实现你自己的日志记录