diff options
Diffstat (limited to 'common/src/main/java/me/lucko/spark/profiler')
4 files changed, 68 insertions, 4 deletions
diff --git a/common/src/main/java/me/lucko/spark/profiler/Sampler.java b/common/src/main/java/me/lucko/spark/profiler/Sampler.java index 9696c03..d03b4b6 100644 --- a/common/src/main/java/me/lucko/spark/profiler/Sampler.java +++ b/common/src/main/java/me/lucko/spark/profiler/Sampler.java @@ -61,14 +61,17 @@ public class Sampler extends TimerTask { private final int interval; /** The instance used to generate thread information for use in sampling */ private final ThreadDumper threadDumper; + /** The instance used to group threads together */ + private final ThreadGrouper threadGrouper; /** The time when sampling first began */ private long startTime = -1; /** The unix timestamp (in millis) when this sampler should automatically complete.*/ private final long endTime; // -1 for nothing - public Sampler(int interval, ThreadDumper threadDumper, long endTime) { + public Sampler(int interval, ThreadDumper threadDumper, ThreadGrouper threadGrouper, long endTime) { this.interval = interval; this.threadDumper = threadDumper; + this.threadGrouper = threadGrouper; this.endTime = endTime; } @@ -84,7 +87,8 @@ public class Sampler extends TimerTask { private void insertData(QueuedThreadInfo data) { try { - StackNode node = this.threadData.computeIfAbsent(data.threadName, StackNode::new); + String group = this.threadGrouper.getGroup(data.threadName); + StackNode node = this.threadData.computeIfAbsent(group, StackNode::new); node.log(data.stack, Sampler.this.interval); } catch (Exception e) { e.printStackTrace(); diff --git a/common/src/main/java/me/lucko/spark/profiler/SamplerBuilder.java b/common/src/main/java/me/lucko/spark/profiler/SamplerBuilder.java index 8e79b33..fa2898b 100644 --- a/common/src/main/java/me/lucko/spark/profiler/SamplerBuilder.java +++ b/common/src/main/java/me/lucko/spark/profiler/SamplerBuilder.java @@ -12,7 +12,8 @@ public class SamplerBuilder { private int samplingInterval = 10; private long timeout = -1; - private ThreadDumper threadDumper = new ThreadDumper.All(); + private ThreadDumper threadDumper = ThreadDumper.ALL; + private ThreadGrouper threadGrouper = ThreadGrouper.BY_NAME; public SamplerBuilder() { } @@ -33,8 +34,13 @@ public class SamplerBuilder { return this; } + public SamplerBuilder threadGrouper(ThreadGrouper threadGrouper) { + this.threadGrouper = threadGrouper; + return this; + } + public Sampler start(Timer samplingThread) { - Sampler sampler = new Sampler(this.samplingInterval, this.threadDumper, this.timeout); + Sampler sampler = new Sampler(this.samplingInterval, this.threadDumper, this.threadGrouper, this.timeout); sampler.start(samplingThread); return sampler; } diff --git a/common/src/main/java/me/lucko/spark/profiler/ThreadDumper.java b/common/src/main/java/me/lucko/spark/profiler/ThreadDumper.java index 9c2e974..68d7dc9 100644 --- a/common/src/main/java/me/lucko/spark/profiler/ThreadDumper.java +++ b/common/src/main/java/me/lucko/spark/profiler/ThreadDumper.java @@ -41,6 +41,8 @@ public interface ThreadDumper { /** * Implementation of {@link ThreadDumper} that generates data for all threads. */ + ThreadDumper ALL = new All(); + final class All implements ThreadDumper { @Override public ThreadInfo[] dumpThreads(ThreadMXBean threadBean) { diff --git a/common/src/main/java/me/lucko/spark/profiler/ThreadGrouper.java b/common/src/main/java/me/lucko/spark/profiler/ThreadGrouper.java new file mode 100644 index 0000000..56a6cc4 --- /dev/null +++ b/common/src/main/java/me/lucko/spark/profiler/ThreadGrouper.java @@ -0,0 +1,52 @@ +package me.lucko.spark.profiler; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Function for grouping threads together + */ +@FunctionalInterface +public interface ThreadGrouper { + + /** + * Gets the group for the given thread. + * + * @param threadName the name of the thread + * @return the group + */ + String getGroup(String threadName); + + /** + * Implementation of {@link ThreadGrouper} that just groups by thread name. + */ + ThreadGrouper BY_NAME = new ByName(); + + final class ByName implements ThreadGrouper { + @Override + public String getGroup(String threadName) { + return threadName; + } + } + + /** + * Implementation of {@link ThreadGrouper} that attempts to group by the name of the pool + * the thread originated from. + */ + ThreadGrouper BY_POOL = new ByPool(); + + final class ByPool implements ThreadGrouper { + private static final Pattern THREAD_POOL_PATTERN = Pattern.compile("^(.*)[-#] ?\\d+$"); + + @Override + public String getGroup(String threadName) { + Matcher matcher = THREAD_POOL_PATTERN.matcher(threadName); + if (!matcher.matches()) { + return threadName; + } + + return matcher.group(1).trim() + " (Combined)"; + } + } + +} |