/**
*
*/
package edu.washington.cs.oneswarm.f2f.network;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPOutputStream;
import org.gudy.azureus2.core3.util.SystemProperties;
class RotatingLogger {
private static Logger slogger = Logger.getLogger(RotatingLogger.class.getName());
private LinkedBlockingQueue<String> queuedLines = new LinkedBlockingQueue<String>();
final String mLogName;
public void log(String line) {
if (slogger.isLoggable(Level.FINEST)) {
queuedLines.add(line);
}
}
File logFile;
BufferedWriter logWriter;
private File getLogFileName() {
Calendar d = Calendar.getInstance();
DecimalFormat f = new DecimalFormat("00");
return new File(SystemProperties.getApplicationPath(), mLogName + "_"
+ d.get(Calendar.YEAR) + "-" + f.format(d.get(Calendar.MONTH) + 1) + "-"
+ f.format(d.get(Calendar.DAY_OF_MONTH)) + ".log");
}
private void rotateLogs() throws IOException {
File oldFile = logFile;
synchronized (RotatingLogger.this) {
if (logWriter != null) {
logWriter.close();
}
logFile = getLogFileName();
logWriter = new BufferedWriter(new FileWriter(logFile, true));
slogger.fine("rotating log, new file: " + logFile.getName());
}
/*
* file rotated, lets gzip the old one
*/
if (oldFile != null) {
slogger.fine("gzipping the old file");
BufferedInputStream in = new BufferedInputStream(new FileInputStream(oldFile));
final File zippedFile = new File(oldFile.getCanonicalPath() + ".gz");
BufferedOutputStream out = new BufferedOutputStream(new GZIPOutputStream(
new FileOutputStream(zippedFile)));
byte[] buffer = new byte[1024 * 1024];
int len;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
out.close();
in.close();
slogger.finer("gzipped old log, new size: " + zippedFile.length() + " compression: "
+ ((100 * zippedFile.length()) / oldFile.length()) + " %");
slogger.finer("deleting old file: " + oldFile.delete());
}
}
public RotatingLogger(final String logname) {
mLogName = logname;
Thread startLaterThread = new Thread(new Runnable() {
public void run() {
try {
Thread.sleep(60 * 1000);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (slogger.isLoggable(Level.FINEST)) {
slogger.fine("Starting search timing logger");
try {
rotateLogs();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Thread t = new Thread(new Runnable() {
long lastFlush = 0;
public void run() {
try {
while (true) {
String line = queuedLines.poll(5, TimeUnit.SECONDS);
if (line != null) {
synchronized (RotatingLogger.this) {
logWriter.append(line + "\n");
if (lastFlush + 5000 < System.currentTimeMillis()) {
logWriter.flush();
lastFlush = System.currentTimeMillis();
}
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
t.setName("RotatingLogger - " + logname);
t.setDaemon(true);
t.start();
Timer logRotator = new Timer("RotatingLoggerTimer - " + logname);
Calendar startDate = Calendar.getInstance();
startDate.set(Calendar.DAY_OF_YEAR, startDate.get(Calendar.DAY_OF_YEAR) + 1);
startDate.set(Calendar.HOUR, 0);
startDate.set(Calendar.MINUTE, 1);
startDate.set(Calendar.SECOND, 0);
startDate.set(Calendar.MILLISECOND, 0);
startDate.set(Calendar.AM_PM, Calendar.AM);
slogger.finer("next log rotate will be at: " + startDate.getTime());
logRotator.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
synchronized (RotatingLogger.this) {
try {
rotateLogs();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}, startDate.getTime(), 1000 * 60 * 60 * 24);
}
}
});
startLaterThread.setDaemon(true);
startLaterThread.setName("StartLaterRotatingLogger - " + logname);
startLaterThread.start();
}
public boolean isEnabled() {
return slogger.isLoggable(Level.FINEST);
}
}