2024-04-03 22:42:30 +02:00

120 lines
3.1 KiB
Java

package btools.util;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
public class StackSampler extends Thread {
private DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss,SSS", new Locale("en", "US"));
private BufferedWriter bw;
private Random rand = new Random();
private int interval;
private int flushCnt = 0;
private volatile boolean stopped;
public StackSampler(File logfile, int interval) {
this.interval = interval;
try {
bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(logfile, true)));
} catch (Exception e) {
printError("StackSampler: " + e.getMessage());
}
}
protected void printError(String msg) {
System.out.println(msg);
}
@Override
public void run() {
while (!stopped) {
dumpThreads();
}
if (bw != null) {
try {
bw.close();
} catch (Exception e) {
}
}
}
public void dumpThreads() {
try {
int wait1 = rand.nextInt(interval);
int wait2 = interval - wait1;
sleep(wait1);
StringBuilder sb = new StringBuilder(df.format(new Date()) + " THREADDUMP\n");
Map<Thread, StackTraceElement[]> allThreads = getAllStackTraces();
for (Map.Entry<Thread, StackTraceElement[]> e : allThreads.entrySet()) {
Thread t = e.getKey();
if (t == currentThread()) {
continue; // not me
}
StackTraceElement[] stack = e.getValue();
if (!matchesFilter(stack)) {
continue;
}
sb.append(" (ID=").append(t.getId()).append(" \"").append(t.getName()).append("\" ").append(t.getState()).append("\n");
for (StackTraceElement line : stack) {
sb.append(" ").append(line.toString()).append("\n");
}
sb.append("\n");
}
bw.write(sb.toString());
if (flushCnt++ >= 0) {
flushCnt = 0;
bw.flush();
}
sleep(wait2);
} catch (Exception e) {
// ignore
}
}
public void close() {
stopped = true;
interrupt();
}
private boolean matchesFilter(StackTraceElement[] stack) {
boolean positiveMatch = false;
for (StackTraceElement e : stack) {
String s = e.toString();
if (s.indexOf("btools") >= 0) {
positiveMatch = true;
}
if (s.indexOf("Thread.sleep") >= 0 || s.indexOf("PlainSocketImpl.socketAccept") >= 0) {
return false;
}
}
return positiveMatch;
}
public static void main(String[] args) throws Exception {
System.out.println("StackSampler...");
Class<?> clazz = Class.forName(args[0]);
String[] args2 = new String[args.length - 1];
for (int i = 1; i < args.length; i++) {
args2[i - 1] = args[i];
}
StackSampler t = new StackSampler(new File("stacks.log"), 1000);
t.start();
try {
clazz.getMethod("main", String[].class).invoke(null, new Object[]{args2});
} finally {
t.close();
}
}
}