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 楼答案
你混合了两个不同的概念。要么让log4j将日志事件写入数据库,要么实现自己的与log4j无关的记录器
第一部分显示您将使用log4j。好的但是,您不需要使用相同表的JPA实体。类
Log
,方法saveLogForGetAll(Log log)
只是不需要。Log4j将把日志事件保存到数据库中log4j的思想是,代码不应该知道日志事件将如何持久化(在文件系统、数据库、通过消息队列可访问的远程设备等中)
第二部分,类
Log
和方法saveLogForGetAll(Log log)
,表明您希望直接持久化日志事件,而不需要log4j。那么,在log4j中定义数据库appender的目的是什么两者都不是对的或错的。但是有两个独立的日志机制没有多大意义。但是实现自己的日志记录可能是一项相当复杂的任务:考虑性能、异步持久性、按类和包配置日志记录级别、检索有关当前线程和方法的信息等等
这就是为什么我建议您选择一个log4j(或logback),配置并使用它。只有当你发现你不能用log4j意识到一些真正重要的事情时,才抛弃log4j,实现你自己的日志记录