package com.team254.lib.util;
import edu.wpi.first.wpilibj.Timer;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.stream.Collectors;
public class Logger {
public static final double WRITE_TIME = 0.5; // Write every .5 seconds
private static Logger inst = null;
protected File logFile = null;
private BufferedWriter writer;
private ArrayBlockingQueue<String> logMessages = new ArrayBlockingQueue<String>(
300);
Thread consumer;
public static Logger getInstance() {
if (inst == null) {
inst = new Logger();
}
return inst;
}
Runnable consumerTask = new Runnable() {
public void run() {
double lastWriteTime = Timer.getFPGATimestamp();
while (true) {
try {
String msg = logMessages.take();
writer.write(msg);
if (Timer.getFPGATimestamp() >= lastWriteTime + WRITE_TIME) {
writer.flush();
lastWriteTime = Timer.getFPGATimestamp();
}
} catch (InterruptedException | IOException e) {
e.printStackTrace();
}
}
}
};
private Logger() {
File baseDrive = determineMountPoint();
if (baseDrive != null) {
File logDir = new File(baseDrive, "logs");
if (!logDir.exists()) {
logDir.mkdirs();
}
File lastBoot = getLastBootLogFile();
int number = 0;
if (lastBoot != null) {
String name = lastBoot.getName();
String numberStr = name.substring(0, name.lastIndexOf('.'));
number = Integer.parseInt(numberStr);
}
logFile = new File(logDir, String.format("%04d.log", number + 1));
try {
writer = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream(logFile), "utf-8"));
} catch (IOException e) {
e.printStackTrace();
}
consumer = new Thread(consumerTask);
consumer.setName("Logger");
consumer.setPriority(Thread.MIN_PRIORITY);
consumer.start();
}
}
protected static File determineMountPoint() {
char iter = 'z';
for (int i = 0; i < 6; i++) {
File f = new File("/" + iter);
if (f.exists() && f.isDirectory()) {
return f;
}
iter--;
}
return null;
}
public static File getLogDirectory() {
File baseDrive = determineMountPoint();
if (baseDrive == null) {
return null;
}
return new File(baseDrive, "logs");
}
public static File getLastBootLogFile() {
List<String> fileNames = getAllLogFiles().stream()
.map(File::getName).collect(Collectors.toList());
fileNames.sort(null);
if (fileNames.size() <= 0)
return null;
String lastFileName = fileNames.get(fileNames.size() - 1);
return new File(getLogDirectory(), lastFileName);
}
public static Collection<File> getAllLogFiles() {
FilenameFilter logFilter = new FilenameFilter() {
public boolean accept(File dir, String name) {
String lowercaseName = name.toLowerCase();
return lowercaseName.matches("\\d\\d\\d\\d.log");
}
};
File logDir = getLogDirectory();
File[] files = logDir.listFiles(logFilter);
if (files == null) {
return new ArrayList<File>();
} else {
return Arrays.asList(files);
}
}
protected File getCurrentLogFile() {
return logFile;
}
public static File getLogFile() {
return getInstance().getCurrentLogFile();
}
private boolean printLocal(String s) {
return logMessages.offer(s);
}
public static boolean print(String s) {
return getInstance().printLocal(s);
}
private boolean printlnLocal(String s) {
return logMessages.offer(s + '\n');
}
public static boolean println(String s) {
return getInstance().printlnLocal(s);
}
}