Rogue: Savage Rats, a retro-themed dungeon crawler
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
rogue-savage-rats/src/mightypork/utils/logging/LogInstance.java

406 lines
7.3 KiB

package mightypork.utils.logging;
import java.io.File;
import java.io.FileFilter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.logging.FileHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import mightypork.utils.files.FileUtils;
/**
* Static logger class.
*
* @author MightyPork
* @copy (c) 2014
*/
public class LogInstance {
/** log file */
private File file;
/** Log name */
private String name;
/** Number of old logs to keep */
private int logs_to_keep;
/** Logs dir */
private File dir;
/** Logger instance. */
private Logger logger;
/** Logging enabled */
private boolean enabled = true;
private boolean sysout = true;
private int monitorId = 0;
private HashMap<Integer, LogMonitor> monitors = new HashMap<Integer, LogMonitor>();
private LogToSysoutMonitor sysoutMonitor;
public LogInstance(String name, File dir, int oldLogCount) {
this.name = name;
this.file = new File(dir, name + getSuffix());
this.dir = dir;
this.logs_to_keep = oldLogCount;
init();
}
/**
* Prepare logs for logging
*/
private void init()
{
logger = Logger.getLogger(name);
cleanup();
FileHandler handler = null;
try {
handler = new FileHandler(file.getPath());
} catch (Exception e) {
throw new RuntimeException("Failed to init log", e);
}
handler.setFormatter(new LogFormatter());
logger.addHandler(handler);
enabled = true;
sysoutMonitor = new LogToSysoutMonitor();
addMonitor(sysoutMonitor);
logger.setUseParentHandlers(false);
logger.setLevel(Level.ALL);
logger.info("Main logger initialized.");
logger.info((new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new Date()));
}
private void cleanup()
{
if (logs_to_keep == 0) return; // overwrite
for (File f : FileUtils.listDirectory(file.getParentFile())) {
if (!f.isFile()) continue;
if (f.equals(file)) {
Date d = new Date(f.lastModified());
String fbase = name + '_' + (new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss")).format(d);
String suff = getSuffix();
String cntStr = "";
File f2;
for (int cnt = 0; (f2 = new File(dir, fbase + cntStr + suff)).exists(); cntStr = "_" + (++cnt));
f.renameTo(f2);
}
}
if (logs_to_keep == -1) return; // keep all
List<File> oldLogs = FileUtils.listDirectory(dir, new FileFilter() {
@Override
public boolean accept(File f)
{
if (f.isDirectory()) return false;
if (!f.getName().endsWith(getSuffix())) return false;
if (!f.getName().startsWith(name)) return false;
return true;
}
});
Collections.sort(oldLogs, new Comparator<File>() {
@Override
public int compare(File o1, File o2)
{
return o1.getName().compareTo(o2.getName());
}
});
for (int i = 0; i < oldLogs.size() - logs_to_keep; i++) {
oldLogs.get(i).delete();
}
}
/**
* Add log monitor
*
* @param mon
* monitor
* @return assigned ID
*/
public synchronized int addMonitor(LogMonitor mon)
{
int id = monitorId;
monitorId++;
monitors.put(id, mon);
return id;
}
/**
* Remove a monitor by ID
*
* @param id
* monitor ID
*/
public synchronized void removeMonitor(int id)
{
monitors.remove(id);
}
/**
* Enable logging.
*
* @param flag
* do enable logging
*/
public void enable(boolean flag)
{
enabled = flag;
}
/**
* Enable printing logs to sysout
*
* @param flag
* do enable logging
*/
public void enableSysout(boolean flag)
{
sysout = flag;
sysoutMonitor.enable(sysout);
}
/**
* Log FINE message
*
* @param msg
* message
*/
public void f1(String msg)
{
if (enabled) logger.log(Level.FINE, msg);
}
/**
* Log FINER message
*
* @param msg
* message
*/
public void f2(String msg)
{
if (enabled) logger.log(Level.FINER, msg);
}
/**
* Log FINEST message
*
* @param msg
* message
*/
public void f3(String msg)
{
if (enabled) logger.log(Level.FINEST, msg);
}
/**
* Log INFO message
*
* @param msg
* message
*/
public void i(String msg)
{
if (enabled) logger.log(Level.INFO, msg);
}
/**
* Log WARNING message (less severe than ERROR)
*
* @param msg
* message
*/
public void w(String msg)
{
if (enabled) logger.log(Level.WARNING, msg);
}
/**
* Log ERROR message
*
* @param msg
* message
*/
public void e(String msg)
{
if (enabled) logger.log(Level.SEVERE, msg);
}
/**
* Log THROWING message
*
* @param msg
* message
* @param thrown
* thrown exception
*/
public void e(String msg, Throwable thrown)
{
if (enabled) logger.log(Level.SEVERE, msg + "\n" + getStackTrace(thrown));
}
/**
* Log exception thrown
*
* @param thrown
* thrown exception
*/
public void e(Throwable thrown)
{
if (enabled) logger.log(Level.SEVERE, getStackTrace(thrown));
}
/**
* Get stack trace from throwable
*
* @param t
* @return trace
*/
private String getStackTrace(Throwable t)
{
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
t.printStackTrace(pw);
pw.flush();
sw.flush();
return sw.toString();
}
/**
* PowerCraft Log file formatter.
*
* @author MightyPork
* @copy (c) 2012
*/
private class LogFormatter extends Formatter {
/** Newline string constant */
private final String nl = System.getProperty("line.separator");
@Override
public String format(LogRecord record)
{
StringBuffer buf = new StringBuffer(180);
if (record.getMessage().equals("\n")) {
return nl;
}
if (record.getMessage().charAt(0) == '\n') {
buf.append(nl);
record.setMessage(record.getMessage().substring(1));
}
Level level = record.getLevel();
String trail = "[ ? ]";
if (level == Level.FINE) {
trail = "[ # ] ";
}
if (level == Level.FINER) {
trail = "[ - ] ";
}
if (level == Level.FINEST) {
trail = "[ ] ";
}
if (level == Level.INFO) {
trail = "[ i ] ";
}
if (level == Level.SEVERE) {
trail = "[!E!] ";
}
if (level == Level.WARNING) {
trail = "[!W!] ";
}
record.setMessage(record.getMessage().replaceAll("\n", nl + trail));
buf.append(trail);
buf.append(formatMessage(record));
buf.append(nl);
Throwable throwable = record.getThrown();
if (throwable != null) {
buf.append("at ");
buf.append(record.getSourceClassName());
buf.append('.');
buf.append(record.getSourceMethodName());
buf.append(nl);
StringWriter sink = new StringWriter();
throwable.printStackTrace(new PrintWriter(sink, true));
buf.append(sink.toString());
buf.append(nl);
}
String str = buf.toString();
for (LogMonitor mon : monitors.values()) {
mon.log(level, str);
}
return str;
}
}
/**
* @return log filename suffix (incl. dot)
*/
protected String getSuffix()
{
return ".log";
}
}