[jOOQ/jOOQ#14146] Add a LoggingDiagnosticsListener, a default

DiagnosticsListener implementation that logs events
This commit is contained in:
Lukas Eder 2022-11-09 10:20:24 +01:00
parent 46f3ccbcd9
commit 044c70b3ba
4 changed files with 213 additions and 1 deletions

View File

@ -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()));

View File

@ -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) {

View File

@ -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()
);
}
}

View File

@ -1065,6 +1065,10 @@ case of which, this defaults to INLINED]]></jxb:javadoc></jxb:property></appinfo
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[When set to true, this will add jOOQ's default logging ExecuteListeners.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="diagnosticsLogging" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[When set to true, this will add jOOQ's default logging DiagnosticsListeners.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>
<element name="updateRecordVersion" type="boolean" minOccurs="0" maxOccurs="1" default="true">
<annotation><appinfo><jxb:property><jxb:javadoc><![CDATA[Whether store(), insert(), and update() methods should update the record version prior to the operation, for use with {@link #executeWithOptimisticLocking}.]]></jxb:javadoc></jxb:property></appinfo></annotation>
</element>