You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 15:53:20