-
Notifications
You must be signed in to change notification settings - Fork 38.3k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #27826 from Drezir
* pr/27826: Polish "Add CacheErrorHandler implementation that logs exceptions" Add CacheErrorHandler implementation that logs exceptions Closes gh-27826
- Loading branch information
Showing
2 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
105 changes: 105 additions & 0 deletions
105
...context/src/main/java/org/springframework/cache/interceptor/LoggingCacheErrorHandler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
* Copyright 2002-2022 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.cache.interceptor; | ||
|
||
import org.apache.commons.logging.Log; | ||
import org.apache.commons.logging.LogFactory; | ||
|
||
import org.springframework.cache.Cache; | ||
import org.springframework.lang.Nullable; | ||
import org.springframework.util.Assert; | ||
|
||
/** | ||
* A {@link CacheErrorHandler} implementation that logs error message. Can be | ||
* used when underlying cache errors should be ignored. | ||
* | ||
* @author Adam Ostrožlík | ||
* @author Stephane Nicoll | ||
* @since 5.3.16 | ||
*/ | ||
public class LoggingCacheErrorHandler implements CacheErrorHandler { | ||
|
||
private final Log logger; | ||
|
||
private final boolean logStacktrace; | ||
|
||
|
||
/** | ||
* Create an instance with the {@link Log logger} to use. | ||
* @param logger the logger to use | ||
* @param logStacktrace whether to log stack trace | ||
*/ | ||
public LoggingCacheErrorHandler(Log logger, boolean logStacktrace) { | ||
Assert.notNull(logger, "Logger must not be null"); | ||
this.logger = logger; | ||
this.logStacktrace = logStacktrace; | ||
} | ||
|
||
/** | ||
* Create an instance that does not log stack traces. | ||
*/ | ||
public LoggingCacheErrorHandler() { | ||
this(LogFactory.getLog(LoggingCacheErrorHandler.class), false); | ||
} | ||
|
||
|
||
@Override | ||
public void handleCacheGetError(RuntimeException exception, Cache cache, Object key) { | ||
logCacheError(logger, | ||
createMessage(cache, "failed to get entry with key '" + key + "'"), | ||
exception); | ||
} | ||
|
||
@Override | ||
public void handleCachePutError(RuntimeException exception, Cache cache, Object key, @Nullable Object value) { | ||
logCacheError(logger, | ||
createMessage(cache, "failed to put entry with key '" + key + "'"), | ||
exception); | ||
} | ||
|
||
@Override | ||
public void handleCacheEvictError(RuntimeException exception, Cache cache, Object key) { | ||
logCacheError(logger, | ||
createMessage(cache, "failed to evict entry with key '" + key + "'"), | ||
exception); | ||
} | ||
|
||
@Override | ||
public void handleCacheClearError(RuntimeException exception, Cache cache) { | ||
logCacheError(logger, createMessage(cache, "failed to clear entries"), exception); | ||
} | ||
|
||
/** | ||
* Log the specified message. | ||
* @param logger the logger | ||
* @param message the message | ||
* @param ex the exception | ||
*/ | ||
protected void logCacheError(Log logger, String message, RuntimeException ex) { | ||
if (this.logStacktrace) { | ||
logger.warn(message, ex); | ||
} | ||
else { | ||
logger.warn(message); | ||
} | ||
} | ||
|
||
private String createMessage(Cache cache, String reason) { | ||
return String.format("Cache '%s' %s", cache.getName(), reason); | ||
} | ||
|
||
} |
76 changes: 76 additions & 0 deletions
76
...xt/src/test/java/org/springframework/cache/interceptor/LoggingCacheErrorHandlerTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
/* | ||
* Copyright 2002-2022 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.cache.interceptor; | ||
|
||
import org.apache.commons.logging.Log; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import org.springframework.cache.support.NoOpCache; | ||
|
||
import static org.mockito.Mockito.mock; | ||
import static org.mockito.Mockito.verify; | ||
|
||
/** | ||
* Tests for {@link LoggingCacheErrorHandler}. | ||
* | ||
* @author Adam Ostrožlík | ||
* @author Stephane Nicoll | ||
*/ | ||
public class LoggingCacheErrorHandlerTests { | ||
|
||
@Test | ||
void handleGetCacheErrorLogsAppropriateMessage() { | ||
Log logger = mock(Log.class); | ||
LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(logger, false); | ||
handler.handleCacheGetError(new RuntimeException(), new NoOpCache("NOOP"), "key"); | ||
verify(logger).warn("Cache 'NOOP' failed to get entry with key 'key'"); | ||
} | ||
|
||
@Test | ||
void handlePutCacheErrorLogsAppropriateMessage() { | ||
Log logger = mock(Log.class); | ||
LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(logger, false); | ||
handler.handleCachePutError(new RuntimeException(), new NoOpCache("NOOP"), "key", new Object()); | ||
verify(logger).warn("Cache 'NOOP' failed to put entry with key 'key'"); | ||
} | ||
|
||
@Test | ||
void handleEvictCacheErrorLogsAppropriateMessage() { | ||
Log logger = mock(Log.class); | ||
LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(logger, false); | ||
handler.handleCacheEvictError(new RuntimeException(), new NoOpCache("NOOP"), "key"); | ||
verify(logger).warn("Cache 'NOOP' failed to evict entry with key 'key'"); | ||
} | ||
|
||
@Test | ||
void handleClearErrorLogsAppropriateMessage() { | ||
Log logger = mock(Log.class); | ||
LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(logger, false); | ||
handler.handleCacheClearError(new RuntimeException(), new NoOpCache("NOOP")); | ||
verify(logger).warn("Cache 'NOOP' failed to clear entries"); | ||
} | ||
|
||
@Test | ||
void handleCacheErrorWithStacktrace() { | ||
Log logger = mock(Log.class); | ||
LoggingCacheErrorHandler handler = new LoggingCacheErrorHandler(logger, true); | ||
RuntimeException exception = new RuntimeException(); | ||
handler.handleCacheGetError(exception, new NoOpCache("NOOP"), "key"); | ||
verify(logger).warn("Cache 'NOOP' failed to get entry with key 'key'", exception); | ||
} | ||
|
||
} |