Remade logging system, cleaned up BaseApp.
This commit is contained in:
@@ -2,14 +2,16 @@ package mightypork.gamecore.control;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.Thread.UncaughtExceptionHandler;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
|
|
||||||
import mightypork.gamecore.audio.SoundSystem;
|
import mightypork.gamecore.audio.SoundSystem;
|
||||||
import mightypork.gamecore.control.bus.EventBus;
|
import mightypork.gamecore.control.bus.EventBus;
|
||||||
import mightypork.gamecore.control.bus.events.*;
|
import mightypork.gamecore.control.bus.events.*;
|
||||||
|
import mightypork.gamecore.control.interf.DefaultImpl;
|
||||||
import mightypork.gamecore.control.interf.Destroyable;
|
import mightypork.gamecore.control.interf.Destroyable;
|
||||||
import mightypork.gamecore.control.interf.NoImpl;
|
|
||||||
import mightypork.gamecore.control.timing.Updateable;
|
import mightypork.gamecore.control.timing.Updateable;
|
||||||
import mightypork.gamecore.gui.screens.ScreenRegistry;
|
import mightypork.gamecore.gui.screens.ScreenRegistry;
|
||||||
import mightypork.gamecore.input.InputSystem;
|
import mightypork.gamecore.input.InputSystem;
|
||||||
@@ -17,7 +19,7 @@ import mightypork.gamecore.loading.AsyncResourceLoader;
|
|||||||
import mightypork.gamecore.render.DisplaySystem;
|
import mightypork.gamecore.render.DisplaySystem;
|
||||||
import mightypork.utils.files.InstanceLock;
|
import mightypork.utils.files.InstanceLock;
|
||||||
import mightypork.utils.logging.Log;
|
import mightypork.utils.logging.Log;
|
||||||
import mightypork.utils.logging.LogInstance;
|
import mightypork.utils.logging.LogWriter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,7 +28,7 @@ import mightypork.utils.logging.LogInstance;
|
|||||||
*
|
*
|
||||||
* @author MightyPork
|
* @author MightyPork
|
||||||
*/
|
*/
|
||||||
public abstract class BaseApp implements AppAccess {
|
public abstract class BaseApp implements AppAccess, UncaughtExceptionHandler {
|
||||||
|
|
||||||
// modules
|
// modules
|
||||||
private InputSystem inputSystem;
|
private InputSystem inputSystem;
|
||||||
@@ -40,8 +42,9 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
/**
|
/**
|
||||||
* Start the application
|
* Start the application
|
||||||
*/
|
*/
|
||||||
public void start()
|
public final void start()
|
||||||
{
|
{
|
||||||
|
Thread.setDefaultUncaughtExceptionHandler(this);
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
@@ -57,7 +60,6 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
*/
|
*/
|
||||||
protected void initialize()
|
protected void initialize()
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Lock working directory
|
* Lock working directory
|
||||||
*/
|
*/
|
||||||
@@ -69,8 +71,11 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
/*
|
/*
|
||||||
* Setup logging
|
* Setup logging
|
||||||
*/
|
*/
|
||||||
final LogInstance log = createLog();
|
final LogWriter log = createLog();
|
||||||
|
if (log != null) {
|
||||||
|
Log.setMainLogger(log);
|
||||||
org.newdawn.slick.util.Log.setLogSystem(new SlickLogRedirector(log));
|
org.newdawn.slick.util.Log.setLogSystem(new SlickLogRedirector(log));
|
||||||
|
}
|
||||||
|
|
||||||
// only here it makes sense to log.
|
// only here it makes sense to log.
|
||||||
Log.i("=== Commencing initialization sequence ===");
|
Log.i("=== Commencing initialization sequence ===");
|
||||||
@@ -82,6 +87,7 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
eventBus = new EventBus();
|
eventBus = new EventBus();
|
||||||
|
|
||||||
Log.f3("Registering channels...");
|
Log.f3("Registering channels...");
|
||||||
|
initDefaultBusChannels(eventBus);
|
||||||
initBus(eventBus);
|
initBus(eventBus);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -139,16 +145,16 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
* Called at the beginning of the initialization sequence, right after lock
|
* Called at the beginning of the initialization sequence, right after lock
|
||||||
* was obtained.
|
* was obtained.
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void preInit()
|
protected void preInit()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Called at the end of init sequence, before main loop starts.
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void postInit()
|
protected void postInit()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -159,7 +165,13 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
*
|
*
|
||||||
* @return new log instance
|
* @return new log instance
|
||||||
*/
|
*/
|
||||||
protected abstract LogInstance createLog();
|
@DefaultImpl
|
||||||
|
protected LogWriter createLog()
|
||||||
|
{
|
||||||
|
final LogWriter log = Log.create("runtime", new File("runtime.log"));
|
||||||
|
log.setLevel(Level.ALL);
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -167,7 +179,12 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
*
|
*
|
||||||
* @param display
|
* @param display
|
||||||
*/
|
*/
|
||||||
protected abstract void initDisplay(DisplaySystem display);
|
@DefaultImpl
|
||||||
|
protected void initDisplay(DisplaySystem display)
|
||||||
|
{
|
||||||
|
display.createMainWindow(800, 600, true, false, "BaseApp using LWJGL display.");
|
||||||
|
display.setTargetFps(60);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -175,7 +192,10 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
*
|
*
|
||||||
* @param audio
|
* @param audio
|
||||||
*/
|
*/
|
||||||
protected abstract void initSoundSystem(SoundSystem audio);
|
@DefaultImpl
|
||||||
|
protected void initSoundSystem(SoundSystem audio)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,14 +203,20 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
*
|
*
|
||||||
* @param input
|
* @param input
|
||||||
*/
|
*/
|
||||||
protected abstract void initInputSystem(InputSystem input);
|
@DefaultImpl
|
||||||
|
protected void initInputSystem(InputSystem input)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize resource banks; {@link AsyncResourceLoader} is already
|
* Initialize resource banks; {@link AsyncResourceLoader} is already
|
||||||
* started.
|
* started.
|
||||||
*/
|
*/
|
||||||
protected abstract void initResources();
|
@DefaultImpl
|
||||||
|
protected void initResources()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -198,7 +224,10 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
*
|
*
|
||||||
* @param screens
|
* @param screens
|
||||||
*/
|
*/
|
||||||
protected abstract void initScreens(ScreenRegistry screens);
|
@DefaultImpl
|
||||||
|
protected void initScreens(ScreenRegistry screens)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -215,7 +244,13 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
*
|
*
|
||||||
* @param bus
|
* @param bus
|
||||||
*/
|
*/
|
||||||
|
@DefaultImpl
|
||||||
protected void initBus(EventBus bus)
|
protected void initBus(EventBus bus)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void initDefaultBusChannels(EventBus bus)
|
||||||
{
|
{
|
||||||
// framework events
|
// framework events
|
||||||
bus.addChannel(DestroyEvent.class, Destroyable.class);
|
bus.addChannel(DestroyEvent.class, Destroyable.class);
|
||||||
@@ -259,7 +294,7 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
*/
|
*/
|
||||||
protected void onLockError()
|
protected void onLockError()
|
||||||
{
|
{
|
||||||
System.err.println("Could not obtain lock file.\nOnly one instance can run at a time.");
|
Log.e("Could not obtain lock file.\nOnly one instance can run at a time.");
|
||||||
|
|
||||||
//@formatter:off
|
//@formatter:off
|
||||||
JOptionPane.showMessageDialog(
|
JOptionPane.showMessageDialog(
|
||||||
@@ -279,7 +314,11 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
*
|
*
|
||||||
* @return lock file, or null to disable lock.
|
* @return lock file, or null to disable lock.
|
||||||
*/
|
*/
|
||||||
protected abstract File getLockFile();
|
@DefaultImpl
|
||||||
|
protected File getLockFile()
|
||||||
|
{
|
||||||
|
return new File(".lock");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -310,15 +349,42 @@ public abstract class BaseApp implements AppAccess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@DefaultImpl
|
||||||
public void shutdown()
|
protected void beforeShutdown()
|
||||||
{
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void uncaughtException(Thread t, Throwable e)
|
||||||
|
{
|
||||||
|
onCrash(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@DefaultImpl
|
||||||
|
protected void onCrash(Throwable e)
|
||||||
|
{
|
||||||
|
Log.e("The game has crashed.", e);
|
||||||
|
shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void shutdown()
|
||||||
|
{
|
||||||
|
beforeShutdown();
|
||||||
|
|
||||||
Log.i("Shutting down subsystems...");
|
Log.i("Shutting down subsystems...");
|
||||||
|
|
||||||
|
try {
|
||||||
if (getEventBus() != null) {
|
if (getEventBus() != null) {
|
||||||
getEventBus().send(new DestroyEvent());
|
getEventBus().send(new DestroyEvent());
|
||||||
getEventBus().destroy();
|
getEventBus().destroy();
|
||||||
}
|
}
|
||||||
|
} catch (final Exception e) {
|
||||||
|
// ignore it
|
||||||
|
}
|
||||||
|
|
||||||
Log.i("Terminating...");
|
Log.i("Terminating...");
|
||||||
System.exit(0);
|
System.exit(0);
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||||||
|
|
||||||
import mightypork.gamecore.control.bus.events.MainLoopTaskRequest;
|
import mightypork.gamecore.control.bus.events.MainLoopTaskRequest;
|
||||||
import mightypork.gamecore.control.bus.events.UpdateEvent;
|
import mightypork.gamecore.control.bus.events.UpdateEvent;
|
||||||
import mightypork.gamecore.control.interf.NoImpl;
|
import mightypork.gamecore.control.interf.DefaultImpl;
|
||||||
import mightypork.gamecore.control.timing.TimerDelta;
|
import mightypork.gamecore.control.timing.TimerDelta;
|
||||||
import mightypork.gamecore.gui.components.Renderable;
|
import mightypork.gamecore.gui.components.Renderable;
|
||||||
import mightypork.gamecore.gui.screens.ScreenRegistry;
|
import mightypork.gamecore.gui.screens.ScreenRegistry;
|
||||||
@@ -78,7 +78,7 @@ public abstract class GameLoop extends AppModule implements MainLoopTaskRequest.
|
|||||||
/**
|
/**
|
||||||
* Called before render
|
* Called before render
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void beforeRender()
|
protected void beforeRender()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -88,7 +88,7 @@ public abstract class GameLoop extends AppModule implements MainLoopTaskRequest.
|
|||||||
/**
|
/**
|
||||||
* Called after render
|
* Called after render
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void afterRender()
|
protected void afterRender()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
package mightypork.gamecore.control;
|
package mightypork.gamecore.control;
|
||||||
|
|
||||||
|
|
||||||
import mightypork.utils.logging.LogInstance;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import mightypork.utils.logging.LogWriter;
|
||||||
|
|
||||||
import org.newdawn.slick.util.LogSystem;
|
import org.newdawn.slick.util.LogSystem;
|
||||||
|
|
||||||
@@ -13,13 +15,13 @@ import org.newdawn.slick.util.LogSystem;
|
|||||||
*/
|
*/
|
||||||
public class SlickLogRedirector implements LogSystem {
|
public class SlickLogRedirector implements LogSystem {
|
||||||
|
|
||||||
LogInstance l;
|
LogWriter l;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param log log to redirect into
|
* @param log log to redirect into
|
||||||
*/
|
*/
|
||||||
public SlickLogRedirector(LogInstance log) {
|
public SlickLogRedirector(LogWriter log) {
|
||||||
this.l = log;
|
this.l = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,49 +29,49 @@ public class SlickLogRedirector implements LogSystem {
|
|||||||
@Override
|
@Override
|
||||||
public void error(String msg, Throwable e)
|
public void error(String msg, Throwable e)
|
||||||
{
|
{
|
||||||
l.e(msg, e);
|
l.log(Level.SEVERE, msg, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void error(Throwable e)
|
public void error(Throwable e)
|
||||||
{
|
{
|
||||||
l.e(e);
|
l.log(Level.SEVERE, null, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void error(String msg)
|
public void error(String msg)
|
||||||
{
|
{
|
||||||
l.e(msg);
|
l.log(Level.SEVERE, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void warn(String msg)
|
public void warn(String msg)
|
||||||
{
|
{
|
||||||
l.w(msg);
|
l.log(Level.WARNING, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void warn(String msg, Throwable e)
|
public void warn(String msg, Throwable e)
|
||||||
{
|
{
|
||||||
l.e(msg, e);
|
l.log(Level.WARNING, msg, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void info(String msg)
|
public void info(String msg)
|
||||||
{
|
{
|
||||||
l.i(msg);
|
l.log(Level.INFO, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void debug(String msg)
|
public void debug(String msg)
|
||||||
{
|
{
|
||||||
l.f3(msg);
|
l.log(Level.FINEST, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -9,14 +9,14 @@ import java.lang.annotation.Target;
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicates that the marked method is not implemented and can be safely
|
* Marked method can be safely overriden; it's left blank (or with default
|
||||||
* overriden.
|
* implementation) as a convenience.
|
||||||
*
|
*
|
||||||
* @author MightyPork
|
* @author MightyPork
|
||||||
*/
|
*/
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@Target(value = { ElementType.METHOD })
|
@Target(value = { ElementType.METHOD })
|
||||||
public @interface NoImpl {
|
public @interface DefaultImpl {
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ package mightypork.gamecore.gui.screens;
|
|||||||
import mightypork.gamecore.control.AppAccess;
|
import mightypork.gamecore.control.AppAccess;
|
||||||
import mightypork.gamecore.control.AppSubModule;
|
import mightypork.gamecore.control.AppSubModule;
|
||||||
import mightypork.gamecore.control.bus.events.ScreenChangeEvent;
|
import mightypork.gamecore.control.bus.events.ScreenChangeEvent;
|
||||||
import mightypork.gamecore.control.interf.NoImpl;
|
import mightypork.gamecore.control.interf.DefaultImpl;
|
||||||
import mightypork.gamecore.gui.components.Renderable;
|
import mightypork.gamecore.gui.components.Renderable;
|
||||||
import mightypork.gamecore.gui.constraints.RectConstraint;
|
import mightypork.gamecore.gui.constraints.RectConstraint;
|
||||||
import mightypork.gamecore.input.KeyBinder;
|
import mightypork.gamecore.input.KeyBinder;
|
||||||
@@ -130,7 +130,7 @@ public abstract class Screen extends AppSubModule implements Renderable, KeyBind
|
|||||||
/**
|
/**
|
||||||
* Called when the screen becomes active
|
* Called when the screen becomes active
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void onScreenEnter()
|
protected void onScreenEnter()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -140,7 +140,7 @@ public abstract class Screen extends AppSubModule implements Renderable, KeyBind
|
|||||||
/**
|
/**
|
||||||
* Called when the screen is no longer active
|
* Called when the screen is no longer active
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void onScreenLeave()
|
protected void onScreenLeave()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -152,7 +152,7 @@ public abstract class Screen extends AppSubModule implements Renderable, KeyBind
|
|||||||
*
|
*
|
||||||
* @param size screen size
|
* @param size screen size
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void onSizeChanged(Coord size)
|
protected void onSizeChanged(Coord size)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ package mightypork.gamecore.gui.screens;
|
|||||||
|
|
||||||
|
|
||||||
import mightypork.gamecore.control.AppSubModule;
|
import mightypork.gamecore.control.AppSubModule;
|
||||||
import mightypork.gamecore.control.interf.NoImpl;
|
import mightypork.gamecore.control.interf.DefaultImpl;
|
||||||
import mightypork.gamecore.gui.components.Renderable;
|
import mightypork.gamecore.gui.components.Renderable;
|
||||||
import mightypork.gamecore.gui.constraints.RectConstraint;
|
import mightypork.gamecore.gui.constraints.RectConstraint;
|
||||||
import mightypork.gamecore.input.KeyBinder;
|
import mightypork.gamecore.input.KeyBinder;
|
||||||
@@ -75,7 +75,7 @@ public abstract class ScreenLayer extends AppSubModule implements Comparable<Scr
|
|||||||
/**
|
/**
|
||||||
* Called when the screen becomes active
|
* Called when the screen becomes active
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void onScreenEnter()
|
protected void onScreenEnter()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -85,7 +85,7 @@ public abstract class ScreenLayer extends AppSubModule implements Comparable<Scr
|
|||||||
/**
|
/**
|
||||||
* Called when the screen is no longer active
|
* Called when the screen is no longer active
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void onScreenLeave()
|
protected void onScreenLeave()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
@@ -97,7 +97,7 @@ public abstract class ScreenLayer extends AppSubModule implements Comparable<Scr
|
|||||||
*
|
*
|
||||||
* @param size screen size
|
* @param size screen size
|
||||||
*/
|
*/
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void onSizeChanged(Coord size)
|
protected void onSizeChanged(Coord size)
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import java.util.HashMap;
|
|||||||
import mightypork.gamecore.control.AppAccess;
|
import mightypork.gamecore.control.AppAccess;
|
||||||
import mightypork.gamecore.control.AppModule;
|
import mightypork.gamecore.control.AppModule;
|
||||||
import mightypork.gamecore.control.bus.events.ScreenRequestEvent;
|
import mightypork.gamecore.control.bus.events.ScreenRequestEvent;
|
||||||
import mightypork.gamecore.control.interf.NoImpl;
|
import mightypork.gamecore.control.interf.DefaultImpl;
|
||||||
import mightypork.gamecore.gui.components.Renderable;
|
import mightypork.gamecore.gui.components.Renderable;
|
||||||
import mightypork.utils.logging.Log;
|
import mightypork.utils.logging.Log;
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ public class ScreenRegistry extends AppModule implements ScreenRequestEvent.List
|
|||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NoImpl
|
@DefaultImpl
|
||||||
protected void deinit()
|
protected void deinit()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -2,10 +2,7 @@ package mightypork.rogue;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.logging.Level;
|
|
||||||
|
|
||||||
import mightypork.gamecore.audio.SoundSystem;
|
|
||||||
import mightypork.gamecore.control.BaseApp;
|
import mightypork.gamecore.control.BaseApp;
|
||||||
import mightypork.gamecore.control.GameLoop;
|
import mightypork.gamecore.control.GameLoop;
|
||||||
import mightypork.gamecore.control.bus.EventBus;
|
import mightypork.gamecore.control.bus.EventBus;
|
||||||
@@ -20,8 +17,6 @@ import mightypork.rogue.screens.test_bouncyboxes.ScreenTestBouncy;
|
|||||||
import mightypork.rogue.screens.test_cat_sound.ScreenTestCat;
|
import mightypork.rogue.screens.test_cat_sound.ScreenTestCat;
|
||||||
import mightypork.rogue.screens.test_font.ScreenTestFont;
|
import mightypork.rogue.screens.test_font.ScreenTestFont;
|
||||||
import mightypork.rogue.screens.test_render.ScreenTestRender;
|
import mightypork.rogue.screens.test_render.ScreenTestRender;
|
||||||
import mightypork.utils.logging.Log;
|
|
||||||
import mightypork.utils.logging.LogInstance;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -31,31 +26,6 @@ import mightypork.utils.logging.LogInstance;
|
|||||||
*/
|
*/
|
||||||
public class App extends BaseApp {
|
public class App extends BaseApp {
|
||||||
|
|
||||||
/** instance pointer */
|
|
||||||
private static BaseApp inst;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param args
|
|
||||||
*/
|
|
||||||
public static void main(String[] args)
|
|
||||||
{
|
|
||||||
Config.init();
|
|
||||||
Config.save();
|
|
||||||
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler(new CrashHandler());
|
|
||||||
|
|
||||||
inst = new App();
|
|
||||||
|
|
||||||
try {
|
|
||||||
inst.start();
|
|
||||||
} catch (final Throwable t) {
|
|
||||||
onCrash(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initScreens(ScreenRegistry screens)
|
protected void initScreens(ScreenRegistry screens)
|
||||||
{
|
{
|
||||||
@@ -71,9 +41,6 @@ public class App extends BaseApp {
|
|||||||
@Override
|
@Override
|
||||||
protected void initBus(EventBus bus)
|
protected void initBus(EventBus bus)
|
||||||
{
|
{
|
||||||
super.initBus(bus);
|
|
||||||
|
|
||||||
// custom channels
|
|
||||||
bus.addChannel(ActionRequest.class, ActionRequest.Listener.class);
|
bus.addChannel(ActionRequest.class, ActionRequest.Listener.class);
|
||||||
|
|
||||||
//bus.detailedLogging = true;
|
//bus.detailedLogging = true;
|
||||||
@@ -115,26 +82,17 @@ public class App extends BaseApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
// @Override
|
||||||
protected void preInit()
|
// protected LogWriter createLog()
|
||||||
{
|
// {
|
||||||
// to get dot instead of comma in floats
|
// Locale.setDefault(Locale.ENGLISH);
|
||||||
Locale.setDefault(Locale.ENGLISH);
|
//
|
||||||
}
|
// final LogWriter log = Log.create("runtime", Paths.LOG_FILE, 10);
|
||||||
|
// log.setLevel(Level.WARNING);
|
||||||
|
// log.enable(Config.LOGGING_ENABLED);
|
||||||
@Override
|
//
|
||||||
protected LogInstance createLog()
|
// return log;
|
||||||
{
|
// }
|
||||||
final LogInstance log = Log.create("runtime", Paths.LOGS, 10);
|
|
||||||
log.setFileLevel(Level.WARNING);
|
|
||||||
log.setSysoutLevel(Level.ALL);
|
|
||||||
log.enable(Config.LOGGING_ENABLED);
|
|
||||||
log.enableSysout(Config.LOG_TO_STDOUT);
|
|
||||||
|
|
||||||
return log;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void initDisplay(DisplaySystem display)
|
protected void initDisplay(DisplaySystem display)
|
||||||
@@ -144,13 +102,6 @@ public class App extends BaseApp {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initSoundSystem(SoundSystem audio)
|
|
||||||
{
|
|
||||||
audio.setMasterVolume(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected GameLoop createLoop()
|
protected GameLoop createLoop()
|
||||||
{
|
{
|
||||||
@@ -171,22 +122,4 @@ public class App extends BaseApp {
|
|||||||
return Paths.LOCK;
|
return Paths.LOCK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle a crash
|
|
||||||
*
|
|
||||||
* @param error
|
|
||||||
*/
|
|
||||||
public static void onCrash(Throwable error)
|
|
||||||
{
|
|
||||||
if (Log.ready()) {
|
|
||||||
Log.e("The game has crashed!", error);
|
|
||||||
} else {
|
|
||||||
System.err.println("The game has crashed!");
|
|
||||||
error.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (inst != null) inst.shutdown();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +0,0 @@
|
|||||||
package mightypork.rogue;
|
|
||||||
|
|
||||||
|
|
||||||
import java.lang.Thread.UncaughtExceptionHandler;
|
|
||||||
|
|
||||||
|
|
||||||
public class CrashHandler implements UncaughtExceptionHandler {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void uncaughtException(Thread t, Throwable e)
|
|
||||||
{
|
|
||||||
e.printStackTrace();
|
|
||||||
App.onCrash(e);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package mightypork.rogue;
|
||||||
|
|
||||||
|
|
||||||
|
public class Main {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args)
|
||||||
|
{
|
||||||
|
Config.init();
|
||||||
|
Config.save();
|
||||||
|
|
||||||
|
(new App()).start();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,9 +11,13 @@ public class Paths {
|
|||||||
private static final String APPDIR_NAME = "rogue";
|
private static final String APPDIR_NAME = "rogue";
|
||||||
|
|
||||||
public static final File WORKDIR = OsUtils.getWorkDir(APPDIR_NAME);
|
public static final File WORKDIR = OsUtils.getWorkDir(APPDIR_NAME);
|
||||||
public static final File LOGS = OsUtils.getWorkDir(APPDIR_NAME, "logs");
|
|
||||||
public static final File SCREENSHOTS = OsUtils.getWorkDir(APPDIR_NAME, "screenshots");
|
public static final File LOG_FILE = new File(WORKDIR, "runtime.log");
|
||||||
|
|
||||||
|
public static final File SCREENSHOTS = new File(WORKDIR, "screenshots");
|
||||||
|
|
||||||
public static final File CONFIG = new File(WORKDIR, "config.ini");
|
public static final File CONFIG = new File(WORKDIR, "config.ini");
|
||||||
|
|
||||||
public static final File LOCK = new File(WORKDIR, ".lock");
|
public static final File LOCK = new File(WORKDIR, ".lock");
|
||||||
|
|
||||||
public static final String DIR_EFFECTS = "res/sounds/effects/";
|
public static final String DIR_EFFECTS = "res/sounds/effects/";
|
||||||
|
|||||||
@@ -71,8 +71,6 @@ public class LayerFlyingCat extends ScreenLayer implements Updateable, MouseButt
|
|||||||
size.update(delta);
|
size.update(delta);
|
||||||
xPos.update(delta);
|
xPos.update(delta);
|
||||||
yPos.update(delta);
|
yPos.update(delta);
|
||||||
|
|
||||||
System.out.println(cat.getRect());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
package mightypork.utils.logging;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import mightypork.utils.files.FileUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logger that cleans directory & archives old logs
|
||||||
|
*
|
||||||
|
* @author MightyPork
|
||||||
|
* @copy (c) 2014
|
||||||
|
*/
|
||||||
|
public class ArchivingLog extends SimpleLog {
|
||||||
|
|
||||||
|
/** Number of old logs to keep */
|
||||||
|
private final int logs_to_keep;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log
|
||||||
|
*
|
||||||
|
* @param name log name
|
||||||
|
* @param file log file (in log directory)
|
||||||
|
* @param oldLogCount number of old log files to keep: -1 all, 0 none.
|
||||||
|
*/
|
||||||
|
public ArchivingLog(String name, File file, int oldLogCount) {
|
||||||
|
super(name, file);
|
||||||
|
this.logs_to_keep = oldLogCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log, not keeping 5 last log files (default);
|
||||||
|
*
|
||||||
|
* @param name log name
|
||||||
|
* @param file log file (in log directory)
|
||||||
|
*/
|
||||||
|
public ArchivingLog(String name, File file) {
|
||||||
|
super(name, file);
|
||||||
|
this.logs_to_keep = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
cleanLoggingDirectory();
|
||||||
|
|
||||||
|
super.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void cleanLoggingDirectory()
|
||||||
|
{
|
||||||
|
if (logs_to_keep == 0) return; // overwrite
|
||||||
|
|
||||||
|
final File log_file = getFile();
|
||||||
|
final File log_dir = log_file.getParentFile();
|
||||||
|
final String fname = FileUtils.getBasename(log_file.toString());
|
||||||
|
|
||||||
|
// move old file
|
||||||
|
for (final File f : FileUtils.listDirectory(log_dir)) {
|
||||||
|
if (!f.isFile()) continue;
|
||||||
|
if (f.equals(getFile())) {
|
||||||
|
|
||||||
|
final Date d = new Date(f.lastModified());
|
||||||
|
final String fbase = fname + '_' + (new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss")).format(d);
|
||||||
|
final String suff = "." + getSuffix();
|
||||||
|
String cntStr = "";
|
||||||
|
File f2;
|
||||||
|
|
||||||
|
for (int cnt = 0; (f2 = new File(log_dir, fbase + cntStr + suff)).exists(); cntStr = "_" + (++cnt)) {}
|
||||||
|
|
||||||
|
f.renameTo(f2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (logs_to_keep == -1) return; // keep all
|
||||||
|
|
||||||
|
final List<File> oldLogs = FileUtils.listDirectory(log_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(fname)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
Collections.sort(oldLogs, new Comparator<File>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compare(File o1, File o2)
|
||||||
|
{
|
||||||
|
return o1.getName().compareTo(o2.getName());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// playing with fireee
|
||||||
|
for (int i = 0; i < oldLogs.size() - logs_to_keep; i++) {
|
||||||
|
oldLogs.get(i).delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return log filename suffix
|
||||||
|
*/
|
||||||
|
private String getSuffix()
|
||||||
|
{
|
||||||
|
return FileUtils.getExtension(getFile());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package mightypork.utils.logging;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
|
||||||
|
public abstract class BaseLogMonitor implements LogMonitor {
|
||||||
|
|
||||||
|
private boolean enabled = true;
|
||||||
|
private Level accepted = Level.ALL;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMessageLogged(Level level, String message)
|
||||||
|
{
|
||||||
|
if (!enabled) return;
|
||||||
|
if (accepted.intValue() > level.intValue()) return;
|
||||||
|
|
||||||
|
logMessage(level, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected abstract void logMessage(Level level, String message);
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLevel(Level level)
|
||||||
|
{
|
||||||
|
this.accepted = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable(boolean flag)
|
||||||
|
{
|
||||||
|
this.enabled = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,195 +2,306 @@ package mightypork.utils.logging;
|
|||||||
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
import mightypork.utils.string.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A log.
|
||||||
|
*
|
||||||
|
* @author MightyPork
|
||||||
|
*/
|
||||||
public class Log {
|
public class Log {
|
||||||
|
|
||||||
/** enable static logging */
|
private static LogWriter main = null;
|
||||||
private static boolean staticLogging = true;
|
private static boolean enabled = true;
|
||||||
|
private static final LogToSysoutMonitor sysoMonitor = new LogToSysoutMonitor();
|
||||||
|
private static final long start_ms = System.currentTimeMillis();
|
||||||
|
|
||||||
|
private static HashMap<String, SimpleLog> logs = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log FINE message in main logger
|
* Create a logger. If another with the name already exists, it'll be
|
||||||
|
* retrieved instead of creating a new one.
|
||||||
|
*
|
||||||
|
* @param logName log name (used for filename, should be application-unique)
|
||||||
|
* @param logFile log file; old logs will be kept here too.
|
||||||
|
* @param oldLogsCount number of old logs to keep, -1 infinite, 0 none.
|
||||||
|
* @return the created Log instance
|
||||||
|
*/
|
||||||
|
public static synchronized LogWriter create(String logName, File logFile, int oldLogsCount)
|
||||||
|
{
|
||||||
|
if (logs.containsKey(logName)) return logs.get(logName);
|
||||||
|
|
||||||
|
final ArchivingLog log = new ArchivingLog(logName, logFile, oldLogsCount);
|
||||||
|
log.init();
|
||||||
|
|
||||||
|
logs.put(logName, log);
|
||||||
|
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a logger. If another with the name already exists, it'll be
|
||||||
|
* retrieved instead of creating a new one.
|
||||||
|
*
|
||||||
|
* @param logName log name (used for filename, must be application-unique)
|
||||||
|
* @param logFile log file; old logs will be kept here too.
|
||||||
|
* @return the created Log instance
|
||||||
|
*/
|
||||||
|
public static synchronized LogWriter create(String logName, File logFile)
|
||||||
|
{
|
||||||
|
if (logs.containsKey(logName)) return logs.get(logName);
|
||||||
|
|
||||||
|
final SimpleLog log = new SimpleLog(logName, logFile);
|
||||||
|
log.init();
|
||||||
|
|
||||||
|
logs.put(logName, log);
|
||||||
|
|
||||||
|
return log;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setMainLogger(LogWriter log)
|
||||||
|
{
|
||||||
|
main = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void addMonitor(LogMonitor mon)
|
||||||
|
{
|
||||||
|
assertInited();
|
||||||
|
|
||||||
|
main.addMonitor(mon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void removeMonitor(LogMonitor mon)
|
||||||
|
{
|
||||||
|
assertInited();
|
||||||
|
|
||||||
|
main.removeMonitor(mon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void assertInited()
|
||||||
|
{
|
||||||
|
if (main == null) throw new IllegalStateException("Main logger not initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message
|
||||||
|
*
|
||||||
|
* @param level message level
|
||||||
|
* @param msg message text
|
||||||
|
*/
|
||||||
|
public static void log(Level level, String msg)
|
||||||
|
{
|
||||||
|
if (enabled) {
|
||||||
|
final long ms = System.currentTimeMillis() - start_ms;
|
||||||
|
sysoMonitor.onMessageLogged(level, formatMessage(level, msg, null, ms));
|
||||||
|
|
||||||
|
if (main != null) {
|
||||||
|
main.log(level, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message
|
||||||
|
*
|
||||||
|
* @param level message level
|
||||||
|
* @param msg message text
|
||||||
|
* @param t thrown exception
|
||||||
|
*/
|
||||||
|
public static void log(Level level, String msg, Throwable t)
|
||||||
|
{
|
||||||
|
if (enabled) {
|
||||||
|
final long ms = System.currentTimeMillis() - start_ms;
|
||||||
|
sysoMonitor.onMessageLogged(level, formatMessage(level, msg, t, ms));
|
||||||
|
|
||||||
|
if (main != null) {
|
||||||
|
main.log(level, msg, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log FINE message
|
||||||
*
|
*
|
||||||
* @param msg message
|
* @param msg message
|
||||||
*/
|
*/
|
||||||
public static void f1(String msg)
|
public static void f1(String msg)
|
||||||
{
|
{
|
||||||
if (staticLogging && ready()) main.f1(msg);
|
log(Level.FINE, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log FINER message in main logger
|
* Log FINER message
|
||||||
*
|
*
|
||||||
* @param msg message
|
* @param msg message
|
||||||
*/
|
*/
|
||||||
public static void f2(String msg)
|
public static void f2(String msg)
|
||||||
{
|
{
|
||||||
if (staticLogging && ready()) main.f2(msg);
|
log(Level.FINER, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log FINEST message in main logger
|
* Log FINEST message
|
||||||
*
|
*
|
||||||
* @param msg message
|
* @param msg message
|
||||||
*/
|
*/
|
||||||
public static void f3(String msg)
|
public static void f3(String msg)
|
||||||
{
|
{
|
||||||
if (staticLogging && ready()) main.f3(msg);
|
log(Level.FINEST, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log INFO message in main logger
|
* Log INFO message
|
||||||
*
|
*
|
||||||
* @param msg message
|
* @param msg message
|
||||||
*/
|
*/
|
||||||
public static void i(String msg)
|
public static void i(String msg)
|
||||||
{
|
{
|
||||||
if (staticLogging && ready()) main.i(msg);
|
log(Level.INFO, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log WARNING message in main logger
|
* Log WARNING message (less severe than ERROR)
|
||||||
*
|
*
|
||||||
* @param msg message
|
* @param msg message
|
||||||
*/
|
*/
|
||||||
public static void w(String msg)
|
public static void w(String msg)
|
||||||
{
|
{
|
||||||
if (staticLogging && ready()) {
|
log(Level.WARNING, msg);
|
||||||
main.w(msg);
|
|
||||||
} else {
|
|
||||||
System.err.println(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log ERROR message in main logger
|
* Log ERROR message
|
||||||
*
|
*
|
||||||
* @param msg message
|
* @param msg message
|
||||||
*/
|
*/
|
||||||
public static void e(String msg)
|
public static void e(String msg)
|
||||||
{
|
{
|
||||||
if (staticLogging && ready()) {
|
log(Level.SEVERE, msg);
|
||||||
main.e(msg);
|
|
||||||
} else {
|
|
||||||
System.err.println(msg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log EXCEPTION and ERROR message in main logger
|
* Log THROWING message
|
||||||
*
|
*
|
||||||
* @param msg message
|
* @param msg message
|
||||||
* @param thrown thrown exception
|
* @param thrown thrown exception
|
||||||
*/
|
*/
|
||||||
public static void e(String msg, Throwable thrown)
|
public static void e(String msg, Throwable thrown)
|
||||||
{
|
{
|
||||||
if (staticLogging && ready()) {
|
log(Level.SEVERE, msg, thrown);
|
||||||
main.e(msg, thrown);
|
|
||||||
} else {
|
|
||||||
System.err.println(msg);
|
|
||||||
thrown.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log EXCEPTION in main logger
|
* Log exception thrown
|
||||||
*
|
*
|
||||||
* @param thrown thrown exception
|
* @param thrown thrown exception
|
||||||
*/
|
*/
|
||||||
public static void e(Throwable thrown)
|
public static void e(Throwable thrown)
|
||||||
{
|
{
|
||||||
if (staticLogging && ready()) {
|
log(Level.SEVERE, null, thrown);
|
||||||
main.e(thrown);
|
|
||||||
} else {
|
|
||||||
thrown.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void enable(boolean flag)
|
public static void enable(boolean flag)
|
||||||
{
|
{
|
||||||
if (staticLogging && ready()) main.enable(flag);
|
enabled = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setSysoutLevel(Level level)
|
||||||
|
{
|
||||||
|
sysoMonitor.setLevel(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void setLevel(Level level)
|
||||||
|
{
|
||||||
|
assertInited();
|
||||||
|
|
||||||
|
main.setLevel(level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enable / disable static log delegate methods
|
* Get stack trace from throwable
|
||||||
*
|
*
|
||||||
* @param flag enable
|
* @param t
|
||||||
|
* @return trace
|
||||||
*/
|
*/
|
||||||
public static void enableStaticLogging(boolean flag)
|
public static String getStackTrace(Throwable t)
|
||||||
{
|
{
|
||||||
staticLogging = flag;
|
final StringWriter sw = new StringWriter();
|
||||||
}
|
final PrintWriter pw = new PrintWriter(sw, true);
|
||||||
|
t.printStackTrace(pw);
|
||||||
private static HashMap<String, LogInstance> logs = new HashMap<>();
|
pw.flush();
|
||||||
private static LogInstance main = null;
|
sw.flush();
|
||||||
|
return sw.toString();
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a logger. If this is the first logger made, then it'll be made
|
|
||||||
* available via the static methods.
|
|
||||||
*
|
|
||||||
* @param logName log name (used for filename, must be application-unique)
|
|
||||||
* @param logsDir directory to store logs in
|
|
||||||
* @param oldLogsCount number of old logs to keep, -1 for infinite, 0 for
|
|
||||||
* none.
|
|
||||||
* @return the created Log instance
|
|
||||||
*/
|
|
||||||
public static synchronized LogInstance create(String logName, File logsDir, int oldLogsCount)
|
|
||||||
{
|
|
||||||
if (logs.containsKey(logName)) return logs.get(logName);
|
|
||||||
final LogInstance log = new LogInstance(logName, logsDir, oldLogsCount);
|
|
||||||
if (main == null) main = log;
|
|
||||||
logs.put(logName, log);
|
|
||||||
|
|
||||||
return log;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
static String formatMessage(Level level, String message, Throwable throwable, long start_ms)
|
||||||
* Create a logger. If this is the first logger made, then it'll be made
|
|
||||||
* available via the static methods.<br>
|
|
||||||
* Old logs will be kept.
|
|
||||||
*
|
|
||||||
* @param logName log name (used for filename, must be application-unique)
|
|
||||||
* @param logsDir directory to store logs in
|
|
||||||
* @return the created Log instance
|
|
||||||
*/
|
|
||||||
public static synchronized LogInstance create(String logName, File logsDir)
|
|
||||||
{
|
{
|
||||||
if (logs.containsKey(logName)) return logs.get(logName);
|
|
||||||
final LogInstance log = new LogInstance(logName, logsDir, -1);
|
|
||||||
if (main == null) main = log;
|
|
||||||
logs.put(logName, log);
|
|
||||||
|
|
||||||
return log;
|
final String nl = System.getProperty("line.separator");
|
||||||
|
|
||||||
|
if (message.equals("\n")) {
|
||||||
|
return nl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.charAt(0) == '\n') {
|
||||||
public int addMonitor(LogMonitor mon)
|
message = nl + message.substring(1);
|
||||||
{
|
|
||||||
if (!ready()) throw new IllegalStateException("Main logger not initialized.");
|
|
||||||
|
|
||||||
return main.addMonitor(mon);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final long time_ms = (System.currentTimeMillis() - start_ms);
|
||||||
|
final double time_s = time_ms / 1000D;
|
||||||
|
final String time = String.format("%6.2f ", time_s);
|
||||||
|
final String time_blank = StringUtils.repeat(" ", time.length());
|
||||||
|
|
||||||
public void removeMonitor(int id)
|
String prefix = "[ ? ]";
|
||||||
{
|
|
||||||
if (!ready()) throw new IllegalStateException("Main logger not initialized.");
|
|
||||||
|
|
||||||
main.removeMonitor(id);
|
if (level == Level.FINE) {
|
||||||
|
prefix = "[ # ] ";
|
||||||
|
} else if (level == Level.FINER) {
|
||||||
|
prefix = "[ - ] ";
|
||||||
|
} else if (level == Level.FINEST) {
|
||||||
|
prefix = "[ ] ";
|
||||||
|
} else if (level == Level.INFO) {
|
||||||
|
prefix = "[ i ] ";
|
||||||
|
} else if (level == Level.SEVERE) {
|
||||||
|
prefix = "[!E!] ";
|
||||||
|
} else if (level == Level.WARNING) {
|
||||||
|
prefix = "[!W!] ";
|
||||||
|
}
|
||||||
|
|
||||||
|
message = time + prefix + message.replaceAll("\n", nl + time_blank + prefix) + nl;
|
||||||
|
|
||||||
|
if (throwable != null) {
|
||||||
|
message += getStackTrace(throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -237,10 +348,4 @@ public class Log {
|
|||||||
|
|
||||||
return (enclosing == null ? "" : str(enclosing) + sep) + name;
|
return (enclosing == null ? "" : str(enclosing) + sep) + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static boolean ready()
|
|
||||||
{
|
|
||||||
return main != null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,424 +0,0 @@
|
|||||||
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;
|
|
||||||
import mightypork.utils.string.StringUtils;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Static logger class.
|
|
||||||
*
|
|
||||||
* @author MightyPork
|
|
||||||
* @copy (c) 2014
|
|
||||||
*/
|
|
||||||
public class LogInstance {
|
|
||||||
|
|
||||||
/** log file */
|
|
||||||
private final File file;
|
|
||||||
|
|
||||||
/** Log name */
|
|
||||||
private final String name;
|
|
||||||
|
|
||||||
/** Number of old logs to keep */
|
|
||||||
private final int logs_to_keep;
|
|
||||||
|
|
||||||
/** Logs dir */
|
|
||||||
private final File log_dir;
|
|
||||||
|
|
||||||
/** Logger instance. */
|
|
||||||
private Logger logger;
|
|
||||||
|
|
||||||
/** Logging enabled */
|
|
||||||
private boolean enabled = true;
|
|
||||||
|
|
||||||
private boolean sysout = true;
|
|
||||||
|
|
||||||
private int monitorId = 0;
|
|
||||||
private final HashMap<Integer, LogMonitor> monitors = new HashMap<>();
|
|
||||||
|
|
||||||
private LogToSysoutMonitor sysoutMonitor;
|
|
||||||
|
|
||||||
private final long started_ms;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log
|
|
||||||
*
|
|
||||||
* @param name log name
|
|
||||||
* @param dir log directory
|
|
||||||
* @param oldLogCount number of old log files to keep: -1 all, 0 none.
|
|
||||||
*/
|
|
||||||
public LogInstance(String name, File dir, int oldLogCount) {
|
|
||||||
this.name = name;
|
|
||||||
this.file = new File(dir, name + getSuffix());
|
|
||||||
this.log_dir = dir;
|
|
||||||
this.logs_to_keep = oldLogCount;
|
|
||||||
this.started_ms = System.currentTimeMillis();
|
|
||||||
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prepare logs for logging
|
|
||||||
*/
|
|
||||||
private void init()
|
|
||||||
{
|
|
||||||
logger = Logger.getLogger(name);
|
|
||||||
|
|
||||||
cleanLoggingDirectory();
|
|
||||||
|
|
||||||
FileHandler handler = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
handler = new FileHandler(file.getPath());
|
|
||||||
} catch (final 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);
|
|
||||||
final String stamp = (new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new Date());
|
|
||||||
i("Logger \"" + name + "\" initialized.\n" + stamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void cleanLoggingDirectory()
|
|
||||||
{
|
|
||||||
if (logs_to_keep == 0) return; // overwrite
|
|
||||||
|
|
||||||
// move old file
|
|
||||||
for (final File f : FileUtils.listDirectory(file.getParentFile())) {
|
|
||||||
if (!f.isFile()) continue;
|
|
||||||
if (f.equals(file)) {
|
|
||||||
|
|
||||||
final Date d = new Date(f.lastModified());
|
|
||||||
final String fbase = name + '_' + (new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss")).format(d);
|
|
||||||
final String suff = getSuffix();
|
|
||||||
String cntStr = "";
|
|
||||||
File f2;
|
|
||||||
|
|
||||||
for (int cnt = 0; (f2 = new File(log_dir, fbase + cntStr + suff)).exists(); cntStr = "_" + (++cnt)) {}
|
|
||||||
|
|
||||||
f.renameTo(f2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (logs_to_keep == -1) return; // keep all
|
|
||||||
|
|
||||||
final List<File> oldLogs = FileUtils.listDirectory(log_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)
|
|
||||||
{
|
|
||||||
final 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setSysoutLevel(Level level)
|
|
||||||
{
|
|
||||||
sysoutMonitor.setLevel(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setFileLevel(Level level)
|
|
||||||
{
|
|
||||||
logger.setLevel(level);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void log(Level level, String msg)
|
|
||||||
{
|
|
||||||
if (enabled) {
|
|
||||||
logger.log(level, msg);
|
|
||||||
|
|
||||||
final String fmt = formatMessage(level, msg, null);
|
|
||||||
|
|
||||||
for (final LogMonitor mon : monitors.values()) {
|
|
||||||
mon.onMessageLogged(level, fmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void log(Level level, String msg, Throwable t)
|
|
||||||
{
|
|
||||||
if (enabled) {
|
|
||||||
logger.log(level, msg, t);
|
|
||||||
|
|
||||||
final String fmt = formatMessage(level, msg, t);
|
|
||||||
|
|
||||||
for (final LogMonitor mon : monitors.values()) {
|
|
||||||
mon.onMessageLogged(level, fmt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log FINE message
|
|
||||||
*
|
|
||||||
* @param msg message
|
|
||||||
*/
|
|
||||||
public void f1(String msg)
|
|
||||||
{
|
|
||||||
log(Level.FINE, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log FINER message
|
|
||||||
*
|
|
||||||
* @param msg message
|
|
||||||
*/
|
|
||||||
public void f2(String msg)
|
|
||||||
{
|
|
||||||
log(Level.FINER, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log FINEST message
|
|
||||||
*
|
|
||||||
* @param msg message
|
|
||||||
*/
|
|
||||||
public void f3(String msg)
|
|
||||||
{
|
|
||||||
log(Level.FINEST, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log INFO message
|
|
||||||
*
|
|
||||||
* @param msg message
|
|
||||||
*/
|
|
||||||
public void i(String msg)
|
|
||||||
{
|
|
||||||
log(Level.INFO, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log WARNING message (less severe than ERROR)
|
|
||||||
*
|
|
||||||
* @param msg message
|
|
||||||
*/
|
|
||||||
public void w(String msg)
|
|
||||||
{
|
|
||||||
log(Level.WARNING, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log ERROR message
|
|
||||||
*
|
|
||||||
* @param msg message
|
|
||||||
*/
|
|
||||||
public void e(String msg)
|
|
||||||
{
|
|
||||||
log(Level.SEVERE, msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log THROWING message
|
|
||||||
*
|
|
||||||
* @param msg message
|
|
||||||
* @param thrown thrown exception
|
|
||||||
*/
|
|
||||||
public void e(String msg, Throwable thrown)
|
|
||||||
{
|
|
||||||
log(Level.SEVERE, msg, thrown);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log exception thrown
|
|
||||||
*
|
|
||||||
* @param thrown thrown exception
|
|
||||||
*/
|
|
||||||
public void e(Throwable thrown)
|
|
||||||
{
|
|
||||||
log(Level.SEVERE, null, thrown);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PowerCraft Log file formatter.
|
|
||||||
*
|
|
||||||
* @author MightyPork
|
|
||||||
* @copy (c) 2012
|
|
||||||
*/
|
|
||||||
private class LogFormatter extends Formatter {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String format(LogRecord record)
|
|
||||||
{
|
|
||||||
return LogInstance.this.formatMessage(record.getLevel(), record.getMessage(), record.getThrown());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return log filename suffix (incl. dot)
|
|
||||||
*/
|
|
||||||
protected String getSuffix()
|
|
||||||
{
|
|
||||||
return ".log";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private String formatMessage(Level level, String message, Throwable throwable)
|
|
||||||
{
|
|
||||||
|
|
||||||
final String nl = System.getProperty("line.separator");
|
|
||||||
|
|
||||||
if (message.equals("\n")) {
|
|
||||||
return nl;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message.charAt(0) == '\n') {
|
|
||||||
message = nl + message.substring(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
final long time_ms = (System.currentTimeMillis() - started_ms);
|
|
||||||
final double time_s = time_ms / 1000D;
|
|
||||||
final String time = String.format("%6.2f ", time_s);
|
|
||||||
final String time_blank = StringUtils.repeat(" ", time.length());
|
|
||||||
|
|
||||||
String prefix = "[ ? ]";
|
|
||||||
|
|
||||||
if (level == Level.FINE) {
|
|
||||||
prefix = "[ # ] ";
|
|
||||||
} else if (level == Level.FINER) {
|
|
||||||
prefix = "[ - ] ";
|
|
||||||
} else if (level == Level.FINEST) {
|
|
||||||
prefix = "[ ] ";
|
|
||||||
} else if (level == Level.INFO) {
|
|
||||||
prefix = "[ i ] ";
|
|
||||||
} else if (level == Level.SEVERE) {
|
|
||||||
prefix = "[!E!] ";
|
|
||||||
} else if (level == Level.WARNING) {
|
|
||||||
prefix = "[!W!] ";
|
|
||||||
}
|
|
||||||
|
|
||||||
message = time + prefix + message.replaceAll("\n", nl + time_blank + prefix) + nl;
|
|
||||||
|
|
||||||
if (throwable != null) {
|
|
||||||
message += getStackTrace(throwable);
|
|
||||||
}
|
|
||||||
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get stack trace from throwable
|
|
||||||
*
|
|
||||||
* @param t
|
|
||||||
* @return trace
|
|
||||||
*/
|
|
||||||
private static String getStackTrace(Throwable t)
|
|
||||||
{
|
|
||||||
final StringWriter sw = new StringWriter();
|
|
||||||
final PrintWriter pw = new PrintWriter(sw, true);
|
|
||||||
t.printStackTrace(pw);
|
|
||||||
pw.flush();
|
|
||||||
sw.flush();
|
|
||||||
return sw.toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -4,18 +4,14 @@ package mightypork.utils.logging;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Log monitor, receives all logged messages
|
|
||||||
*
|
|
||||||
* @author MightyPork
|
|
||||||
*/
|
|
||||||
public interface LogMonitor {
|
public interface LogMonitor {
|
||||||
|
|
||||||
/**
|
|
||||||
* Message logged;
|
|
||||||
*
|
|
||||||
* @param level message level
|
|
||||||
* @param message message text, already formatted.
|
|
||||||
*/
|
|
||||||
void onMessageLogged(Level level, String message);
|
void onMessageLogged(Level level, String message);
|
||||||
|
|
||||||
|
|
||||||
|
void setLevel(Level level);
|
||||||
|
|
||||||
|
|
||||||
|
void enable(boolean flag);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,24 +4,11 @@ package mightypork.utils.logging;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
|
||||||
public class LogToSysoutMonitor implements LogMonitor {
|
public class LogToSysoutMonitor extends BaseLogMonitor {
|
||||||
|
|
||||||
private boolean enabled = true;
|
|
||||||
private Level accepted = Level.ALL;
|
|
||||||
|
|
||||||
|
|
||||||
public void setLevel(Level level)
|
|
||||||
{
|
|
||||||
this.accepted = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessageLogged(Level level, String message)
|
protected void logMessage(Level level, String message)
|
||||||
{
|
{
|
||||||
if (!enabled) return;
|
|
||||||
if (accepted.intValue() > level.intValue()) return;
|
|
||||||
|
|
||||||
if (level == Level.SEVERE || level == Level.WARNING) {
|
if (level == Level.SEVERE || level == Level.WARNING) {
|
||||||
System.err.print(message);
|
System.err.print(message);
|
||||||
} else {
|
} else {
|
||||||
@@ -29,10 +16,4 @@ public class LogToSysoutMonitor implements LogMonitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void enable(boolean enable)
|
|
||||||
{
|
|
||||||
this.enabled = enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
package mightypork.utils.logging;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log interface
|
||||||
|
*
|
||||||
|
* @author MightyPork
|
||||||
|
*/
|
||||||
|
public interface LogWriter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepare logs for logging
|
||||||
|
*/
|
||||||
|
void init();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add log monitor
|
||||||
|
*
|
||||||
|
* @param mon monitor
|
||||||
|
*/
|
||||||
|
void addMonitor(LogMonitor mon);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a monitor
|
||||||
|
*
|
||||||
|
* @param removed monitor to remove
|
||||||
|
*/
|
||||||
|
void removeMonitor(LogMonitor removed);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set logging level
|
||||||
|
*
|
||||||
|
* @param level
|
||||||
|
*/
|
||||||
|
void setLevel(Level level);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable logging.
|
||||||
|
*
|
||||||
|
* @param flag do enable logging
|
||||||
|
*/
|
||||||
|
void enable(boolean flag);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message
|
||||||
|
*
|
||||||
|
* @param level message level
|
||||||
|
* @param msg message text
|
||||||
|
*/
|
||||||
|
void log(Level level, String msg);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log a message
|
||||||
|
*
|
||||||
|
* @param level message level
|
||||||
|
* @param msg message text
|
||||||
|
* @param t thrown exception
|
||||||
|
*/
|
||||||
|
void log(Level level, String msg, Throwable t);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,251 @@
|
|||||||
|
package mightypork.utils.logging;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.HashSet;
|
||||||
|
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;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Basic logger
|
||||||
|
*
|
||||||
|
* @author MightyPork
|
||||||
|
*/
|
||||||
|
public class SimpleLog implements LogWriter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log file formatter.
|
||||||
|
*/
|
||||||
|
class LogFormatter extends Formatter {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String format(LogRecord record)
|
||||||
|
{
|
||||||
|
return Log.formatMessage(record.getLevel(), record.getMessage(), record.getThrown(), started_ms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Log file */
|
||||||
|
private final File file;
|
||||||
|
|
||||||
|
/** Log name */
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
/** Logger instance. */
|
||||||
|
private Logger logger;
|
||||||
|
|
||||||
|
private boolean enabled = true;
|
||||||
|
private final HashSet<LogMonitor> monitors = new HashSet<>();
|
||||||
|
private final long started_ms;
|
||||||
|
|
||||||
|
|
||||||
|
public SimpleLog(String name, File file) {
|
||||||
|
this.name = name;
|
||||||
|
this.file = file;
|
||||||
|
this.started_ms = System.currentTimeMillis();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init()
|
||||||
|
{
|
||||||
|
logger = Logger.getLogger(getName());
|
||||||
|
|
||||||
|
FileHandler handler = null;
|
||||||
|
try {
|
||||||
|
handler = new FileHandler(getFile().getPath());
|
||||||
|
} catch (final Exception e) {
|
||||||
|
throw new RuntimeException("Failed to init log.", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
handler.setFormatter(new LogFormatter());
|
||||||
|
logger.addHandler(handler);
|
||||||
|
logger.setUseParentHandlers(false);
|
||||||
|
logger.setLevel(Level.ALL);
|
||||||
|
|
||||||
|
printHeader();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void printHeader()
|
||||||
|
{
|
||||||
|
final String stamp = (new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new Date());
|
||||||
|
i("Logger \"" + getName() + "\" initialized.\n" + stamp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add log monitor
|
||||||
|
*
|
||||||
|
* @param mon monitor
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void addMonitor(LogMonitor mon)
|
||||||
|
{
|
||||||
|
monitors.add(mon);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a monitor
|
||||||
|
*
|
||||||
|
* @param removed monitor to remove
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public synchronized void removeMonitor(LogMonitor removed)
|
||||||
|
{
|
||||||
|
monitors.remove(removed);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLevel(Level level)
|
||||||
|
{
|
||||||
|
logger.setLevel(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void enable(boolean flag)
|
||||||
|
{
|
||||||
|
enabled = flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public File getFile()
|
||||||
|
{
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getName()
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(Level level, String msg)
|
||||||
|
{
|
||||||
|
if (enabled) {
|
||||||
|
logger.log(level, msg);
|
||||||
|
|
||||||
|
final String fmt = Log.formatMessage(level, msg, null, started_ms);
|
||||||
|
|
||||||
|
for (final LogMonitor mon : monitors) {
|
||||||
|
mon.onMessageLogged(level, fmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void log(Level level, String msg, Throwable t)
|
||||||
|
{
|
||||||
|
if (enabled) {
|
||||||
|
logger.log(level, msg, t);
|
||||||
|
|
||||||
|
final String fmt = Log.formatMessage(level, msg, t, started_ms);
|
||||||
|
|
||||||
|
for (final LogMonitor mon : monitors) {
|
||||||
|
mon.onMessageLogged(level, fmt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log FINE message
|
||||||
|
*
|
||||||
|
* @param msg message
|
||||||
|
*/
|
||||||
|
public void f1(String msg)
|
||||||
|
{
|
||||||
|
log(Level.FINE, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log FINER message
|
||||||
|
*
|
||||||
|
* @param msg message
|
||||||
|
*/
|
||||||
|
public void f2(String msg)
|
||||||
|
{
|
||||||
|
log(Level.FINER, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log FINEST message
|
||||||
|
*
|
||||||
|
* @param msg message
|
||||||
|
*/
|
||||||
|
public void f3(String msg)
|
||||||
|
{
|
||||||
|
log(Level.FINEST, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log INFO message
|
||||||
|
*
|
||||||
|
* @param msg message
|
||||||
|
*/
|
||||||
|
public void i(String msg)
|
||||||
|
{
|
||||||
|
log(Level.INFO, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log WARNING message (less severe than ERROR)
|
||||||
|
*
|
||||||
|
* @param msg message
|
||||||
|
*/
|
||||||
|
public void w(String msg)
|
||||||
|
{
|
||||||
|
log(Level.WARNING, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log ERROR message
|
||||||
|
*
|
||||||
|
* @param msg message
|
||||||
|
*/
|
||||||
|
public void e(String msg)
|
||||||
|
{
|
||||||
|
log(Level.SEVERE, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log THROWING message
|
||||||
|
*
|
||||||
|
* @param msg message
|
||||||
|
* @param thrown thrown exception
|
||||||
|
*/
|
||||||
|
public void e(String msg, Throwable thrown)
|
||||||
|
{
|
||||||
|
log(Level.SEVERE, msg, thrown);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Log exception thrown
|
||||||
|
*
|
||||||
|
* @param thrown thrown exception
|
||||||
|
*/
|
||||||
|
public void e(Throwable thrown)
|
||||||
|
{
|
||||||
|
log(Level.SEVERE, null, thrown);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -54,6 +54,7 @@ public class StringUtils {
|
|||||||
public static String toLastChar(String s, char c)
|
public static String toLastChar(String s, char c)
|
||||||
{
|
{
|
||||||
if (s == null) return null;
|
if (s == null) return null;
|
||||||
|
if (s.lastIndexOf(c) == -1) return s;
|
||||||
return s.substring(0, s.lastIndexOf(c));
|
return s.substring(0, s.lastIndexOf(c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user