/* * Copyright (C) 2010 Shashank Tulsyan * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package neembuu.util.logging; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; /** * * @author Shashank Tulsyan */ public final class LightWeightLogger extends Logger { //final static BufferedWriter bw = new FinalBW(); private static final LinkedBlockingQueue<L> lbq = new LinkedBlockingQueue<L>(); private static final Flusher F = new Flusher(); static AtomicInteger pendingRqs = new AtomicInteger(0); static AtomicLong totalTime = new AtomicLong(0); static AtomicLong totalCnt = new AtomicLong(0); static { if(false)staticinit(); F.start(); } private static void staticinit(){ } private static final class L { private final LogRecord lr; private final LightWeightLogger lwl; public L(LogRecord lr, LightWeightLogger lwl) { this.lr = lr; this.lwl = lwl; } } public void close() { } /*package private*/ LightWeightLogger(String name) { super(name,Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).getResourceBundleName()); } @Override public void log(LogRecord record) { pendingRqs.incrementAndGet(); record.getSourceMethodName(); if(!lbq.offer(new L(record, this))){ throw new IllegalStateException("could not offer"); } } private void superLog(LogRecord record){ super.log(record); } private static final class Flusher extends Thread { public Flusher() { super("LightWeightLogger flusher"); setDaemon(true); } @Override public final void run() { L l = null; long s,e; try{ while(true){ while((l = lbq.poll(1000, TimeUnit.MILLISECONDS))!=null){ s = System.currentTimeMillis(); try{ l.lwl.superLog(l.lr); }catch(LogRecordContainingException lrce){ Logger.getGlobal().log(Level.SEVERE,"Following log message could not be written to destination file"); Logger.getGlobal().log(lrce.lr); }catch(Exception a){ Logger.getGlobal().log(Level.SEVERE,"",a); } e = System.currentTimeMillis(); totalTime.addAndGet(e-s); totalCnt.incrementAndGet(); pendingRqs.decrementAndGet(); } if(exit()){ return; } } }catch(InterruptedException ie){ ie.printStackTrace(System.err); } } private boolean exit(){ if(Thread.currentThread().isDaemon()){ // daemon thread will exit on it's own // no need to check return false; } ThreadGroup tg = Thread.currentThread().getThreadGroup(); while(tg.getParent()!=null){ tg = tg.getParent(); } Thread[]lst = new Thread[tg.activeCount()]; tg.enumerate(lst, true); for (int i = 0; i < lst.length; i++) { if(!lst[i].isDaemon()){ if(lst[i]!=Thread.currentThread()){ if(lst[i].getName().equals("DestroyJavaVM")) continue; return false; } } } return true; } } }