Spring Boot中的Log4j 2:JDBC附加程序不会将日志消息写入DB的列 [英] Log4j 2 in Spring Boot: JDBC appender doesn't write log messages to the DB's column

查看:145
本文介绍了Spring Boot中的Log4j 2:JDBC附加程序不会将日志消息写入DB的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近我正在尝试使用Log4j 2创建和配置JDBC日志附加程序.

Lately I'm trying to create and configure JDBC log appender, with usage of Log4j 2.

主要思想是,每当我们到达特定的端点(Spring服务)时都发送一条日志,并将来自该日志的Hibernate SQL查询直接发送到GDPR_LOG数据库表中的OPERATION_DESCRIPTION列.

The main idea is to send a log every time we hit the particular endpoint (Spring service) and put the Hibernate SQL query from the logs, directly to OPERATION_DESCRIPTION column in GDPR_LOG database table.

这是迄今为止我为实现这一目标所做的事情:

Here's what I've done so far to achieve it:

  • 我在Gradle中同时排除了"logback-classic"和"spring-boot-starter-logging"依赖.
  • 我添加了'log4j-api','log4j-core'和'spring-boot-starter-log4j2'依赖项.

我当前的build.gradle看起来像这样:

My current build.gradle looks like this:


    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.properties文件并将其放置在/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中更新了application.properties:
    • 
          # 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类和Service方法的样子:

      Now, I would like to send only the Hibernate queries to the one particular column in db table. The rest of columns are being set by the Spring service methods. Here is how my Entity class and Service's method look like:

      
          @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);
              }
      
      

      你们能告诉我我在做什么错吗?

      Could you guys please tell me what am I doing wrong here?

      尽管我在log4j2.properties文件中指定了字段和值,但我仍然在那里仅得到null,并且没有将Hibernate查询保存到数据库中. 我是Spring的初学者,现在已经为这个主题苦苦挣扎了两个星期,因此,我将非常感谢您对此提供的任何帮助.

      Although I specified the field and the value in log4j2.properties file, still I only get nulls there and no Hibernate query is being saved to the database. I'm rather a beginner in Spring and I've been struggling with this topic for two weeks now, so I would be very grateful for any help on that.

      谢谢.

      干杯!

      推荐答案

      您正在混合2个不同的概念.您要么让log4j将记录事件写入数据库,要么实现自己的与log4j不相关的记录器.

      You are mixing 2 different concepts. Either you let log4j to write logging events to database, or you implement your own logger not related to log4j.

      第1部分显示您将要使用log4j.美好的.但是,那么您不需要使用同一表的JPA实体.只是不需要类Log,方法saveLogForGetAll(Log log). Log4j会将日志记录事件保存到数据库.

      The 1st part shows you are going to use log4j. Fine. But then you don't need JPA entity that uses the same table. Class Log, method saveLogForGetAll(Log log) are just not needed. Log4j will save logging events to database.

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

      The idea of log4j is that the the code should not know anything about how the logging events will be persisted (in a file system, in a database, on some remote device reachable via message queue, etc.)

      第二部分,类Log和方法saveLogForGetAll(Log log),表明您要直接持久记录事件,而无需log4j.那么在log4j中定义数据库附加程序的目的是什么?

      The 2nd part, class Log and method saveLogForGetAll(Log log), shows that you want to persist logging events directly, without log4j. Then what is the purpose to define a database appender in log4j?

      都不是,也不是对还是错.但是拥有2个独立的日志记录机制没有多大意义.但是实现自己的日志记录可能是非常复杂的任务:考虑性能,异步持久性,为每个类和程序包配置日志记录级别,获取有关当前线程和方法的信息等.

      Neither of them or wrong or right. But having 2 independent logging mechanisms makes makes not much sense. But implementing own logging may be pretty complex task: thinks of performance, asynchronous persistence, configuring logging level per classes and packages, retrieving information about the current thread and the method, etc.

      这就是为什么我建议您选择一个log4j(或logback),进行配置和使用的原因.而且,只有当您发现无法使用log4j实现真正重要的事情时,才丢弃log4j并实现自己的日志记录.

      That's why I'd suggest you pick up one log4j (or logback), configure and use it. And only if you see that you cannot realize with log4j something really important, only then throw away log4j and implement your own logging.

      这篇关于Spring Boot中的Log4j 2:JDBC附加程序不会将日志消息写入DB的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