From 96e7977f161375c95acafb44d484996f6b930b40 Mon Sep 17 00:00:00 2001 From: brinn <brinn> Date: Thu, 28 Jun 2012 11:43:50 +0000 Subject: [PATCH] Add support for logging dropbox activity. If enabled, a file will be touched whenever DirectoryScanningTimerTask starts a processing round. SVN: 25922 --- .../DirectoryScanningTimerTask.java | 104 +++++++++++++++++- .../DirectoryScanningTimerTaskTest.java | 10 +- 2 files changed, 108 insertions(+), 6 deletions(-) diff --git a/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTask.java b/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTask.java index adb6359ff8f..e8d2ca3102f 100644 --- a/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTask.java +++ b/common/source/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTask.java @@ -18,6 +18,7 @@ package ch.systemsx.cisd.common.filesystem; import java.io.File; import java.io.FileFilter; +import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; @@ -26,6 +27,7 @@ import java.util.Map; import java.util.Set; import java.util.TimerTask; +import org.apache.commons.io.FileUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Level; @@ -79,6 +81,8 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime private String threadNameOrNull; + private File activityLogDirectoryOrNull; + /** * Indicates that we should try to exit the {@link #run()} method as soon as possible. * <p> @@ -87,6 +91,24 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime */ private volatile boolean stopRun; + /** + * 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 directoryScanningHandler A directory scanning handler. + * @param threadName The name of the thread + * @param activityLogDirectory The directory to log activity to. + */ + public DirectoryScanningTimerTask(final File sourceDirectory, final FileFilter filter, + final IPathHandler handler, final IDirectoryScanningHandler directoryScanningHandler, + final String threadName, final File activityLogDirectory) + { + this(asScannedStore(sourceDirectory, filter), directoryScanningHandler, PathHandlerAdapter + .asScanningHandler(sourceDirectory, handler), 0, threadName, activityLogDirectory); + } + /** * Creates a <var>DirectoryScanningTimerTask</var>. * @@ -99,7 +121,7 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime final IPathHandler handler, final IDirectoryScanningHandler directoryScanningHandler) { this(asScannedStore(sourceDirectory, filter), directoryScanningHandler, PathHandlerAdapter - .asScanningHandler(sourceDirectory, handler), 0); + .asScanningHandler(sourceDirectory, handler), 0, null, null); } /** @@ -113,7 +135,8 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime final IStoreHandler storeHandler, final IDirectoryScanningHandler directoryScanningHandler) { - this(asScannedStore(sourceDirectory, filter), directoryScanningHandler, storeHandler, 0); + this(asScannedStore(sourceDirectory, filter), directoryScanningHandler, storeHandler, 0, + null, null); } /** @@ -129,6 +152,21 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime this(sourceDirectory, filter, pathHandler, 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 pathHandler The handler that is used for treating the matching paths. + * @param threadName The name of the thread + * @param activityLogDirectory The directory to log activity to. + */ + public DirectoryScanningTimerTask(final File sourceDirectory, final FileFilter filter, + final IPathHandler pathHandler, String threadName, File activityLogDirectory) + { + this(sourceDirectory, filter, pathHandler, 0, threadName, activityLogDirectory); + } + /** * Creates a <var>DirectoryScanningTimerTask</var>. * @@ -138,10 +176,13 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime * @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) + * @param threadName The name of the thread + * @param activityLogDirectory The directory to log activity to. */ public DirectoryScanningTimerTask(final IScannedStore scannedStore, final IDirectoryScanningHandler directoryScanningHandler, - final IStoreHandler storeHandler, final int ignoredErrorCount) + final IStoreHandler storeHandler, final int ignoredErrorCount, final String threadName, + final File activityLogDirectory) { assert scannedStore != null; assert storeHandler != null; @@ -155,6 +196,17 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime new ConditionalNotificationLogger(operationLog, Level.WARN, notificationLog, ignoredErrorCount); this.errorLog = new LinkedHashMap<StoreItem, String>(); + this.threadNameOrNull = threadName; + this.activityLogDirectoryOrNull = activityLogDirectory; + if (activityLogDirectory != null && activityLogDirectory.isDirectory() == false) + { + activityLogDirectory.mkdirs(); + if (activityLogDirectory.isDirectory() == false) + { + operationLog.error("Cannot create activityLogDirectory " + activityLogDirectory + + " - activity logging disabled."); + } + } } /** @@ -172,7 +224,28 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime { this(asScannedStore(sourceDirectory, fileFilter), new FaultyPathDirectoryScanningHandler( sourceDirectory, pathHandler, null), PathHandlerAdapter.asScanningHandler( - sourceDirectory, pathHandler), ignoredErrorCount); + sourceDirectory, pathHandler), ignoredErrorCount, null, null); + } + + /** + * Creates a <var>DirectoryScanningTimerTask</var>. + * + * @param sourceDirectory The directory to scan for entries. + * @param fileFilter The file filter that picks the entries to handle. + * @param pathHandler 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) + * @param threadName The name of the thread + * @param activityLogDirectory The directory to log activity to. + */ + DirectoryScanningTimerTask(final File sourceDirectory, final FileFilter fileFilter, + final IPathHandler pathHandler, final int ignoredErrorCount, final String threadName, + final File activityLogDirectory) + { + this(asScannedStore(sourceDirectory, fileFilter), new FaultyPathDirectoryScanningHandler( + sourceDirectory, pathHandler, null), PathHandlerAdapter.asScanningHandler( + sourceDirectory, pathHandler), ignoredErrorCount, threadName, activityLogDirectory); } private final static IScannedStore asScannedStore(final File directory, final FileFilter filter) @@ -225,7 +298,11 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime { operationLog.trace(String.format("Start scanning directory '%s'.", sourceDirectory)); } - threadNameOrNull = Thread.currentThread().getName(); + if (threadNameOrNull == null) + { + threadNameOrNull = Thread.currentThread().getName(); + } + logActivity(); try { didSomeWork = false; @@ -366,6 +443,23 @@ public final class DirectoryScanningTimerTask extends TimerTask implements ITime } } + private void logActivity() + { + if (activityLogDirectoryOrNull != null) + { + final File activityFile = + new File(activityLogDirectoryOrNull, threadNameOrNull.replace(' ', + '_')); + try + { + FileUtils.touch(activityFile); + } catch (IOException ex) + { + operationLog.warn("Cannot touch activity file " + activityFile); + } + } + } + private void cleanseErrorLog(StoreItem[] allStoreItemsOrNull) { if (allStoreItemsOrNull == null) diff --git a/common/sourceTest/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTaskTest.java b/common/sourceTest/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTaskTest.java index f1d82cdbd6b..b413e8bf40a 100644 --- a/common/sourceTest/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTaskTest.java +++ b/common/sourceTest/java/ch/systemsx/cisd/common/filesystem/DirectoryScanningTimerTaskTest.java @@ -17,6 +17,7 @@ package ch.systemsx.cisd.common.filesystem; import static ch.systemsx.cisd.common.filesystem.FileUtilities.ACCEPT_ALL_FILTER; +import static ch.systemsx.cisd.common.filesystem.FileUtilities.ACCEPT_ALL_BUT_HIDDEN_FILTER; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertTrue; @@ -149,12 +150,19 @@ public class DirectoryScanningTimerTaskTest { final File someFile = new File(workingDirectory, "some_file"); createNewFile(someFile); + final File activityLogDir = new File(workingDirectory, ".activity_log"); + final String threadName = "abc_test"; final DirectoryScanningTimerTask scanner = - new DirectoryScanningTimerTask(workingDirectory, ACCEPT_ALL_FILTER, mockPathHandler); + new DirectoryScanningTimerTask(workingDirectory, ACCEPT_ALL_BUT_HIDDEN_FILTER, + mockPathHandler, threadName, activityLogDir); assertEquals(0, mockPathHandler.handledPaths.size()); scanner.run(); assertEquals(1, mockPathHandler.handledPaths.size()); assertEquals(someFile, mockPathHandler.handledPaths.get(0)); + final File activityLogFile = new File(activityLogDir, threadName); + assertTrue(activityLogFile.exists()); + final long milliDiff = System.currentTimeMillis() - activityLogFile.lastModified(); + assertTrue(milliDiff + "ms", milliDiff < 1000); } @Test -- GitLab