JOOQ SQL查询正常执行日志不输出问题求助(R2DBC环境)
解决JOOQ R2DBC环境下正常SQL查询日志不输出问题
环境信息
- Kotlin 1.9
- Spring Boot v2.7.13
- Gradle 8.3
- JOOQ 3.18.2
- PostgreSQL R2DBC驱动v1.0.2
- SLF4J v2.0.7
问题描述
当前仅当SQL执行出错时才会输出日志,正常执行的SQL查询日志完全不输出,需要实现记录所有SQL查询日志的功能。
问题排查与解决方案
1. 修复SLF4J日志绑定冲突
你的build.gradle中同时引入了slf4j-simple和spring-boot-starter-log4j2,这两个都是SLF4J的日志实现绑定,会导致日志逻辑冲突,进而部分日志无法正常输出。
修改dependencies块,移除slf4j-simple依赖:
dependencies { implementation 'org.springframework.boot:spring-boot-starter-webflux' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation "org.springframework.boot:spring-boot-starter-log4j2" implementation "org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}" implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:${kotlinCoroutinesVersion}" implementation "org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}" implementation "org.jetbrains.kotlin:kotlin-allopen:${kotlinVersion}" implementation "org.slf4j:slf4j-api:${slf4jVersion}" // 移除冲突的slf4j-simple依赖 // implementation "org.slf4j:slf4j-simple:${slf4jVersion}" implementation "org.springdoc:springdoc-openapi-webflux-ui:${springdocVersion}" implementation "org.springdoc:springdoc-openapi-kotlin:${springdocVersion}" implementation "org.springdoc:springdoc-openapi-common:${springdocVersion}" implementation "org.postgresql:r2dbc-postgresql:${r2dbcPostgreVersion}" implementation "io.r2dbc:r2dbc-pool:${r2dbcPoolVersion}" jooqGenerator "org.jooq:jooq-meta-extensions" jooqGenerator "jakarta.xml.bind:jakarta.xml.bind-api:${jakartaApi}" } configurations{ all*.exclude module : 'spring-boot-starter-logging' }
2. 注册自定义ExecuteListener到DSLContext
你自定义的PrettyPrinter监听器未被注册到DSLContext中,导致executeStart方法从未触发,正常SQL执行时不会输出日志。
修改JooqConfiguration类,在创建DSLContext时添加该监听器:
@Configuration class JooqConfiguration(private val connectionFactory: ConnectionFactory) { init { System.setProperty("org.jooq.no-logo", "true") System.setProperty("org.jooq.no-tips", "true") } @Bean fun createContext(prettyPrinter: PrettyPrinter): DSLContext { val settings = Settings() .withRenderQuotedNames(RenderQuotedNames.EXPLICIT_DEFAULT_UNQUOTED) .withExecuteLoggingSQLExceptions(true) .withExecuteWithOptimisticLocking(true) .withRenderFormatted(true) // 显式开启执行日志(默认值为true,显式设置确保配置生效) .withExecuteLogging(true) return DSL.using(connectionFactory, SQLDialect.POSTGRES, settings) // 添加自定义监听器到配置中 .configuration() .set(prettyPrinter) .dsl() } } @Configuration class PrettyPrinter : ExecuteListener { private val log = org.slf4j.LoggerFactory.getLogger(PrettyPrinter::class.java) override fun executeStart(ctx: ExecuteContext) { val create = DSL.using( ctx.dialect(), Settings().withRenderFormatted(true) ) when { ctx.query() != null -> log.info(create.renderInlined(ctx.query())) ctx.routine() != null -> log.info(create.renderInlined(ctx.routine())) } } }
注意:确保
PrettyPrinter中的日志对象正确初始化,避免日志输出异常。
3. 确认Log4j2配置有效性
你的log4j2.xml已开启org.jooq和org.jooq.tools.LoggerListener的DEBUG级别,修复上述问题后,默认的JOOQ日志也会输出正常执行的SQL。如果使用自定义PrettyPrinter,可根据需求调整其日志级别(比如设为INFO)。
验证
启动应用后执行正常SQL查询,此时控制台应能看到格式化后的SQL日志输出。
内容的提问来源于stack exchange,提问作者Yaroslav
相关产品推荐
相关产品推荐

