HHH-15300 - Lazy evaluation to statement.toString() when logging slow queries
This commit is contained in:
parent
6110c0a98a
commit
6728afadb7
|
@ -14,6 +14,7 @@ import org.jboss.logging.Logger;
|
||||||
|
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Centralize logging for SQL statements.
|
* Centralize logging for SQL statements.
|
||||||
|
@ -138,10 +139,7 @@ public class SqlStatementLogger {
|
||||||
* @param startTimeNanos Start time in nanoseconds.
|
* @param startTimeNanos Start time in nanoseconds.
|
||||||
*/
|
*/
|
||||||
public void logSlowQuery(Statement statement, long startTimeNanos) {
|
public void logSlowQuery(Statement statement, long startTimeNanos) {
|
||||||
if ( logSlowQuery < 1 ) {
|
logSlowQuery( statement::toString, startTimeNanos );
|
||||||
return;
|
|
||||||
}
|
|
||||||
logSlowQuery( statement.toString(), startTimeNanos );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,6 +150,15 @@ public class SqlStatementLogger {
|
||||||
*/
|
*/
|
||||||
@AllowSysOut
|
@AllowSysOut
|
||||||
public void logSlowQuery(String sql, long startTimeNanos) {
|
public void logSlowQuery(String sql, long startTimeNanos) {
|
||||||
|
logSlowQuery( () -> sql, startTimeNanos );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param sqlSupplier Supplier to generate The SQL query.
|
||||||
|
* @param startTimeNanos Start time in nanoseconds.
|
||||||
|
*/
|
||||||
|
@AllowSysOut
|
||||||
|
private void logSlowQuery(Supplier<String> sqlSupplier, long startTimeNanos) {
|
||||||
if ( logSlowQuery < 1 ) {
|
if ( logSlowQuery < 1 ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +169,7 @@ public class SqlStatementLogger {
|
||||||
long queryExecutionMillis = TimeUnit.NANOSECONDS.toMillis( System.nanoTime() - startTimeNanos );
|
long queryExecutionMillis = TimeUnit.NANOSECONDS.toMillis( System.nanoTime() - startTimeNanos );
|
||||||
|
|
||||||
if ( queryExecutionMillis > logSlowQuery ) {
|
if ( queryExecutionMillis > logSlowQuery ) {
|
||||||
String logData = "SlowQuery: " + queryExecutionMillis + " milliseconds. SQL: '" + sql + "'";
|
String logData = "SlowQuery: " + queryExecutionMillis + " milliseconds. SQL: '" + sqlSupplier.get() + "'";
|
||||||
LOG_SLOW.info( logData );
|
LOG_SLOW.info( logData );
|
||||||
if ( logToStdout ) {
|
if ( logToStdout ) {
|
||||||
System.out.println( logData );
|
System.out.println( logData );
|
||||||
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
package org.hibernate.engine.jdbc.spi;
|
||||||
|
|
||||||
|
import java.sql.Statement;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.mockito.stubbing.Answer;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Kyuhee Cho
|
||||||
|
*/
|
||||||
|
@TestForIssue(jiraKey = "HHH-15300")
|
||||||
|
class SqlStatementLoggerTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLogSlowQueryFromStatementWhenLoggingDisabled() {
|
||||||
|
SqlStatementLogger sqlStatementLogger = new SqlStatementLogger( false, false, false, 0L );
|
||||||
|
AtomicInteger callCounterToString = new AtomicInteger();
|
||||||
|
Statement statement = mockStatementForCountingToString( callCounterToString );
|
||||||
|
|
||||||
|
sqlStatementLogger.logSlowQuery( statement, System.nanoTime() );
|
||||||
|
assertEquals( 0, callCounterToString.get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLogSlowQueryFromStatementWhenLoggingEnabled() {
|
||||||
|
long logSlowQueryThresholdMillis = 300L;
|
||||||
|
SqlStatementLogger sqlStatementLogger = new SqlStatementLogger(
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
logSlowQueryThresholdMillis
|
||||||
|
);
|
||||||
|
AtomicInteger callCounterToString = new AtomicInteger();
|
||||||
|
Statement statement = mockStatementForCountingToString( callCounterToString );
|
||||||
|
|
||||||
|
long startTimeNanos = System.nanoTime() - TimeUnit.MILLISECONDS.toNanos( logSlowQueryThresholdMillis + 1 );
|
||||||
|
sqlStatementLogger.logSlowQuery( statement, startTimeNanos );
|
||||||
|
assertEquals( 1, callCounterToString.get() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Statement mockStatementForCountingToString(AtomicInteger callCounter) {
|
||||||
|
Statement statement = mock( Statement.class );
|
||||||
|
when( statement.toString() ).then( (Answer<String>) invocation -> {
|
||||||
|
callCounter.incrementAndGet();
|
||||||
|
return (String) invocation.callRealMethod();
|
||||||
|
} );
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue