File | Directory Monitoring Service

Log monitoring is prime requirement for any batch execution application. Often batch process get hung an we are not able to check if this happened.

To achieve this we need to have some sort of File/Directory Change Notification service is required, which should be able to detect any changes. One way of doing is to poll for file system but this is an in-efficient way of doing so.
One way to do so is to poll the file system looking for changes, but this approach is inefficient. It does not scale to applications that have hundreds of open files or directories to monitor.

Java provides java.nio.file package provides a file notification API called watch service API. This api provides a mechanism to register a directory with the watch service. While registering, you tell the service which events you are interested in:
  • File Creation
  • File deletion
  • File Modification
When Watchservice finds any such event it forwards to the regitered process.

Implementation of a simple DirectoryMonitor is as follows:
public class DirectoryWatcher {

 public static void doMonitor(Path path) {
  
  try {
   Boolean isFolder = (Boolean) Files.getAttribute(path,
     "basic:isDirectory", NOFOLLOW_LINKS);
   if (!isFolder) {
    throw new IllegalArgumentException("Path: " + path + " is not a folder");
   }
  } catch (IOException ioe) {
   // Folder does not exists
   ioe.printStackTrace();
  }
  
  System.out.println("Watching path: " + path);
  
  // We obtain the file system of the Path
  FileSystem fs = path.getFileSystem ();
  
  // We create the new WatchService using the new try() block
  try(WatchService service = fs.newWatchService()) {
   
   // We register the path to the service
   // We watch for creation events
   path.register(service, ENTRY_CREATE);
   
   // Start the infinite polling loop
   WatchKey key = null;
   while(true) {
    key = service.take();
    
    // Dequeueing events
    Kind kind = null;
    for(WatchEvent watchEvent : key.pollEvents()) {
     // Get the type of the event
     kind = watchEvent.kind();
     if (OVERFLOW == kind) {
      continue; //loop
     } else if (ENTRY_CREATE == kind) {
      // A new Path was created 
      Path newPath = ((WatchEvent) watchEvent).context();
      // Output
      System.out.println("New path created: " + newPath);
     }
    }
    
    if(!key.reset()) {
     break; //loop
    }
   }
   
  } catch(IOException ioe) {
   ioe.printStackTrace();
  } catch(InterruptedException ie) {
   ie.printStackTrace();
  }
  
 }

 public static void main(String[] args) throws IOException,
   InterruptedException {
  // Folder we are going to watch
  Path folder = Paths.get(System.getProperty("user.home"));
  doMontor(folder);
 }
}

Output

Watching path: /home/ram
New path created: a




0 comments: