Skip to content
Snippets Groups Projects
Commit e6e3a029 authored by brinn's avatar brinn
Browse files

add: feature to ignore a specifiable number of errors in listing a directory and log only then

SVN: 2063
parent f8f4ef5c
No related branches found
No related tags found
No related merge requests found
......@@ -61,10 +61,13 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ISelf
};
private final IPathHandler handler;
private final File sourceDirectory;
private boolean errorReadingDirectory;
/** The number of consecutive errors of reading a directory that need to occur before the event is logged. */
private final int ignoredErrorCount;
private int errorCountReadingDirectory;
private final FileFilter filter;
......@@ -82,11 +85,29 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ISelf
* @param handler The handler that is used for treating the matching paths.
*/
public DirectoryScanningTimerTask(File sourceDirectory, FileFilter filter, IPathHandler handler)
{
this(sourceDirectory, filter, handler, 0);
}
/**
* Creates a <var>DirectoryScanningTimerTask</var>.
*
* @param sourceDirectory The directory to scan for entries.
* @param filter The file filter that picks the entries to handle.
* @param handler The handler that is used for treating the matching paths.
* @param ignoredErrorCount The number of consecutive errors of reading the directory that need to occur before the
* next error is logged (can be used to suppress error when the directory is on a remote share and the
* server is flaky sometimes)
*/
public DirectoryScanningTimerTask(File sourceDirectory, FileFilter filter, IPathHandler handler,
int ignoredErrorCount)
{
assert sourceDirectory != null;
assert filter != null;
assert handler != null;
assert ignoredErrorCount >= 0;
this.ignoredErrorCount = ignoredErrorCount;
this.sourceDirectory = sourceDirectory;
this.filter = filter;
this.handler = handler;
......@@ -154,18 +175,24 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ISelf
private File[] listFiles()
{
final boolean logErrors = (errorReadingDirectory == false);
final boolean logErrors = (errorCountReadingDirectory == ignoredErrorCount); // Avoid mailbox flooding.
final ISimpleLogger errorLogger = logErrors ? createSimpleErrorLogger() : null;
final File[] paths = FileUtilities.tryListFiles(sourceDirectory, filter, errorLogger);
if (errorReadingDirectory && paths != null)
if (errorCountReadingDirectory > ignoredErrorCount && paths != null)
{
if (notificationLog.isInfoEnabled())
{
notificationLog.info(String.format("Directory '%s' is available again.", sourceDirectory));
}
}
errorReadingDirectory = (paths == null); // Avoid mailbox flooding.
if (paths == null)
{
++errorCountReadingDirectory;
} else
{
errorCountReadingDirectory = 0;
}
return (paths == null) ? new File[0] : paths;
}
......
......@@ -109,6 +109,11 @@ public final class LogMonitoringAppender extends AppenderSkeleton
return false;
}
public void verifyLogHasNotHappened()
{
assert logHappened == false : "Following log snipped was found but shouldn't have: " + messagePart;
}
public void verifyLogHasHappened()
{
assert logHappened : "Following log snippet has been missed: " + messagePart;
......
......@@ -138,9 +138,10 @@ public class DirectoryScanningTimerTaskTest
file.delete();
file.deleteOnExit();
file.createNewFile();
final DirectoryScanningTimerTask task = new DirectoryScanningTimerTask(file, ACCEPT_ALL_FILTER, mockPathHandler);
final DirectoryScanningTimerTask task =
new DirectoryScanningTimerTask(file, ACCEPT_ALL_FILTER, mockPathHandler);
task.check();
}
}
@Test(groups =
{ "requires_unix" }, expectedExceptions =
......@@ -156,7 +157,8 @@ public class DirectoryScanningTimerTaskTest
try
{
// Here we should get an AssertationError
final DirectoryScanningTimerTask task = new DirectoryScanningTimerTask(readOnlyDirectory, ACCEPT_ALL_FILTER, mockPathHandler);
final DirectoryScanningTimerTask task =
new DirectoryScanningTimerTask(readOnlyDirectory, ACCEPT_ALL_FILTER, mockPathHandler);
task.check();
} finally
{
......@@ -359,4 +361,64 @@ public class DirectoryScanningTimerTaskTest
LogMonitoringAppender.removeAppender(appender2);
}
@Test
public void testSuppressLogging() throws IOException
{
final File dir = new File(workingDirectory, "testSuppressLogging");
dir.mkdir();
LogMonitoringAppender appenderError =
LogMonitoringAppender.addAppender(LogCategory.NOTIFY, "Failed to get listing of directory");
LogMonitoringAppender appenderOK =
LogMonitoringAppender.addAppender(LogCategory.NOTIFY, "' is available again");
final int numberOfErrorsToIgnore = 2;
// The directory needs to exist when the scanner is created, otherwise the self-test will fail.
final DirectoryScanningTimerTask scanner =
new DirectoryScanningTimerTask(dir, ACCEPT_ALL_FILTER, mockPathHandler, numberOfErrorsToIgnore);
dir.delete();
assert dir.exists() == false;
// First error -> ignored
scanner.run();
appenderError.verifyLogHasNotHappened();
// Second error -> ignored
scanner.run();
appenderError.verifyLogHasNotHappened();
// Third error -> recorded
scanner.run();
appenderError.verifyLogHasHappened();
dir.mkdir();
assert dir.exists();
// Now it is OK again and that should be logged as well
scanner.run();
appenderOK.verifyLogHasHappened();
LogMonitoringAppender.removeAppender(appenderError);
LogMonitoringAppender.removeAppender(appenderOK);
}
@Test
public void testDoNotLogDirectoryAvailableWhenNoErrorWasLogged() throws IOException
{
final File dir = new File(workingDirectory, "testDoNotLogDirectoryAvailableWhenNoErrorWasLogged");
dir.mkdir();
LogMonitoringAppender appender =
LogMonitoringAppender.addAppender(LogCategory.NOTIFY, "' is available again.");
final int numberOfErrorsToIgnore = 2;
// The directory needs to exist when the scanner is created, otherwise the self-test will fail.
final DirectoryScanningTimerTask scanner =
new DirectoryScanningTimerTask(dir, ACCEPT_ALL_FILTER, mockPathHandler, numberOfErrorsToIgnore);
dir.delete();
assert dir.exists() == false;
// First error -> ignored
scanner.run();
appender.verifyLogHasNotHappened();
// Second error -> ignored
scanner.run();
appender.verifyLogHasNotHappened();
dir.mkdir();
assert dir.exists();
// Now it's OK, but nothing should be logged because the error wasn't logged either.
scanner.run();
appender.verifyLogHasNotHappened();
LogMonitoringAppender.removeAppender(appender);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment