Grails에서 SQL 문을 기록하는 방법


86

성능을 확인하기 위해 Grails가 수행하는 모든 쿼리를 콘솔이나 파일에 로그인하고 싶습니다.

나는 이것을 성공없이 구성 했습니다 .

어떤 아이디어라도 도움이 될 것입니다.


어떤 솔루션도 나를 위해 일하지 못했습니다. 내가 얼마나 절망적인지 모두에게 알리기 위해이 글을 쓰고 있습니다.
Andrea

답변:


131

환경

datasource {
...
logSql = true
}

DataSource.groovy ( 지침에 따라)는 내 환경에서 작동하기에 충분했습니다. FAQ의 일부가 오래된 것 같습니다 (예 : "다 대다 열 거꾸로"질문). 그 동안 변경된 내용 일 수도 있습니다.


6
logSql=true혼자서는 충분하지 않습니다. Hibernate 로깅도 켜져 있어야합니다. @Pete의 답변을 참조하십시오.
Jason

2
여기에는 "?"가있는 SQL 문에 들어가는 값이 포함되지 않는다는 것을 알았습니다.
Jason

1
이것은 작동하지만 모든 쿼리에 적용됩니다. logSql = true를 설정하지 않고도 특정 기준에 대해 생성 된 SQL을 인쇄 할 수 있습니까?
8월

@Guus 특정 기준에 대해 생성 된 SQL을 어떻게 인쇄 할 수 있습니까?
biniam 2015-10-23

@biniam_Ethiopia 내가 아는 한 이것은 불가능합니다. 특정 클래스를 디버깅하고 다른 쿼리도보고 싶지 않을뿐만 아니라 이것을 원합니다.
8월

91

다음을 수행하는 것이 더 유용하다는 것을 알았습니다. Hibernate의 로깅을 활성화하여 바인드 변수와 함께 SQL을 기록 할 수 있습니다 (따라서 호출에 전달 된 값을 볼 수 있고 편집기에서 SQL을 쉽게 복제 할 수 있습니다).

에서 Config.groovylog4j 블록에 다음을 추가하십시오.

log4j = {

    // Enable Hibernate SQL logging with param values
    trace 'org.hibernate.type'
    debug 'org.hibernate.SQL'
    //the rest of your logging config
    // ...
    }

8
나는 이것을 여러 번 사용했습니다. 한 가지주의 할 점은 매개 변수를 출력하는 데 비용이 많이 듭니다. 이 작업은 개발자 상자에서만 수행하는 것이 좋습니다.
John Gordon

2
또한 추가 할 수 있습니다 format_sql = truehibernate당신의 블록 DataSource.groovy멋지게 포맷 출력.
Gregor Petrin 2014

1
참고 : 쿼리 결과 집합에서 추출 된 where 절 매개 변수와 열 값을 모두 기록합니다. where 절 매개 변수 만 로깅하려면trace 'org.hibernate.type.BasicBinder'
GreenGiant

누구나 grails 3.3.8에 해당하는 것을 알고 있습니까?
John Little

어떤 이유로 구문 상 유효하지 않은 쿼리 (안타깝게도 Hibernate에서 생성)는 기록되지 않습니다. 다른 모든 쿼리는 기록됩니다. Hibernate 자체에 문제가 있습니까?
Janaka Bandara

32

성배 3. *

옵션 # 1은 logback.groovy에 다음을 추가합니다.

logger("org.hibernate.SQL", DEBUG, ["STDOUT"], false)
logger("org.hibernate.type.descriptor.sql.BasicBinder", TRACE, ["STDOUT"], false)

또는

옵션 # 2는 application.yml의 dataSource에 다음을 추가합니다. 그러나이 방법은 매개 변수 값을 기록하지 않습니다.

environments:
  local:
    dataSource:
        logSql: true
        formatSql: true

17

이 시도:

log4j = {
   ...
   debug 'org.hibernate.SQL'
   trace 'org.hibernate.type.descriptor.sql.BasicBinder'
}

Hibernate type패키지에 대한 추적 로깅의 성능 문제를 방지합니다 . 이것은 Hibernate 3.6 이상에서 작동합니다. https://burtbeckwith.com/blog/?p=1604 에서 가져 왔습니다.


6

솔루션은 프로덕션이 아닌 개발 용입니다.

위의 모든 답변이 작동하며 정확합니다. 그러나 그들은 사람이 읽을 수있는 좋은 방식으로 완전한 쿼리를 표시하지 않습니다. 최종 (?,?없이) 쿼리를 보려면 두 가지 옵션이 있습니다.

A) log4jdbc 또는 p6Spy를 사용하여 jdbc 연결을 프록시하십시오.

B) 데이터베이스 수준에서 살펴보십시오. 예를 들어 mysql로 ​​정말 쉽게 할 수 있습니다.

general_log_file이 어디에 있는지 알아보십시오. 활성화되지 않은 경우 활성 일반 로그입니다.

mysql command line> show variables like "%general_log%";
mysql command line> set global general_log = true;

이제 모든 것이 로그 파일에 기록됩니다. Mac / linux 예제는 쿼리의 멋진 스트림을 보여줍니다.

tail -f path_to_log_file 

3

참조 용으로 만 순수하지만 p6spy를 사용하여 SQL 쿼리를 기록합니다. 작은 중급 jdbc 드라이버입니다. 정확한 쿼리는 서버로 전송되는 것처럼 기록됩니다 (매개 변수 포함).

