From 008e7c5f2c0b9458bdde0b38dbbaa837e355cfb5 Mon Sep 17 00:00:00 2001 From: iMoHax Date: Tue, 31 May 2016 17:01:45 +0300 Subject: [PATCH] implement log watcher --- .../main/java/ru/trader/edlog/LogHandler.java | 10 ++ .../main/java/ru/trader/edlog/LogReader.java | 93 ++++++++++++++++++ .../main/java/ru/trader/edlog/LogWatcher.java | 98 +++++++++++++++++++ .../java/ru/trader/edlog/LogWatcherTest.java | 33 +++++++ utils/src/test/resources/log4j.properties | 3 +- 5 files changed, 236 insertions(+), 1 deletion(-) create mode 100644 utils/src/main/java/ru/trader/edlog/LogHandler.java create mode 100644 utils/src/main/java/ru/trader/edlog/LogReader.java create mode 100644 utils/src/main/java/ru/trader/edlog/LogWatcher.java create mode 100644 utils/src/test/java/ru/trader/edlog/LogWatcherTest.java diff --git a/utils/src/main/java/ru/trader/edlog/LogHandler.java b/utils/src/main/java/ru/trader/edlog/LogHandler.java new file mode 100644 index 0000000..e0f7ba8 --- /dev/null +++ b/utils/src/main/java/ru/trader/edlog/LogHandler.java @@ -0,0 +1,10 @@ +package ru.trader.edlog; + +import java.nio.file.Path; + +public interface LogHandler { + + void createFile(Path file); + void updateFile(Path file); + void close(); +} diff --git a/utils/src/main/java/ru/trader/edlog/LogReader.java b/utils/src/main/java/ru/trader/edlog/LogReader.java new file mode 100644 index 0000000..f917fc5 --- /dev/null +++ b/utils/src/main/java/ru/trader/edlog/LogReader.java @@ -0,0 +1,93 @@ +package ru.trader.edlog; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.*; +import java.nio.file.Path; + +public class LogReader implements LogHandler { + private final static Logger LOG = LoggerFactory.getLogger(LogReader.class); + + private final String pattern; + private BufferedReader reader; + private File file; + + public LogReader(String pattern) { + this.pattern = pattern; + } + + private void changeFile(File file){ + if (this.file != null && this.file.equals(file)) return; + LOG.trace("Watch new file {}", file); + FileReader fileReader; + try { + fileReader = new FileReader(file); + if (reader != null){ + closeReader(); + } + reader = new BufferedReader(fileReader); + this.file = file; + } catch (FileNotFoundException e) { + LOG.error("Not found log file", e); + } + } + + private void readFile(){ + LOG.trace("Read file {}", file); + String line; + try { + while ((line = reader.readLine()) != null){ + outLine(line); + } + } catch (IOException e) { + LOG.error("Error on read log file",e); + } + } + + protected void outLine(String line){ + LOG.trace("Reading line:{}", line); + } + + @Override + public void createFile(Path file) { + if (file.toString().matches(pattern)){ + changeFile(file.toFile()); + readFile(); + } else { + LOG.trace("{} Is not log file, skip", file); + } + } + + @Override + public void updateFile(Path file) { + if (file.toString().matches(pattern)){ + File f = file.toFile(); + if (this.file == null){ + changeFile(f); + readFile(); + } else { + if (this.file.equals(f)){ + readFile(); + } + } + } else { + LOG.trace("{} Is not log file, skip", file); + } + + } + + private void closeReader(){ + if (reader == null) return; + try { + reader.close(); + } catch (IOException e) { + LOG.warn("Error on close old reader", e); + } + } + + @Override + public void close() { + closeReader(); + } +} diff --git a/utils/src/main/java/ru/trader/edlog/LogWatcher.java b/utils/src/main/java/ru/trader/edlog/LogWatcher.java new file mode 100644 index 0000000..ab18656 --- /dev/null +++ b/utils/src/main/java/ru/trader/edlog/LogWatcher.java @@ -0,0 +1,98 @@ +package ru.trader.edlog; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; +import java.nio.file.*; +import java.util.concurrent.TimeUnit; + +public class LogWatcher { + private final static Logger LOG = LoggerFactory.getLogger(LogWatcher.class); + + private final Path dir; + private final LogHandler handler; + private WatchService watcher; + private boolean notCancel; + private Thread thread; + + public LogWatcher(String dir, LogHandler handler) { + this(FileSystems.getDefault().getPath(dir), handler); + } + + public LogWatcher(Path dir, LogHandler handler) { + this.dir = dir; + this.handler = handler; + thread = new Thread(){ + @Override + public void run() { + watch(); + } + }; + } + + public void start() throws IOException { + LOG.debug("Start log watch service, dir {}", dir); + if (watcher != null){ + throw new IllegalStateException("Watch service already started"); + } + watcher = FileSystems.getDefault().newWatchService(); + dir.register(watcher, StandardWatchEventKinds.ENTRY_CREATE, StandardWatchEventKinds.ENTRY_MODIFY); + notCancel = true; + thread.start(); + } + + private void watch(){ + try { + while (notCancel) { + WatchKey key = watcher.poll(5, TimeUnit.SECONDS); + if (key == null) continue; + for (WatchEvent event: key.pollEvents()) { + WatchEvent.Kind kind = event.kind(); + if (kind == StandardWatchEventKinds.OVERFLOW) { + continue; + } + @SuppressWarnings("unchecked") + WatchEvent ev = (WatchEvent)event; + Path filename = ev.context(); + Path file = dir.resolve(filename); + if (ev.kind() == StandardWatchEventKinds.ENTRY_CREATE){ + LOG.trace("File {} was created", file); + handler.createFile(file); + } else + if (ev.kind() == StandardWatchEventKinds.ENTRY_MODIFY){ + LOG.trace("File {} was modified", file); + handler.updateFile(file); + } + } + + boolean valid = key.reset(); + if (!valid) { + break; + } + } + } catch (InterruptedException | ClosedWatchServiceException e) { + if (!Thread.currentThread().isInterrupted()){ + Thread.currentThread().interrupt(); + } + } finally { + close(); + } + + } + + private void close() { + if (watcher != null) try { + watcher.close(); + } catch (IOException e) { + LOG.warn("Error on close log watcher", e); + } + handler.close(); + watcher = null; + } + + public void stop(){ + LOG.debug("Stop log watch service"); + notCancel = false; + } +} diff --git a/utils/src/test/java/ru/trader/edlog/LogWatcherTest.java b/utils/src/test/java/ru/trader/edlog/LogWatcherTest.java new file mode 100644 index 0000000..c6276a9 --- /dev/null +++ b/utils/src/test/java/ru/trader/edlog/LogWatcherTest.java @@ -0,0 +1,33 @@ +package ru.trader.edlog; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; + +public class LogWatcherTest { + private final static Logger LOG = LoggerFactory.getLogger(LogWatcherTest.class); + + private static String readLine(String format, Object... args) throws IOException { + if (System.console() != null) { + return System.console().readLine(format, args); + } + System.out.print(String.format(format, args)); + BufferedReader reader = new BufferedReader(new InputStreamReader( + System.in)); + return reader.readLine(); + } + + public static void main(String args[]) throws Exception { + LOG.info("Test log watcher"); + LogHandler handler = new LogReader(".+\\.log$"); + String path = readLine("Watch dir:"); + LogWatcher watcher = new LogWatcher(path, handler); + watcher.start(); + Thread.sleep(5*60*1000); + watcher.stop(); + } + +} diff --git a/utils/src/test/resources/log4j.properties b/utils/src/test/resources/log4j.properties index c4b2c17..0231244 100644 --- a/utils/src/test/resources/log4j.properties +++ b/utils/src/test/resources/log4j.properties @@ -5,4 +5,5 @@ log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%p: %d{dd.MM.yyyy HH:mm:ss} (%F:%L) - %m%n -log4j.logger.ru.trader.edce = DEBUG \ No newline at end of file +log4j.logger.ru.trader.edce = DEBUG +log4j.logger.ru.trader.edlog = DEBUG \ No newline at end of file