001/* [{
002Copyright 2007, 2008, 2009 Nicolas Carranza <nicarran at gmail.com>
003
004This file is part of jpen.
005
006jpen is free software: you can redistribute it and/or modify
007it under the terms of the GNU Lesser General Public License as published by
008the Free Software Foundation, either version 3 of the License,
009or (at your option) any later version.
010
011jpen is distributed in the hope that it will be useful,
012but WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014GNU Lesser General Public License for more details.
015
016You should have received a copy of the GNU Lesser General Public License
017along with jpen.  If not, see <http://www.gnu.org/licenses/>.
018}] */
019package jpen.demo.inspect;
020
021import java.util.Date;
022import java.util.logging.Level;
023import java.util.logging.Logger;
024import java.util.Map;
025import jpen.demo.StatusReport;
026
027public class InspectorThread
028        implements Runnable{
029        static final Logger L=Logger.getLogger(InspectorThread.class.getName());
030        //static { L.setLevel(Level.ALL); }
031
032        final Inspector inspector;
033        final long period;
034        final long times;
035
036        InspectorThread(Inspector inspector, long period, long times){
037                if(period<=0)
038                        throw new IllegalArgumentException("period must be greater than 0");
039                this.inspector=inspector;
040                this.period=period;
041                this.times=times;
042                Thread t=new Thread(this, "JPen-Inspector");
043                t.setPriority(Thread.MAX_PRIORITY);
044                t.start();
045        }
046
047
048        //@Override
049        public synchronized void run(){
050                try{
051                        long totalTime=times*period/1000;
052                        L.warning("JPen Demo will automatically shut down in "+totalTime+" seconds");
053                        logInfo(0);
054                        for(int i=1; i<=times; i++){
055                                wait(period);
056                                logInfo(i);
057                                inspector.fileHandler.flush();
058                        }
059                        inspector.fileHandler.close();
060                        L.info("shutting down...");
061                        System.exit(0);
062                }catch(InterruptedException ex){
063                        L.warning("interrupted!");
064                        ex.printStackTrace();
065                }
066        }
067        
068        private void logInfo(int count){
069                L.info("collecting info "+count+"/"+times);
070                L.fine(new StatusReport(inspector.penManager).toString());
071                L.fine(evalThreadsDump(count));
072                inspector.fileHandler.flush();
073                L.info("info collected");
074        }
075
076        private String evalThreadsDump(int count){
077                StringBuilder sb=new StringBuilder();
078                Map<Thread, StackTraceElement[]> threadToStackTraces=Thread.getAllStackTraces();
079                sb.append("=== ("+count+") Stack Traces "+new Date()+" ===\n");
080                for(Map.Entry<Thread, StackTraceElement[]> threadToStackTracesE: threadToStackTraces.entrySet()){
081                        Thread thread=threadToStackTracesE.getKey();
082                        sb.append(thread+", state="+thread.getState()+", isAlive="+thread.isAlive());
083                        sb.append("\n");
084                        for(StackTraceElement stackTraceElement: threadToStackTracesE.getValue()){
085                                sb.append("\t");
086                                sb.append(stackTraceElement);
087                                sb.append("\n");
088                        }
089                }
090                sb.append("=== === ===");
091                return sb.toString();
092        }
093
094}