Jak rejestrować instrukcje SQL w Grails


86

Chcę zalogować się do konsoli lub do pliku, wszystkie zapytania, które robi Grails, aby sprawdzić wydajność.

Skonfigurowałem to bez powodzenia.

Każdy pomysł by pomógł.


Żadne z przedstawionych rozwiązań nie działa dla mnie. Piszę to, żeby wszyscy wiedzieli, jak bardzo jestem zdesperowany.
Andrea

Odpowiedzi:


131

Oprawa

datasource {
...
logSql = true
}

w DataSource.groovy (zgodnie z tymi instrukcjami) wystarczyło, aby dostać pracę w moim otoczeniu. Wygląda na to, że części FAQ są nieaktualne (np. Pytanie „wiele do wielu kolumn wstecz”), więc może to też się zmienić w międzyczasie.


6
logSql=truesam nie wystarczy. Rejestrowanie hibernacji również musi być włączone. Zobacz odpowiedź @ Pete'a.
Jason

2
Zauważyłem, że nie obejmuje to wartości, które pojawiają się w instrukcjach SQL, w których znajdują się znaki „?”.
Jason

1
To działa, ale w przypadku wszystkich zapytań. Czy można również wydrukować wygenerowany plik sql dla określonych kryteriów bez konieczności ustawiania logSql = true?
sierpień

@Guus, jak mogę wydrukować wygenerowany plik sql dla określonych kryteriów?
biniam

@biniam_Ethiopia O ile wiem, nie jest to możliwe. Chcę tego, ponieważ jest to denerwujące w przypadku debugowania niektórych klas i nie chce widzieć również innych zapytań.
sierpnia

91

Uważam, że bardziej przydatne jest wykonanie następujących czynności, które polegają na umożliwieniu rejestrowania przez Hibernate rejestrowania kodu SQL wraz ze zmiennymi powiązanymi (aby można było zobaczyć wartości przekazywane do wywołań i łatwo replikować kod SQL w edytorze lub w inny sposób).

W swoim Config.groovy, dodaj do swojego bloku log4j:

log4j = {

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

8
Używałem tego wiele razy. Jedna uwaga: wyprowadzanie parametrów jest bardzo kosztowne. Zalecałbym zrobienie tego tylko na twoim dev boxie.
John Gordon

2
Możesz również dodać format_sql = truedo hibernatebloku swojego, DataSource.groovyaby uzyskać ładnie sformatowane wyjście.
Gregor Petrin

1
Uwaga: spowoduje to zarejestrowanie zarówno parametrów klauzuli where, jak i wartości kolumn wyodrębnionych z zestawów wyników zapytania. Aby rejestrować tylko w przypadku parametrów klauzuli, użyjtrace 'org.hibernate.type.BasicBinder'
GreenGiant

Czy ktoś zna odpowiednik Grailsów 3.3.8?
John Little,

Z jakiegoś powodu niepoprawne składniowo zapytania (generowane przez samą Hibernate, niestety!) Nie są rejestrowane - wszystkie inne zapytania są rejestrowane ... Prawdopodobnie problem z samą Hibernate?
Janaka Bandara

32

Za Graile 3. *

Opcja nr 1: dodaj następujące elementy do logback.groovy

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

lub

Opcja nr 2 dodaj następujące elementy do dataSource w pliku application.yml. Jednak to podejście nie rejestruje wartości parametrów

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

17

Spróbuj tego:

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

Pozwala uniknąć problemów z wydajnością związanych z rejestrowaniem śledzenia typepakietu Hibernate . Działa to z Hibernate 3.6 i nowszymi wersjami. Mam to z: https://burtbeckwith.com/blog/?p=1604


6

Rozwiązanie służy tylko do rozwoju, a nie do produkcji.

Wszystkie powyższe odpowiedzi działają i są poprawne. Ale nie pokazują całego zapytania w sposób czytelny dla człowieka. Jeśli chcesz zobaczyć ostatnie (bez?,?) Zapytanie, masz dwie opcje.

A) proxy połączenia JDBC za pomocą log4jdbc lub p6Spy.

B) spójrz na to na poziomie bazy danych. Na przykład bardzo łatwe do zrobienia z mysql.

Dowiedz się, gdzie znajduje się plik general_log_file. Aktywny dziennik ogólny, jeśli nie został jeszcze aktywowany.

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

Teraz wszystko jest zapisywane w pliku dziennika. Przykład Mac / linux, aby pokazać ładny strumień zapytań.

tail -f path_to_log_file 

3

Pure tylko w celach informacyjnych, ale używam p6spy do rejestrowania zapytań SQL. To mały pośredni sterownik jdbc. Dokładne zapytanie jest rejestrowane tak, jakby było wysłane do serwera (z uwzględnieniem parametrów).

uwzględnij to w swoim projekcie:

runtime 'p6spy:p6spy:3.0.0'

Zmień sterownik źródła danych:

driverClassName: com.p6spy.engine.spy.P6SpyDriver

I Twój adres URL jdbc:

url: jdbc:p6spy:mysql://

Skonfiguruj go za pomocą spy.properties (w 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

Nie zapomnij wyłączyć tego na potrzeby produkcji!


2

Dalej działa dla mnie:

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
// ...

Źródło: http://sergiodelamo.es/log-sql-grails-3-app/


1

Wiem, że zadawano to pytanie i odpowiadałem na nie dawno temu, ale właśnie zdarzyło mi się zobaczyć to pytanie i nie mogłem się powstrzymać przed udzieleniem odpowiedzi lub udostępnieniem naszego podejścia do implementacji logowania sql w naszym projekcie. Mam nadzieję, że to pomoże.

Obecnie jest w środowisku deweloperskim. Używamy „log4jdbc Driver Spy” do logowania sql.

Konfiguracja:

W swoim BuildConfig.groovy: dodaj poniższe zależności:

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

A w swoim źródle danych lub innej konfiguracji związanej z: [gdziekolwiek zdefiniowałeś konfigurację związaną ze źródłem danych], dodaj:

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'

}

Z własnego doświadczenia wynika, że ​​jest to przydatne i pomocne podczas debugowania. Więcej informacji można znaleźć na tej stronie. https://code.google.com/p/log4jdbc-remix/

Z poważaniem


0

Dla konkretnego bloku kodu możemy również stworzyć metodę akceptującą zamknięcie. na przykład.

 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

Jeśli masz zainstalowaną wtyczkę konsoli , możesz uzyskać rejestrowanie sql za pomocą tego małego fragmentu kodu.

// 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
}

Jest to odmiana wielu z powyższych rozwiązań, ale umożliwia dostosowanie wartości w czasie wykonywania. I podobnie jak inne rozwiązania, które sobie z tym radzą logToStdout, pokazuje tylko zapytania, a nie wartości wiązania.

Pomysł został skradziony z burtbeck z wpisem, który przeczytałem kilka lat temu, którego nie mogę teraz znaleźć. Został zredagowany do pracy z Grails 3.3.

Podobnej techniki można użyć do włączenia logowania dla określonych testów integracyjnych:

class SomeIntegrationSpec extends IntegrationSpec {

    def sessionFactory

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

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

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

Spowoduje to włączenie logowania sql tylko dla testów w tym jednym pliku.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.