我想在控制台或文件中登录Grails所做的所有查询,以检查性能。
我没有成功配置此配置。
任何想法都会有所帮助。
Answers:
设置
datasource {
...
logSql = true
}
在DataSource.groovy中(按照这些说明进行操作)足以使其在我的环境中正常工作。常见问题解答的某些部分似乎已过时(例如,“多对多列倒退”问题),因此与此同时它也可能有所更改。
logSql=true
单靠光棍是不够的。休眠日志记录也必须打开。参见@Pete的答案。
我发现执行以下操作更为有用,这是为了使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
// ...
}
format_sql = true
到hibernate
您的代码块中,DataSource.groovy
以获得格式正确的输出。
trace 'org.hibernate.type.BasicBinder'
对于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
试试这个:
log4j = {
...
debug 'org.hibernate.SQL'
trace 'org.hibernate.type.descriptor.sql.BasicBinder'
}
它避免了跟踪记录Hibernatetype
包的性能问题。这适用于Hibernate 3.6及更高版本。我从以下网址获得此信息:https : //burtbeckwith.com/blog/?p=1604
解决方案仅用于开发,而不用于生产。
以上所有答案均有效且正确。但是它们并没有以一种很好的人类可读的方式显示完整的查询。如果要查看最终查询(无任何?,?),则有两个选择。
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
纯仅供参考,但我使用p6spy记录SQL查询。这是一个小型的中间jdbc驱动程序。记录准确的查询,就像将其发送到服务器一样(包含参数)。
将其包含在您的项目中:
runtime 'p6spy:p6spy:3.0.0'
更改数据源驱动程序:
driverClassName: com.p6spy.engine.spy.P6SpyDriver
和您的jdbc网址:
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
不要忘记在生产中禁用它!
下一个对我有用:
# ...
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
// ...
我知道这个问题早就被问到并回答了。但是我只是偶然看到了这个问题,并不能阻止自己在我们的项目中回答或分享我们的sql日志记录实现方法。希望对您有所帮助。
当前它处于开发环境中。我们正在使用“ log4jdbc驱动程序间谍”来记录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/
国王的问候
对于特定的代码块,我们还可以创建一个接受闭包的方法。例如。
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")}
如果安装了控制台插件,则可以使用此小代码段获取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
它的其他解决方案一样,它仅显示查询,而不显示绑定值。
我几年前读过的一篇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"() {
...
}
这将仅打开该文件中的测试的sql日志记录。