Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose a Profiler API in spark-api #131

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions spark-api/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ plugins {
version = '0.1-SNAPSHOT'

dependencies {
compileOnly 'org.checkerframework:checker-qual:3.8.0'
compileOnly 'org.jetbrains:annotations:20.1.0'
compileOnly 'org.checkerframework:checker-qual:3.16.0'
compileOnly 'org.jetbrains:annotations:22.0.0'
}

publishing {
Expand Down
8 changes: 7 additions & 1 deletion spark-api/src/main/java/me/lucko/spark/api/Spark.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@
package me.lucko.spark.api;

import me.lucko.spark.api.gc.GarbageCollector;
import me.lucko.spark.api.profiler.Profiler;
import me.lucko.spark.api.statistic.StatisticWindow;
import me.lucko.spark.api.statistic.misc.DoubleAverageInfo;
import me.lucko.spark.api.statistic.types.DoubleStatistic;
import me.lucko.spark.api.statistic.types.GenericStatistic;

import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.jetbrains.annotations.Unmodifiable;
Expand Down Expand Up @@ -81,4 +81,10 @@ public interface Spark {
*/
@NonNull @Unmodifiable Map<String, GarbageCollector> gc();

/**
* Get the {@link Profiler} API.
*
* @return the profiler api
*/
@NonNull Profiler profiler();
}
62 changes: 62 additions & 0 deletions spark-api/src/main/java/me/lucko/spark/api/profiler/Dumper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package me.lucko.spark.api.profiler;

import java.util.Objects;
import java.util.Set;

/**
* TODO: implement this class, see {@link ProfilerConfiguration} for the purpose.
*/
public final class Dumper {
private final Method method;
private final Set<String> criteria;

/**
*
*/
public Dumper(Method method, Set<String> criteria) {
this.method = method;
this.criteria = criteria;
}

public static Dumper pattern(Set<String> criteria) {
return new Dumper(Method.PATTERN, criteria);
}

public static Dumper specific(Set<String> criteria) {
return new Dumper(Method.SPECIFIC, criteria);
}

public Method method() {
return method;
}

public Set<String> criteria() {
return criteria;
}

@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (obj == null || obj.getClass() != this.getClass()) return false;
Dumper that = (Dumper) obj;
return Objects.equals(this.method, that.method) &&
Objects.equals(this.criteria, that.criteria);
}

@Override
public int hashCode() {
return Objects.hash(method, criteria);
}

@Override
public String toString() {
return "Dumper[" +
"method=" + method + ", " +
"criteria=" + criteria + ']';
}

public enum Method {
PATTERN,
SPECIFIC
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package me.lucko.spark.api.profiler;

/**
* Group the threads by a specific mode. Either grouping them by name, pool or combined into a single group.
*/
public enum GrouperChoice {
SINGLE,
NAME,
POOL
}
23 changes: 23 additions & 0 deletions spark-api/src/main/java/me/lucko/spark/api/profiler/Profiler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package me.lucko.spark.api.profiler;

import org.jetbrains.annotations.Nullable;

public interface Profiler {

/**
* Start the Spark Profiler using a profiler configuration.
* A configuration can be built using {@link ProfilerConfiguration#builder()}.
*
* @param configuration the configuration object
* @return if the profiler started successfully
*/
boolean start(ProfilerConfiguration configuration);

/**
* Stop the currently running profiler.
*
* @return the profiler report or null if no profiler was running.
*/
@Nullable
ProfilerReport stop();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package me.lucko.spark.api.profiler;

import org.jetbrains.annotations.Nullable;

import java.time.Duration;

public interface ProfilerConfiguration {

static ProfilerConfigurationBuilder builder() {
return new ProfilerConfigurationBuilder();
}

/**
* Get the interval (in millis) of when the profiler should take samples.
*
* @return the sample interval
*/
double interval();

/**
* Get if sleeping threads should be ignored.
*
* @return if sleeping threads are ignored
*/
boolean ignoreSleeping();

/**
* Get if native threads should be ignored.
*
* @return if native threads are ignored
*/
boolean ignoreNative();

/**
* Get if the native Java sampler should be used.
*
* @return if the native Java sampler is used
*/
boolean forceJavaSampler();

/**
* Minimum duration (in millis) a tick has to take in order to be recorded.
* If this value is below 0, all ticks will be recorded.
*
* @return the minimum tick duration
*/
int minimumTickDuration();

/**
* Get how long the profiler should run, if the duration is null, the profiler runs indefinite.
*
* @return duration of the profile or null if indefinite
*/
@Nullable
Duration duration();

/**
* Get the choice of which dumper to use (i.e. ALL, Regex or Specific).
* If no dumper is defined, ALL is used.
*
* @return the thread dumper choice
*/
@Nullable
Dumper dumper();

/**
* Get the choice of which thread grouper (AS_ONE, BY_NAME, BY_POOL) to use for this profiler.
* If the grouper is null, BY_POOL is used.
*
* @return the thread grouper choice
*/
@Nullable
GrouperChoice grouper();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package me.lucko.spark.api.profiler;

import org.jetbrains.annotations.Nullable;

import java.time.Duration;

public class ProfilerConfigurationBuilder {

private double interval = 5;
private boolean ignoreSleeping = false;
private boolean ignoreNative = false;
private boolean forceJavaSampler = true;
private int minimumTickDuration = -1;
private @Nullable Duration duration = null;
private @Nullable Dumper dumper = null;
private @Nullable GrouperChoice grouper = null;

/**
* Set the interval to a given value or 5 if value is below 0.
*
* @param interval the interval
* @return the builder instance
*/
public ProfilerConfigurationBuilder interval(double interval) {
this.interval = interval > 0 ? interval : 5;
return this;
}

public ProfilerConfigurationBuilder ignoreSleeping(boolean ignoreSleeping) {
this.ignoreSleeping = ignoreSleeping;
return this;
}

public ProfilerConfigurationBuilder ignoreNative(boolean ignoreNative) {
this.ignoreNative = ignoreNative;
return this;
}

public ProfilerConfigurationBuilder forceJavaSampler(boolean forceJavaSampler) {
this.forceJavaSampler = forceJavaSampler;
return this;
}

/**
* Set the minimum tick duration that will be profiled.
* If the minimumTickDuration is lower than 0 (default is -1), all ticks will be recorded.
*
* @param minimumTickDuration the minimum tick duration
* @return the builder instance
*/
public ProfilerConfigurationBuilder minimumTickDuration(int minimumTickDuration) {
this.minimumTickDuration = minimumTickDuration;
return this;
}

public ProfilerConfigurationBuilder duration(Duration duration) {
this.duration = duration;
return this;
}

public ProfilerConfigurationBuilder dumper(Dumper dumper) {
this.dumper = dumper;
return this;
}

public ProfilerConfigurationBuilder grouper(GrouperChoice grouper) {
this.grouper = grouper;
return this;
}

public ProfilerConfiguration build() {
return new ProfilerConfiguration() {
@Override
public double interval() {
return interval;
}

@Override
public boolean ignoreSleeping() {
return ignoreSleeping;
}

@Override
public boolean ignoreNative() {
return ignoreNative;
}

@Override
public boolean forceJavaSampler() {
return forceJavaSampler;
}

@Override
public int minimumTickDuration() {
return minimumTickDuration;
}

@Override
public @Nullable Duration duration() {
return duration;
}

@Override
public @Nullable Dumper dumper() {
return dumper;
}

@Override
public @Nullable GrouperChoice grouper() {
return grouper;
}
};
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package me.lucko.spark.api.profiler;

public interface ProfilerReport {

String viewer();
}
1 change: 1 addition & 0 deletions spark-common/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dependencies {
compileOnly 'com.google.code.gson:gson:2.7'
compileOnly 'com.google.guava:guava:19.0'
compileOnly 'org.checkerframework:checker-qual:3.8.0'
compileOnly 'org.jetbrains:annotations:22.0.0'
}

processResources {
Expand Down
Loading