web-dev-qa-db-ja.com

GrailsでSQLステートメントを記録する方法

パフォーマンスをチェックするために、Grailsが実行するすべてのクエリをコンソールまたはファイルにログインしたいと思います。

this を設定しましたが、成功しませんでした。

任意のアイデアが役立ちます。

79
user2427

セッティング

datasource {
...
logSql = true
}

dataSource.groovyで( これら 手順に従って)は、私の環境で動作させるのに十分でした。 FAQの一部は古くなっているようです(たとえば、「多対多列後方」の質問)。そのため、これはその間に変更されたものかもしれません。

Hibernateのログを有効にしてバインド変数とともにSQLをログに記録することにより、呼び出しに渡された値を確認したり、エディターなどでSQLを簡単に複製したりできます。

あなたのConfig.groovy、log4jブロックに次を追加します。

log4j = {

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

Grails 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
31
Robert Hutto

これを試して:

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

Hibernate typeパッケージのトレースロギングのパフォーマンスの問題を回避します。これはHibernate 3.6以降で機能します。私はこれを以下から入手しました: https://burtbeckwith.com/blog/?p=1604

17
Jason

ソリューションは開発用であり、実稼働用ではありません。

上記の答えはすべて機能し、正しいです。しかし、彼らはニースの人間が読める方法で完全なクエリを表示しません。最終的な(?、?なしの)クエリを表示するには、2つのオプションがあります。

A)jdbc接続をlog4jdbcまたはp6Spyでプロキシします。

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 
5
Wuestenfuchs

参照のみを目的としていますが、p6spyを使用してSQLクエリを記録します。これは小さな中間jdbcドライバーです。正確なクエリは、サーバーに送信されるときに記録されます(パラメーターが含まれます)。

それをプロジェクトに含めます:

runtime 'p6spy:p6spy:3.0.0'

データソースドライバーを変更します。

driverClassName: com.p6spy.engine.spy.P6SpyDriver

そして、jdbcのURL:

url: jdbc:p6spy:mysql://

(grails-app/conf内の)spy.propertiesを使用して設定します。

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

本番環境ではこれを無効にすることを忘れないでください!

3
Dennie de Lange

私はこれが長い間尋ねられ、答えられたことを知っていますが、たまたまこの質問を見て、私たちのプロジェクトでのSQLロギング実装アプローチに答えたり共有したりするのを止めることができませんでした。それが助けになることを願っています。

現在、開発環境にあります。 「log4jdbc Driver Spy」を使用して、SQLをログに記録しています。

構成:

BuildConfig.groovyで、以下の依存関係を追加します。

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

データソースまたはその他の設定に関連する:[データソース関連の設定を定義した場所]で、追加:

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/

敬具

1
Madhu Bose

特定のコードブロックに対して、クロージャを受け入れるメソッドを作成することもできます。例えば。

 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
user3180264

次は私のために働く:

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/

0
Eduardo Cuomo

console プラグインがインストールされている場合、この小さなコードスニペットで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 {
    logToStdout = false
}

これは上記の多くのソリューションのバリエーションですが、実行時に値を微調整できます。 logToStdoutを扱う他のソリューションと同様に、バインド値ではなくクエリのみを表示します。

このアイデアは、数年前に読んだburtbeckwithの投稿から盗まれました。 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"() {
           ...
    }

これにより、この1つのファイルのテストのみのSQLログが有効になります。

0
burns