프로젝트에 포함 :

runtime 'p6spy:p6spy:3.0.0'

데이터 소스 드라이버를 변경하십시오.

driverClassName: com.p6spy.engine.spy.P6SpyDriver

그리고 귀하의 jdbc URL :

url: jdbc:p6spy:mysql://

spy.properties를 사용하여 구성하십시오 (grails-app / conf에서).

driverlist=org.h2.Driver,com.mysql.jdbc.Driver
autoflush=true
appender=com.p6spy.engine.spy.appender.StdoutLogger
databaseDialectDateFormat=yyyy-MM-dd
logMessageFormat=com.p6spy.engine.spy.appender.MultiLineFormat

프로덕션을 위해 이것을 비활성화하는 것을 잊지 마십시오!


2

다음은 나를 위해 작동합니다.

grails-app / conf / application.yml

# ...
hibernate:
    format_sql: true # <<<<<<< ADD THIS <<<<<<<
    cache:
        queries: false
        use_second_level_cache: true
# ...
environments:
    development:
        dataSource:
            logSql: true // <<<<<<< ADD THIS <<<<<<<
            dbCreate: create-drop
            url: jdbc:h2:mem:...
# ...

grails-app / conf / logback.groovy

// ...
appender('STDOUT', ConsoleAppender) {
    encoder(PatternLayoutEncoder) {
        pattern = "%level %logger - %msg%n"
    }
}

// >>>>>>> ADD IT >>>>>>>
logger 'org.hibernate.type.descriptor.sql.BasicBinder', TRACE, ['STDOUT']
logger 'org.hibernate.SQL', TRACE, ['STDOUT']
// <<<<<<< ADD IT <<<<<<<

root(ERROR, ['STDOUT'])

def targetDir = BuildSettings.TARGET_DIR
// ...

출처 : http://sergiodelamo.es/log-sql-grails-3-app/


1

이 질문을 받고 오랫동안 답변을 받았지만,이 질문을 우연히 보게되었고 프로젝트에서 SQL 로깅 구현 접근 방식에 대한 답변이나 공유를 중단 할 수 없었습니다. 도움이되기를 바랍니다.

현재 개발 환경에 있습니다. "log4jdbc Driver Spy"를 사용하여 SQL을 기록합니다.

구성 :

BuildConfig.groovy에서 다음 종속성을 추가하십시오.

dependencies {
.....
runtime 'org.lazyluke:log4jdbc-remix:0.2.7'
}

그리고 DataSource 또는 기타 구성 관련 : [데이터 소스 관련 구성을 정의한 모든 위치], 추가 :

datasources{
.....
driverClassName: "net.sf.log4jdbc.DriverSpy",
url: "jdbc:log4jdbc:oracle:thin:@(DESCRIPTION =(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = XXXXX.XX>XXX)(PORT = 1521))) (CONNECT_DATA = (SID = XXXX)(SERVER =DEDICATED)))",
....
}
log4j = {

    info 'jdbc.sqlonly' //, 'jdbc.resultsettable'

}

개인적인 경험을 통해 디버깅하는 동안 매우 유용하고 유용하다는 것을 알았습니다. 또한이 사이트에서 더 많은 정보를 찾을 수 있습니다. https://code.google.com/p/log4jdbc-remix/

왕 안부


0

특정 코드 블록의 경우 클로저를 허용하는 메서드를 만들 수도 있습니다. 예.

 static def executeBlockAndGenerateSqlLogs(Closure closure) {
    Logger sqlLogger = Logger.getLogger("org.hibernate.SQL");
    Level currentLevel = sqlLogger.level
    sqlLogger.setLevel(Level.TRACE)
    def result = closure.call()
    sqlLogger.setLevel(currentLevel)
    result }

executeBlockAndGenerateSqlLogs{DomainClazz.findByPropertyName("property value")}

0

당신이있는 경우 콘솔 플러그인을 설치, 당신은이 작은 코드와 SQL 로깅을 얻을 수 있습니다.

// grails 2.3
def logger=ctx.sessionFactory.settings.sqlStatementLogger

// grails 3.3  
def logger = ctx.sessionFactory.currentSession.jdbcCoordinator.statementPreparer.jdbcService.sqlStatementLogger

logger.logToStdout=true    
try {
   <code that will log sql queries>
}
finally {
    logger.logToStdout = false
}

이것은 위의 많은 솔루션의 변형이지만 런타임에 값을 조정할 수 있습니다. 그리고 logToStdout그것을 다루는 다른 솔루션 과 마찬가지로 바인딩 값이 아닌 쿼리 만 표시합니다.

아이디어는 내가 몇 년 전에 읽은 게시물과 함께 버트 벡에서 도난 당했지만 지금은 찾을 수 없습니다. grails 3.3과 함께 작동하도록 편집되었습니다.

유사한 기술을 사용하여 특정 통합 테스트에 대한 로깅을 설정할 수 있습니다.

class SomeIntegrationSpec extends IntegrationSpec {

    def sessionFactory

    def setup() {
        sessionFactory.settings.sqlStatementLogger.logToStdout = true
    }

    def cleanup() {
        sessionFactory.settings.sqlStatementLogger.logToStdout = false
    }

    void "some test"() {
           ...
    }

이렇게하면이 파일의 테스트에 대해서만 SQL 로깅이 설정됩니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.