Skip to content
Merged
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
35 changes: 25 additions & 10 deletions common/src/java/org/apache/hive/http/ProfileServlet.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
Expand Down Expand Up @@ -45,19 +48,19 @@
* // -m method fully qualified method name: 'ClassName.methodName'
* // -t profile different threads separately
* // -s simple class names instead of FQN
* // -o fmt[,fmt...] output format: summary|traces|flat|collapsed|svg|tree|jfr
* // -o fmt[,fmt...] output format: summary|traces|flat|collapsed|svg|tree|jfr|html
* // --width px SVG width pixels (integer)
* // --height px SVG frame height pixels (integer)
* // --minwidth px skip frames smaller than px (double)
* // --reverse generate stack-reversed FlameGraph / Call tree
* Example:
* - To collect 30 second CPU profile of current process (returns FlameGraph svg)
* - To collect 10 second CPU profile of current process (returns FlameGraph html)
* curl "http://localhost:10002/prof"
* - To collect 1 minute CPU profile of current process and output in tree format (html)
* curl "http://localhost:10002/prof?output=tree&duration=60"
* - To collect 30 second heap allocation profile of current process (returns FlameGraph svg)
* - To collect 10 second heap allocation profile of current process (returns FlameGraph html)
* curl "http://localhost:10002/prof?event=alloc"
* - To collect lock contention profile of current process (returns FlameGraph svg)
* - To collect lock contention profile of current process (returns FlameGraph html)
* curl "http://localhost:10002/prof?event=lock"
* Following event types are supported (default is 'cpu') (NOTE: not all OS'es support all events)
* // Perf events:
Expand Down Expand Up @@ -89,7 +92,6 @@ public class ProfileServlet extends HttpServlet {
private static final String CONTENT_TYPE_TEXT = "text/plain; charset=utf-8";
private static final String ASYNC_PROFILER_HOME_ENV = "ASYNC_PROFILER_HOME";
private static final String ASYNC_PROFILER_HOME_SYSTEM_PROPERTY = "async.profiler.home";
private static final String PROFILER_SCRIPT = "/profiler.sh";
private static final int DEFAULT_DURATION_SECONDS = 10;
private static final AtomicInteger ID_GEN = new AtomicInteger(0);
static final String OUTPUT_DIR = System.getProperty("java.io.tmpdir") + "/prof-output";
Expand Down Expand Up @@ -141,7 +143,8 @@ enum Output {
COLLAPSED,
SVG,
TREE,
JFR
JFR,
HTML
}

private Lock profilerLock = new ReentrantLock();
Expand Down Expand Up @@ -213,7 +216,7 @@ protected void doGet(final HttpServletRequest req, final HttpServletResponse res
(method == null ? event.name().toLowerCase() : method) + "-" + ID_GEN.incrementAndGet() + "." +
output.name().toLowerCase());
List<String> cmd = new ArrayList<>();
cmd.add(asyncProfilerHome + PROFILER_SCRIPT);
cmd.add(getProfilerScriptPath());
cmd.add("-e");
cmd.add(method == null ? event.getInternalName() : method);
cmd.add("-d");
Expand Down Expand Up @@ -293,6 +296,16 @@ protected void doGet(final HttpServletRequest req, final HttpServletResponse res
}
}

/**
* Get the path of the profiler script to be executed.
* Before async-profiler 3.0, the script was named profiler.sh, and after 3.0 it's bin/asprof
* @return
*/
private String getProfilerScriptPath() {
Path defaultPath = Paths.get(asyncProfilerHome + "/bin/asprof");
return Files.exists(defaultPath)? defaultPath.toString() : asyncProfilerHome + "/profiler.sh";
}

private Integer getInteger(final HttpServletRequest req, final String param, final Integer defaultValue) {
final String value = req.getParameter(param);
if (value != null) {
Expand Down Expand Up @@ -340,14 +353,16 @@ private Event getEvent(final HttpServletRequest req) {

private Output getOutput(final HttpServletRequest req) {
final String outputArg = req.getParameter("output");
String outputFormat = outputArg.trim().toUpperCase();
if (req.getParameter("output") != null) {
try {
return Output.valueOf(outputArg.trim().toUpperCase());
return Output.valueOf(outputFormat);
} catch (IllegalArgumentException e) {
return Output.SVG;
LOG.warn("Output format value '{}' is invalid, returning with default HTML", outputFormat);
return Output.HTML;
}
}
return Output.SVG;
return Output.HTML;
}

private void setResponseHeader(final HttpServletResponse response) {
Expand Down