package org.rr.jeborker.app; import static org.rr.commons.utils.StringUtil.EMPTY; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; import java.io.RandomAccessFile; import java.io.StringWriter; import java.text.SimpleDateFormat; import java.util.Date; import java.util.logging.Handler; import java.util.logging.Level; import java.util.logging.LogRecord; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.rr.commons.log.LoggerFactory; import org.rr.jeborker.Jeboorker; import org.rr.jeborker.app.preferences.APreferenceStore; import org.rr.jeborker.gui.MainController; import org.rr.jeborker.gui.MainMonitor; public class JeboorkerLogger extends Handler { private static final File LOG_FILE = new File(APreferenceStore.getConfigDirectory(), Jeboorker.APP + ".log"); private static final String LINE_BREAK = System.getProperty("line.separator"); private OutputStream logfileOutputStream; public JeboorkerLogger() { try { logfileOutputStream = new FileOutputStream(LOG_FILE); } catch (FileNotFoundException e) { e.printStackTrace(System.err); } } @Override public void close() throws SecurityException { flush(); IOUtils.closeQuietly(logfileOutputStream); } @Override public void flush() { try { logfileOutputStream.flush(); } catch (IOException e) { e.printStackTrace(System.err); } } @Override public void publish(LogRecord record) { toConsole(record); toLogFile(record); if(MainController.isInitialized()) { toMonitor(record); } } private static void toConsole(LogRecord record) { System.err.println(record.getMessage()); Throwable thrown = record.getThrown(); if(thrown!=null) { thrown.printStackTrace(System.err); } } /** * Log the given record to the UI progress monitor. The record will be * discarded if the UI is not initialized. This can happen with errors * in the startup phase. * @param record The record to be published to the UI monitor. */ private static void toMonitor(LogRecord record) { if (record.getMessage() != null) { String thrownCause = EMPTY; if(record.getThrown() != null) { thrownCause = record.getThrown().getMessage(); if(thrownCause != null && thrownCause.length() == 0) { thrownCause = null; } } try { MainMonitor progressMonitor = MainController.getController().getProgressMonitor(); if(progressMonitor != null) { progressMonitor.setMessage( record.getMessage() + (thrownCause != null && !thrownCause.isEmpty() ? " (" + thrownCause+ ")" : EMPTY)); } } catch(Exception e) { e.printStackTrace(); } } } private void toLogFile(LogRecord record) { StringBuilder s = new StringBuilder(); if (record.getMessage() != null) { s.append(SimpleDateFormat.getDateTimeInstance().format(new Date()) + " " + record.getLevel() + ": " + record.getMessage()); s.append(LINE_BREAK); } if(record.getThrown() != null) { StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); record.getThrown().printStackTrace(new PrintWriter(stringWriter)); printWriter.flush(); printWriter.close(); s.append(stringWriter.getBuffer().toString()); } try { logfileOutputStream.write(s.toString().getBytes()); } catch (IOException e) { e.printStackTrace(System.err); } } public static String getLogFilePrint() { int bytesToRead = 500000; //500kb if(LOG_FILE.length() <= bytesToRead * 2) { try { return FileUtils.readFileToString(LOG_FILE); } catch (IOException e) { LoggerFactory.log(Level.WARNING, JeboorkerLogger.class, "Failed to read bytes from log file " + LOG_FILE, e); } } else { byte[] intro = new byte[bytesToRead]; byte[] tail = new byte[bytesToRead]; try(RandomAccessFile raf = new RandomAccessFile(LOG_FILE, "r")) { raf.read(intro); raf.seek(LOG_FILE.length() - bytesToRead); raf.read(tail, 0, bytesToRead); return new StringBuilder(new String(intro)).append("\n...\n").append(new String(tail)).toString(); } catch (Exception e) { LoggerFactory.log(Level.WARNING, JeboorkerLogger.class, "Failed to read bytes from log file " + LOG_FILE, e); } } return null; } }