diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java
index 3bf6207447..4fbb0caa08 100644
--- a/jOOQ/src/main/java/org/jooq/conf/Settings.java
+++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java
@@ -309,6 +309,8 @@ public class Settings
@XmlElement(defaultValue = "true")
protected Boolean executeLogging = true;
@XmlElement(defaultValue = "true")
+ protected Boolean diagnosticsLogging = true;
+ @XmlElement(defaultValue = "true")
protected Boolean updateRecordVersion = true;
@XmlElement(defaultValue = "true")
protected Boolean updateRecordTimestamp = true;
@@ -3673,6 +3675,30 @@ public class Settings
this.executeLogging = value;
}
+ /**
+ * When set to true, this will add jOOQ's default logging DiagnosticsListeners.
+ *
+ * @return
+ * possible object is
+ * {@link Boolean }
+ *
+ */
+ public Boolean isDiagnosticsLogging() {
+ return diagnosticsLogging;
+ }
+
+ /**
+ * Sets the value of the diagnosticsLogging property.
+ *
+ * @param value
+ * allowed object is
+ * {@link Boolean }
+ *
+ */
+ public void setDiagnosticsLogging(Boolean value) {
+ this.diagnosticsLogging = value;
+ }
+
/**
* Whether store(), insert(), and update() methods should update the record version prior to the operation, for use with {@link #executeWithOptimisticLocking}.
*
@@ -6068,6 +6094,11 @@ public class Settings
return this;
}
+ public Settings withDiagnosticsLogging(Boolean value) {
+ setDiagnosticsLogging(value);
+ return this;
+ }
+
public Settings withUpdateRecordVersion(Boolean value) {
setUpdateRecordVersion(value);
return this;
@@ -6767,6 +6798,7 @@ public class Settings
builder.append("executeListenerStartInvocationOrder", executeListenerStartInvocationOrder);
builder.append("executeListenerEndInvocationOrder", executeListenerEndInvocationOrder);
builder.append("executeLogging", executeLogging);
+ builder.append("diagnosticsLogging", diagnosticsLogging);
builder.append("updateRecordVersion", updateRecordVersion);
builder.append("updateRecordTimestamp", updateRecordTimestamp);
builder.append("executeWithOptimisticLocking", executeWithOptimisticLocking);
@@ -7934,6 +7966,15 @@ public class Settings
return false;
}
}
+ if (diagnosticsLogging == null) {
+ if (other.diagnosticsLogging!= null) {
+ return false;
+ }
+ } else {
+ if (!diagnosticsLogging.equals(other.diagnosticsLogging)) {
+ return false;
+ }
+ }
if (updateRecordVersion == null) {
if (other.updateRecordVersion!= null) {
return false;
@@ -8735,6 +8776,7 @@ public class Settings
result = ((prime*result)+((executeListenerStartInvocationOrder == null)? 0 :executeListenerStartInvocationOrder.hashCode()));
result = ((prime*result)+((executeListenerEndInvocationOrder == null)? 0 :executeListenerEndInvocationOrder.hashCode()));
result = ((prime*result)+((executeLogging == null)? 0 :executeLogging.hashCode()));
+ result = ((prime*result)+((diagnosticsLogging == null)? 0 :diagnosticsLogging.hashCode()));
result = ((prime*result)+((updateRecordVersion == null)? 0 :updateRecordVersion.hashCode()));
result = ((prime*result)+((updateRecordTimestamp == null)? 0 :updateRecordTimestamp.hashCode()));
result = ((prime*result)+((executeWithOptimisticLocking == null)? 0 :executeWithOptimisticLocking.hashCode()));
diff --git a/jOOQ/src/main/java/org/jooq/impl/DiagnosticsListeners.java b/jOOQ/src/main/java/org/jooq/impl/DiagnosticsListeners.java
index c6c8d3b176..3766cc7b8c 100644
--- a/jOOQ/src/main/java/org/jooq/impl/DiagnosticsListeners.java
+++ b/jOOQ/src/main/java/org/jooq/impl/DiagnosticsListeners.java
@@ -38,6 +38,7 @@
package org.jooq.impl;
import static java.lang.Boolean.FALSE;
+import static org.jooq.impl.Tools.combine;
import static org.jooq.impl.Tools.map;
import java.util.function.Predicate;
@@ -60,7 +61,12 @@ final class DiagnosticsListeners implements DiagnosticsListener {
}
static final DiagnosticsListeners get(Configuration configuration) {
- return new DiagnosticsListeners(configuration.diagnosticsListenerProviders());
+ DiagnosticsListenerProvider[] p = configuration.diagnosticsListenerProviders();
+
+ if (!FALSE.equals(configuration.settings().isDiagnosticsLogging()))
+ p = combine(DefaultDiagnosticsListenerProvider.providers(new LoggerDiagnosticsListener()), p);
+
+ return new DiagnosticsListeners(p);
}
private static final boolean check(DiagnosticsContext ctx, Predicate super Settings> test) {
diff --git a/jOOQ/src/main/java/org/jooq/impl/LoggerDiagnosticsListener.java b/jOOQ/src/main/java/org/jooq/impl/LoggerDiagnosticsListener.java
new file mode 100644
index 0000000000..0667598216
--- /dev/null
+++ b/jOOQ/src/main/java/org/jooq/impl/LoggerDiagnosticsListener.java
@@ -0,0 +1,160 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Other licenses:
+ * -----------------------------------------------------------------------------
+ * Commercial licenses for this work are available. These replace the above
+ * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
+ * database integrations.
+ *
+ * For more information, please visit: https://www.jooq.org/legal/licensing
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ */
+package org.jooq.impl;
+
+import static java.util.stream.Collectors.toList;
+
+import java.util.stream.Collectors;
+
+import org.jooq.DiagnosticsContext;
+import org.jooq.DiagnosticsListener;
+import org.jooq.tools.JooqLogger;
+
+/**
+ * A default implementation of a {@link DiagnosticsListener} that logs
+ * diagnostics.
+ *
+ * @author Lukas Eder
+ */
+public class LoggerDiagnosticsListener implements DiagnosticsListener {
+
+ private static final JooqLogger log = JooqLogger.getLogger(LoggerDiagnosticsListener.class);
+
+ private void log(String text, DiagnosticsContext ctx) {
+ log(text, ctx, null);
+ }
+
+ private void log(String text, DiagnosticsContext ctx, String additionalContext) {
+ if (log.isInfoEnabled()) {
+ if (additionalContext != null)
+ text += "\n" + additionalContext;
+
+ if (ctx.actualStatement().equals(ctx.normalisedStatement()))
+ text += "\nStatement: " + ctx.actualStatement();
+ else
+ text += "\nActual statement : " + ctx.actualStatement()
+ + "\nNormalised statement: " + ctx.normalisedStatement();
+
+ log.info("Diagnostics", text);
+ }
+ }
+
+ @Override
+ public void duplicateStatements(DiagnosticsContext ctx) {
+ log("""
+ Duplicate statements were encountered. Why is it bad? See: https://www.jooq.org/doc/latest/manual/sql-execution/diagnostics/diagnostics-duplicate-statements/
+ """,
+ ctx,
+ "Recent statements include: " + ctx.duplicateStatements().stream().limit(5).map(s -> "\n " + s).collect(toList())
+ );
+ }
+
+ @Override
+ public void repeatedStatements(DiagnosticsContext ctx) {
+ log("""
+ Repeated statements were encountered. Why is it bad? See: https://www.jooq.org/doc/latest/manual/sql-execution/diagnostics/diagnostics-repeated-statements/
+ """,
+ ctx,
+ "Recent statements include: " + ctx.repeatedStatements().stream().limit(5).map(s -> "\n " + s).collect(toList())
+ );
+ }
+
+
+ @Override
+ public void tooManyColumnsFetched(DiagnosticsContext ctx) {
+ log("""
+ Too many columns were fetched and never read. Why is it bad? See: https://www.jooq.org/doc/latest/manual/sql-execution/diagnostics/diagnostics-too-many-columns/
+ """,
+ ctx,
+ "Fetched columns : " + ctx.resultSetFetchedColumnNames()
+ + "\nConsumed columns: " + ctx.resultSetConsumedColumnNames()
+ );
+ }
+
+ @Override
+ public void tooManyRowsFetched(DiagnosticsContext ctx) {
+ log("""
+ Too many rows were fetched and never read. Why is it bad? See: https://www.jooq.org/doc/latest/manual/sql-execution/diagnostics/diagnostics-too-many-rows/
+ """,
+ ctx,
+ "Fetched rows : " + ctx.resultSetFetchedRows()
+ + "\nConsumed rows: " + ctx.resultSetConsumedRows()
+ );
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.18.0.xsd b/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.18.0.xsd
index 8c01a11969..b048f2bc6d 100644
--- a/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.18.0.xsd
+++ b/jOOQ/src/main/resources/org/jooq/xsd/jooq-runtime-3.18.0.xsd
@@ -1065,6 +1065,10 @@ case of which, this defaults to INLINED]]>
+
+
+
+