001/*
002 * jPOS Project [http://jpos.org]
003 * Copyright (C) 2000-2026 jPOS Software SRL
004 *
005 * This program is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU Affero General Public License as
007 * published by the Free Software Foundation, either version 3 of the
008 * License, or (at your option) any later version.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
013 * GNU Affero General Public License for more details.
014 *
015 * You should have received a copy of the GNU Affero General Public License
016 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
017 */
018
019package org.jpos.util;
020
021import java.io.PrintStream;
022
023/**
024 * Periodically dumps Thread and memory usage
025 * @author apr@cs.com.uy
026 * @version $Id$
027 * @see Logger
028 */
029public class SystemMonitor implements Runnable, LogSource, Loggeable
030{
031    private Logger logger = null;
032    private String realm  = null;
033    private int sleepTime = 0;
034    private int delay     = 0;
035    private Thread thread = null;
036    private volatile boolean shutdown = false;
037
038    /**
039     * noargs constructor
040     */
041    public SystemMonitor () {
042        super();
043    }
044    /**
045     * @param sleepTime sleep
046     * @param logger current logger
047     * @param realm  instance realm
048     */
049    public SystemMonitor (int sleepTime, Logger logger, String realm) {
050        setLogger (logger, realm);
051        this.sleepTime = sleepTime;
052        startThread();
053    }
054    
055    private void startThread() {
056        if (thread != null)
057            thread.interrupt();
058        else if (sleepTime > 0) {
059            thread = new Thread(this,"SystemMonitor");
060            thread.setPriority (Thread.MIN_PRIORITY);
061            thread.start();
062        }
063    }
064
065    /**
066     * @param sleepTime new sleepTime;
067     */
068    public void setSleepTime (int sleepTime) {
069        this.sleepTime = sleepTime;
070        startThread();
071    }
072
073    void dumpThreads (ThreadGroup g, PrintStream p, String indent) {
074        Thread[] list = new Thread[g.activeCount()+5];
075        int nthreads = g.enumerate(list);
076        for (int i=0; i<nthreads; i++) 
077            p.println (indent + list[i]);
078    }
079
080    public void showThreadGroup (ThreadGroup g, PrintStream p, String indent) {
081        if (g.getParent() != null)
082            showThreadGroup (g.getParent(), p, indent + "  ");
083        else
084            dumpThreads (g, p, indent + "    ");
085    }
086
087    public void run() {
088        while (!shutdown) {
089            Logger.log (new LogEvent (this, "SystemMonitor", this));
090            try {
091                long expected = System.currentTimeMillis() + sleepTime;
092                Thread.sleep (sleepTime);
093                delay = (int) (System.currentTimeMillis() - expected);
094            } catch (InterruptedException e) { }
095        }
096    }
097
098    public void shutdown() {
099        shutdown = true;
100    }
101
102    public void dump (PrintStream p, String indent) {
103        String newIndent = indent + "  ";
104        Runtime r = Runtime.getRuntime();
105        p.println (indent + "--- memory ---");
106        p.println (newIndent+" freeMemory="+r.freeMemory());
107        p.println (newIndent+"totalMemory="+r.totalMemory());
108        p.println (newIndent+"inUseMemory="+(r.totalMemory()-r.freeMemory()));
109        p.println ("");
110        p.println (indent + "--- threads ---");
111        p.println (newIndent+"      delay="+delay+" ms");
112        p.println (newIndent+"    threads="+Thread.activeCount());
113        showThreadGroup (Thread.currentThread().getThreadGroup(), p, newIndent);
114        p.println ("");
115        NameRegistrar.getInstance().dump (p, indent);
116    }
117    public void setLogger (Logger logger, String realm) {
118        this.logger = logger;
119        this.realm  = realm;
120    }
121    public String getRealm () {
122        return realm;
123    }
124    public Logger getLogger() {
125        return logger;
126    }
127}
128
129