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