Quero registrar no console ou em um arquivo todas as consultas que o Grails faz, para verificar o desempenho.
Eu havia configurado isso sem sucesso.
Qualquer ideia ajudaria.
Quero registrar no console ou em um arquivo todas as consultas que o Grails faz, para verificar o desempenho.
Eu havia configurado isso sem sucesso.
Qualquer ideia ajudaria.
Respostas:
Configuração
datasource {
...
logSql = true
}
em DataSource.groovy (de acordo com essas instruções) foi o suficiente para fazê-lo funcionar em meu ambiente. Parece que partes do FAQ estão desatualizadas (por exemplo, a questão "as colunas de muitos para muitos ao contrário"), então isso também pode ser algo que mudou nesse meio tempo.
logSql=true
sozinho não é suficiente. O registro de hibernação também deve ser ativado. Veja a resposta de @Pete.
Acho mais útil fazer o seguinte, que é permitir que o log do Hibernate registre o SQL junto com as variáveis de ligação (para que você possa ver os valores passados em suas chamadas e replicar facilmente o SQL em seu editor ou de outra forma).
No seu Config.groovy
, adicione o seguinte ao seu bloco log4j:
log4j = {
// Enable Hibernate SQL logging with param values
trace 'org.hibernate.type'
debug 'org.hibernate.SQL'
//the rest of your logging config
// ...
}
format_sql = true
no hibernate
bloco do seu DataSource.groovy
para uma saída bem formatada.
trace 'org.hibernate.type.BasicBinder'
Para grails 3. *
Opção # 1 adicionar o seguinte a logback.groovy
logger("org.hibernate.SQL", DEBUG, ["STDOUT"], false)
logger("org.hibernate.type.descriptor.sql.BasicBinder", TRACE, ["STDOUT"], false)
ou
A opção 2 adiciona o seguinte ao dataSource no application.yml. No entanto, esta abordagem não registra os valores dos parâmetros
environments:
local:
dataSource:
logSql: true
formatSql: true
Experimente isto:
log4j = {
...
debug 'org.hibernate.SQL'
trace 'org.hibernate.type.descriptor.sql.BasicBinder'
}
Ele evita os problemas de desempenho do log de rastreamento do type
pacote Hibernate . Isso funciona com o Hibernate 3.6 e superior. Peguei isso em: https://burtbeckwith.com/blog/?p=1604
A solução é apenas para desenvolvimento, não produção.
Todas as respostas acima funcionam e estão corretas. Mas eles não mostram a consulta completa de uma forma legível por humanos. Se quiser ver a consulta final (sem nenhum?,?), Você tem duas opções.
A) proxy sua conexão jdbc com log4jdbc ou p6Spy.
B) olhe para ele no nível do banco de dados. Por exemplo, muito fácil de fazer com o mysql.
Descubra onde você está general_log_file. Registro geral ativo se não estiver ativado.
mysql command line> show variables like "%general_log%";
mysql command line> set global general_log = true;
Agora tudo está registrado em seu arquivo de log. Exemplo de Mac / Linux para mostrar um bom fluxo de suas consultas.
tail -f path_to_log_file
Puro apenas para referência, mas eu uso p6spy para registrar as consultas SQL. É um pequeno driver jdbc intermediário. A consulta exata é registrada como seria enviada ao servidor (com parâmetros incluídos).
inclua-o em seu projeto:
runtime 'p6spy:p6spy:3.0.0'
Altere o driver da fonte de dados:
driverClassName: com.p6spy.engine.spy.P6SpyDriver
E seu url jdbc:
url: jdbc:p6spy:mysql://
Configure-o usando spy.properties (em 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
Não se esqueça de desabilitar isso para produção!
Próximo funciona para mim:
# ...
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:...
# ...
// ...
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
// ...
Eu sei que isso foi perguntado e respondido há muito tempo. Mas aconteceu de eu ver esta pergunta e não pude deixar de responder ou compartilhar nossa abordagem de implementação de log sql em nosso projeto. Espero que seja de alguma ajuda.
Atualmente está em ambiente de desenvolvimento. Estamos usando o "log4jdbc Driver Spy" para registrar o sql.
Em seu BuildConfig.groovy: adicione as dependências abaixo:
dependencies {
.....
runtime 'org.lazyluke:log4jdbc-remix:0.2.7'
}
E em seu DataSource ou outra configuração relacionada: [onde quer que você tenha definido a configuração relacionada à fonte de dados], adicione:
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'
}
Pela minha experiência pessoal, achei bastante útil e útil durante a depuração. Também mais informações você pode encontrar neste site. https://code.google.com/p/log4jdbc-remix/
Rei Atenciosamente
Para um determinado bloco de código, também podemos criar um método que aceite um encerramento. por exemplo.
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")}
Se você tiver o plugin do console instalado, você pode obter o registro do sql com este pequeno trecho de código.
// 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
}
Esta é uma variação de muitas das soluções acima, mas permite que você ajuste o valor em tempo de execução. E assim como as outras soluções que lidam com logToStdout
isso só mostra as consultas e não os valores de bind.
A ideia foi roubada de uma postagem burtbeckwith que li há alguns anos e não consigo encontrar agora. Ele foi editado para funcionar com grails 3.3.
Uma técnica semelhante pode ser usada para ativar o registro para testes de integração específicos:
class SomeIntegrationSpec extends IntegrationSpec {
def sessionFactory
def setup() {
sessionFactory.settings.sqlStatementLogger.logToStdout = true
}
def cleanup() {
sessionFactory.settings.sqlStatementLogger.logToStdout = false
}
void "some test"() {
...
}
Isso ativará o log de sql apenas para os testes neste arquivo.