GH-2800 - Introduce additional loggers for cypher notifications.
Closes #2800
This commit is contained in:
@@ -14,6 +14,8 @@ include::custom-queries.adoc[]
|
||||
|
||||
include::spatial-types.adoc[]
|
||||
|
||||
include::logging.adoc[]
|
||||
|
||||
include::migrating.adoc[]
|
||||
|
||||
include::build.adoc[]
|
||||
|
||||
13
src/main/asciidoc/appendix/logging.adoc
Normal file
13
src/main/asciidoc/appendix/logging.adoc
Normal file
@@ -0,0 +1,13 @@
|
||||
[[logging]]
|
||||
= Logging
|
||||
|
||||
Spring Data Neo4j provides multiple loggers for https://neo4j.com/docs/status-codes/current/notifications/all-notifications/[Cypher notifications], starting with version 7.1.5.
|
||||
The logger `org.springframework.data.neo4j.cypher` includes all statements that were invoked by Spring Data Neo4j and all notifications sent from the server.
|
||||
To exclude or elevate some categories, the following loggers are in place:
|
||||
|
||||
* `org.springframework.data.neo4j.cypher.performance`
|
||||
* `org.springframework.data.neo4j.cypher.hint`
|
||||
* `org.springframework.data.neo4j.cypher.unrecognized`
|
||||
* `org.springframework.data.neo4j.cypher.unsupported`
|
||||
* `org.springframework.data.neo4j.cypher.deprecation`
|
||||
* `org.springframework.data.neo4j.cypher.generic`
|
||||
@@ -19,10 +19,13 @@ import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.neo4j.driver.NotificationCategory;
|
||||
import org.neo4j.driver.summary.InputPosition;
|
||||
import org.neo4j.driver.summary.Notification;
|
||||
import org.neo4j.driver.summary.Plan;
|
||||
import org.neo4j.driver.summary.ResultSummary;
|
||||
import org.springframework.core.log.LogAccessor;
|
||||
|
||||
/**
|
||||
* Utility class for dealing with result summaries.
|
||||
@@ -34,6 +37,12 @@ import org.neo4j.driver.summary.ResultSummary;
|
||||
final class ResultSummaries {
|
||||
|
||||
private static final String LINE_SEPARATOR = System.lineSeparator();
|
||||
private static final LogAccessor cypherPerformanceNotificationLog = new LogAccessor(LogFactory.getLog("org.springframework.data.neo4j.cypher.performance"));
|
||||
private static final LogAccessor cypherHintNotificationLog = new LogAccessor(LogFactory.getLog("org.springframework.data.neo4j.cypher.hint"));
|
||||
private static final LogAccessor cypherUnrecognizedNotificationLog = new LogAccessor(LogFactory.getLog("org.springframework.data.neo4j.cypher.unrecognized"));
|
||||
private static final LogAccessor cypherUnsupportedNotificationLog = new LogAccessor(LogFactory.getLog("org.springframework.data.neo4j.cypher.unsupported"));
|
||||
private static final LogAccessor cypherDeprecationNotificationLog = new LogAccessor(LogFactory.getLog("org.springframework.data.neo4j.cypher.deprecation"));
|
||||
private static final LogAccessor cypherGenericNotificationLog = new LogAccessor(LogFactory.getLog("org.springframework.data.neo4j.cypher.generic"));
|
||||
|
||||
/**
|
||||
* Does some post-processing on the giving result summary, especially logging all notifications
|
||||
@@ -57,15 +66,41 @@ final class ResultSummaries {
|
||||
String query = resultSummary.query().text();
|
||||
resultSummary.notifications()
|
||||
.forEach(notification -> {
|
||||
Consumer<String> log = switch (notification.severity()) {
|
||||
case "WARNING" -> Neo4jClient.cypherLog::warn;
|
||||
case "INFORMATION" -> Neo4jClient.cypherLog::info;
|
||||
default -> Neo4jClient.cypherLog::debug;
|
||||
};
|
||||
log.accept(ResultSummaries.format(notification, query));
|
||||
LogAccessor log = notification.category()
|
||||
.map(ResultSummaries::getLogAccessor)
|
||||
.orElse(Neo4jClient.cypherLog);
|
||||
Consumer<String> logFunction =
|
||||
switch (notification.severity()) {
|
||||
case "WARNING" -> log::warn;
|
||||
case "INFORMATION" -> log::info;
|
||||
default -> log::debug;
|
||||
};
|
||||
logFunction.accept(ResultSummaries.format(notification, query));
|
||||
});
|
||||
}
|
||||
|
||||
private static LogAccessor getLogAccessor(NotificationCategory category) {
|
||||
if (category == NotificationCategory.HINT) {
|
||||
return cypherHintNotificationLog;
|
||||
}
|
||||
if (category == NotificationCategory.DEPRECATION) {
|
||||
return cypherDeprecationNotificationLog;
|
||||
}
|
||||
if (category == NotificationCategory.PERFORMANCE) {
|
||||
return cypherPerformanceNotificationLog;
|
||||
}
|
||||
if (category == NotificationCategory.GENERIC) {
|
||||
return cypherGenericNotificationLog;
|
||||
}
|
||||
if (category == NotificationCategory.UNSUPPORTED) {
|
||||
return cypherUnsupportedNotificationLog;
|
||||
}
|
||||
if (category == NotificationCategory.UNRECOGNIZED) {
|
||||
return cypherUnrecognizedNotificationLog;
|
||||
}
|
||||
return Neo4jClient.cypherLog;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a formatted string for a notification issued for a given query.
|
||||
*
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011-2023 the original author or authors.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package org.springframework.data.neo4j.test;
|
||||
|
||||
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||
import ch.qos.logback.core.filter.Filter;
|
||||
import ch.qos.logback.core.spi.FilterReply;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Gerrit Meier
|
||||
*/
|
||||
public class TestLogFilter extends Filter<ILoggingEvent> {
|
||||
|
||||
private static final List<String> FILTER_MESSAGES = List.of(
|
||||
"ClientNotification.Statement.UnknownRelationshipTypeWarning",
|
||||
"ClientNotification.Statement.UnknownLabelWarning",
|
||||
"ClientNotification.Statement.UnknownPropertyKeyWarning",
|
||||
"ClientNotification.Statement.FeatureDeprecationWarning"
|
||||
);
|
||||
|
||||
@Override
|
||||
public FilterReply decide(ILoggingEvent event) {
|
||||
|
||||
String message = event.getMessage();
|
||||
|
||||
for (String filterMessage : FILTER_MESSAGES) {
|
||||
if (message.contains(filterMessage)) {
|
||||
return FilterReply.DENY;
|
||||
}
|
||||
}
|
||||
|
||||
return FilterReply.ACCEPT;
|
||||
}
|
||||
}
|
||||
@@ -18,7 +18,6 @@
|
||||
<configuration>
|
||||
|
||||
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="org.springframework.data.neo4j.test.TestLogFilter" />
|
||||
<encoder>
|
||||
<pattern>[%t] %d %5p %40.40c:%4L - %m%n</pattern>
|
||||
</encoder>
|
||||
@@ -31,6 +30,13 @@
|
||||
<logger name="InboundMessageDispatcher" level="info"/>
|
||||
|
||||
<logger name="org.springframework.data.neo4j.cypher" level="info"/>
|
||||
<logger name="org.springframework.data.neo4j.cypher.performance" level="info"/>
|
||||
<logger name="org.springframework.data.neo4j.cypher.hint" level="info"/>
|
||||
<logger name="org.springframework.data.neo4j.cypher.unrecognized" level="error"/>
|
||||
<logger name="org.springframework.data.neo4j.cypher.unsupported" level="error"/>
|
||||
<!-- if deprecation gets set to "warn" or finer, all id() deprecation will get logged -->
|
||||
<logger name="org.springframework.data.neo4j.cypher.deprecation" level="error"/>
|
||||
<logger name="org.springframework.data.neo4j.cypher.generic" level="error"/>
|
||||
<logger name="org.springframework.data.neo4j" level="info"/>
|
||||
<logger name="org.springframework.data.neo4j.test" level="info"/>
|
||||
<logger name="org.springframework.data.neo4j.repository.query.Neo4jQuerySupport" level="debug" />
|
||||
|
||||
Reference in New Issue
Block a user