DRILL-5172: Display elapsed time for queries in the UI Displays the elapsed time for running queries and the total duration of completed/failed/cancelled queries in the list of query profiles displayed, and within a query's profile page as well. The query runtime is displayed in '[hr] [min] sec'. e.g. A duration of 25,254,321ms is displayed 7 hr 00 min 54.321 sec
This closes #721 Project: http://git-wip-us.apache.org/repos/asf/drill/repo Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/8a4d7a99 Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/8a4d7a99 Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/8a4d7a99 Branch: refs/heads/master Commit: 8a4d7a9940499a8c972362ab1133d75f211ec786 Parents: a093433 Author: Kunal Khatua <[email protected]> Authored: Wed Jan 11 16:45:15 2017 -0800 Committer: Parth Chandra <[email protected]> Committed: Fri Jan 13 20:07:45 2017 -0800 ---------------------------------------------------------------------- .../server/rest/profile/ProfileResources.java | 42 ++++++++++++++++++-- .../server/rest/profile/ProfileWrapper.java | 4 ++ .../src/main/resources/rest/profile/list.ftl | 9 ++++- .../src/main/resources/rest/profile/profile.ftl | 1 + 4 files changed, 51 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/drill/blob/8a4d7a99/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java index d2e953d..24d37b2 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileResources.java @@ -68,10 +68,31 @@ public class ProfileResources { @Inject DrillUserPrincipal principal; @Inject SecurityContext sc; + /** + * Returns elapsed time a human-readable format. If end time is less than the start time, current epoch time is assumed as the end time. + * e.g. getPrettyDuration(1468368841695,1468394096016) = '7 hr 00 min 54.321 sec' + * @param startTimeMillis Start Time in milliseconds + * @param endTimeMillis End Time in milliseconds + * @return Human-Readable Elapsed Time + */ + public static String getPrettyDuration(long startTimeMillis, long endTimeMillis) { + long durationInMillis = (startTimeMillis > endTimeMillis ? System.currentTimeMillis() : endTimeMillis) - startTimeMillis; + long hours = TimeUnit.MILLISECONDS.toHours(durationInMillis); + long minutes = TimeUnit.MILLISECONDS.toMinutes(durationInMillis) - TimeUnit.HOURS.toMinutes(TimeUnit.MILLISECONDS.toHours(durationInMillis)); + long seconds = TimeUnit.MILLISECONDS.toSeconds(durationInMillis) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(durationInMillis)); + long milliSeconds = durationInMillis - TimeUnit.SECONDS.toMillis(TimeUnit.MILLISECONDS.toSeconds(durationInMillis)); + String formattedDuration = (hours > 0 ? hours + " hr " : "") + + ((minutes + hours) > 0 ? String.format("%02d min ", minutes) : "") + + seconds + "." + String.format("%03d sec", milliSeconds) ; + return formattedDuration; + } + public static class ProfileInfo implements Comparable<ProfileInfo> { public static final SimpleDateFormat format = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss"); private String queryId; + private long startTime; + private long endTime; private Date time; private String location; private String foreman; @@ -79,9 +100,11 @@ public class ProfileResources { private String state; private String user; - public ProfileInfo(String queryId, long time, String foreman, String query, String state, String user) { + public ProfileInfo(String queryId, long startTime, long endTime, String foreman, String query, String state, String user) { this.queryId = queryId; - this.time = new Date(time); + this.startTime = startTime; + this.endTime = endTime; + this.time = new Date(startTime); this.foreman = foreman; this.location = "http://localhost:8047/profile/" + queryId + ".json"; this.query = query.substring(0, Math.min(query.length(), 150)); @@ -105,6 +128,17 @@ public class ProfileResources { return format.format(time); } + public long getStartTime() { + return startTime; + } + + public long getEndTime() { + return endTime; + } + + public String getDuration() { + return getPrettyDuration(startTime, endTime); + } public String getState() { return state; @@ -174,7 +208,7 @@ public class ProfileResources { final Map.Entry<String, QueryInfo> runningEntry = runningEntries.next(); final QueryInfo profile = runningEntry.getValue(); if (principal.canManageProfileOf(profile.getUser())) { - runningQueries.add(new ProfileInfo(runningEntry.getKey(), profile.getStart(), profile.getForeman().getAddress(), profile.getQuery(), profile.getState().name(), profile.getUser())); + runningQueries.add(new ProfileInfo(runningEntry.getKey(), profile.getStart(), System.currentTimeMillis(), profile.getForeman().getAddress(), profile.getQuery(), profile.getState().name(), profile.getUser())); } } catch (Exception e) { errors.add(e.getMessage()); @@ -192,7 +226,7 @@ public class ProfileResources { final Map.Entry<String, QueryProfile> profileEntry = range.next(); final QueryProfile profile = profileEntry.getValue(); if (principal.canManageProfileOf(profile.getUser())) { - finishedQueries.add(new ProfileInfo(profileEntry.getKey(), profile.getStart(), profile.getForeman().getAddress(), profile.getQuery(), profile.getState().name(), profile.getUser())); + finishedQueries.add(new ProfileInfo(profileEntry.getKey(), profile.getStart(), profile.getEnd(), profile.getForeman().getAddress(), profile.getQuery(), profile.getState().name(), profile.getUser())); } } catch (Exception e) { errors.add(e.getMessage()); http://git-wip-us.apache.org/repos/asf/drill/blob/8a4d7a99/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileWrapper.java ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileWrapper.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileWrapper.java index d9edf3a..57223f6 100644 --- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileWrapper.java +++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/profile/ProfileWrapper.java @@ -114,6 +114,10 @@ public class ProfileWrapper { return profile; } + public String getProfileDuration() { + return ProfileResources.getPrettyDuration(profile.getStart(), profile.getEnd()); + } + public String getQueryId() { return id; } http://git-wip-us.apache.org/repos/asf/drill/blob/8a4d7a99/exec/java-exec/src/main/resources/rest/profile/list.ftl ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/resources/rest/profile/list.ftl b/exec/java-exec/src/main/resources/rest/profile/list.ftl index 88d1407..1fcffb6 100644 --- a/exec/java-exec/src/main/resources/rest/profile/list.ftl +++ b/exec/java-exec/src/main/resources/rest/profile/list.ftl @@ -36,6 +36,7 @@ <td>User</td> <td>Query</td> <td>State</td> + <td>Elapsed</td> <td>Foreman</td> </thead> <tbody> @@ -62,7 +63,9 @@ </a> </td> <td> - <div style="height:100%;width:100%">${query.getState()}</div> + <div style="height:100%;width:100%">${query.getState()}</div> + <td> + <div style="height:100%;width:100%">${query.getDuration()}</div> <td> <div style="height:100%;width:100%"> ${query.getForeman()} @@ -91,6 +94,7 @@ <!-- <td>Query Id</td> --> <td>Query</td> <td>State</td> + <td>Duration</td> <td>Foreman</td> </thead> <tbody> @@ -121,6 +125,9 @@ <div style="height:100%;width:100%">${query.getState()}</div> </td> <td> + <div style="height:100%;width:100%">${query.getDuration()}</div> + </td> + <td> <div style="height:100%;width:100%"> ${query.getForeman()} </div> http://git-wip-us.apache.org/repos/asf/drill/blob/8a4d7a99/exec/java-exec/src/main/resources/rest/profile/profile.ftl ---------------------------------------------------------------------- diff --git a/exec/java-exec/src/main/resources/rest/profile/profile.ftl b/exec/java-exec/src/main/resources/rest/profile/profile.ftl index 792739f..e9a8632 100644 --- a/exec/java-exec/src/main/resources/rest/profile/profile.ftl +++ b/exec/java-exec/src/main/resources/rest/profile/profile.ftl @@ -106,6 +106,7 @@ <p>STATE: ${model.getProfile().getState().name()}</p> <p>FOREMAN: ${model.getProfile().getForeman().getAddress()}</p> <p>TOTAL FRAGMENTS: ${model.getProfile().getTotalFragments()}</p> + <p>DURATION: ${model.getProfileDuration()}</p> <#assign options = model.getOptions()> <#if (options?keys?size > 0)>
