package chatty.util.chatlog;
import chatty.util.chatlog.LogWriter.LogItem;
import java.nio.file.Path;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Logger;
/**
* Starts a new LogWriter and sends lines to it through the queue.
*
* @author tduva
*/
public class LogManager {
private static final Logger LOGGER = Logger.getLogger(LogManager.class.getName());
private static final int QUEUE_CAPACITY = 100;
private static final int MAX_WAIT = 10*1000;
private final AtomicInteger errors = new AtomicInteger();
private final BlockingQueue<LogItem> queue;
private final Thread writerThread;
public LogManager(Path path, String splitLogs, boolean useSubdirectories,
boolean lockFiles) {
path.toFile().mkdirs();
if (!path.toFile().exists()) {
LOGGER.warning("Log: Failed to create path: "+path);
}
this.queue = new LinkedBlockingQueue<>(QUEUE_CAPACITY);
this.writerThread = new Thread(new LogWriter(queue, path, splitLogs, useSubdirectories, lockFiles));
}
public void start() {
writerThread.start();
}
/**
* Closes the logging. Sends an item to tell the writer to close all files,
* then waits for the thread to finish, so this could take some time.
*/
public void close() {
try {
boolean added = queue.offer(new LogItem(null, null), MAX_WAIT, TimeUnit.MILLISECONDS);
if (added) {
writerThread.join(MAX_WAIT);
} else {
LOGGER.warning("Log: Could not close Log (Queue full)");
}
} catch (InterruptedException ex) {
LOGGER.warning("Log: Interrupted when waiting for Log to finish..");
Thread.currentThread().interrupt();
}
}
public void writeLine(String channel, String line) {
boolean added = queue.offer(new LogItem(channel, line));
if (!added) {
int current = errors.incrementAndGet();
if (current % 20 == 0) {
LOGGER.warning("Log: Failed writing "+errors+" lines (queue full)");
}
}
}
}