You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by ja...@apache.org on 2015/05/10 18:30:49 UTC

[04/12] drill git commit: DRILL-2981: Add queries log. Update profile to store normal and verbose exception as well as node and errorid.

DRILL-2981: Add queries log.  Update profile to store normal and verbose exception as well as node and errorid.


Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/42d5f818
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/42d5f818
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/42d5f818

Branch: refs/heads/merge_2015_05_09
Commit: 42d5f818a5501dbd05808c53959db86e66202792
Parents: 5de7d6e
Author: Jacques Nadeau <ja...@apache.org>
Authored: Fri May 8 08:16:27 2015 -0700
Committer: Jacques Nadeau <ja...@apache.org>
Committed: Sun May 10 09:24:21 2015 -0700

----------------------------------------------------------------------
 .../drill/common/exceptions/UserException.java  |  29 +-
 .../common/exceptions/UserExceptionContext.java |  23 +-
 distribution/src/resources/drillbit.sh          |   3 +
 distribution/src/resources/logback.xml          |  24 +
 distribution/src/resources/runbit               |   2 +-
 distribution/src/resources/sqlline              |   3 +-
 distribution/src/resources/sqlline.bat          |   2 +-
 distribution/src/resources/submit_plan          |   2 +-
 .../server/rest/profile/ProfileResources.java   |  14 +-
 .../server/rest/profile/ProfileWrapper.java     |   4 +
 .../apache/drill/exec/work/foreman/Foreman.java |  68 +-
 .../drill/exec/work/foreman/LoggedQuery.java    |  80 ++
 .../drill/exec/work/foreman/QueryManager.java   |  39 +-
 .../src/main/resources/rest/profile/list.ftl    |  13 +
 .../src/main/resources/rest/profile/profile.ftl |  25 +
 exec/java-exec/src/test/resources/logback.xml   |   5 +
 .../drill/exec/proto/SchemaUserBitShared.java   |  35 +
 .../apache/drill/exec/proto/UserBitShared.java  | 962 +++++++++++++++++--
 .../drill/exec/proto/beans/QueryInfo.java       |   6 +-
 .../drill/exec/proto/beans/QueryProfile.java    | 112 +++
 protocol/src/main/protobuf/UserBitShared.proto  |   7 +-
 21 files changed, 1324 insertions(+), 134 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/common/src/main/java/org/apache/drill/common/exceptions/UserException.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/drill/common/exceptions/UserException.java b/common/src/main/java/org/apache/drill/common/exceptions/UserException.java
index d90ace1..21859ed 100644
--- a/common/src/main/java/org/apache/drill/common/exceptions/UserException.java
+++ b/common/src/main/java/org/apache/drill/common/exceptions/UserException.java
@@ -18,6 +18,7 @@
 package org.apache.drill.common.exceptions;
 
 import org.apache.drill.exec.proto.CoordinationProtos;
+import org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint;
 import org.apache.drill.exec.proto.UserBitShared.DrillPBError;
 
 /**
@@ -531,7 +532,11 @@ public class UserException extends DrillRuntimeException {
    */
   @Override
   public String getMessage() {
-    return generateMessage();
+    return generateMessage(true);
+  }
+
+  public String getMessage(boolean includeErrorIdAndIdentity) {
+    return generateMessage(includeErrorIdAndIdentity);
   }
 
   /**
@@ -548,7 +553,11 @@ public class UserException extends DrillRuntimeException {
    * @return verbose error message
    */
   public String getVerboseMessage() {
-    return generateMessage() + "\n\n" + ErrorHelper.buildCausesMessage(getCause());
+    return getVerboseMessage(true);
+  }
+
+  public String getVerboseMessage(boolean includeErrorIdAndIdentity) {
+    return generateMessage(includeErrorIdAndIdentity) + "\n\n" + ErrorHelper.buildCausesMessage(getCause());
   }
 
   /**
@@ -575,6 +584,18 @@ public class UserException extends DrillRuntimeException {
     return builder.build();
   }
 
+  public String getErrorId() {
+    return context.getErrorId();
+  }
+
+  public String getErrorLocation() {
+    DrillbitEndpoint ep = context.getEndpoint();
+    if (ep != null) {
+      return ep.getAddress() + ":" + ep.getUserPort();
+    } else {
+      return null;
+    }
+  }
   /**
    * Generates a user error message that has the following structure:
    * ERROR TYPE: ERROR_MESSAGE
@@ -583,9 +604,9 @@ public class UserException extends DrillRuntimeException {
    *
    * @return generated user error message
    */
-  private String generateMessage() {
+  private String generateMessage(boolean includeErrorIdAndIdentity) {
     return errorType + " ERROR: " + super.getMessage() + "\n\n" +
-      context.generateContextMessage();
+        context.generateContextMessage(includeErrorIdAndIdentity);
   }
 
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/common/src/main/java/org/apache/drill/common/exceptions/UserExceptionContext.java
----------------------------------------------------------------------
diff --git a/common/src/main/java/org/apache/drill/common/exceptions/UserExceptionContext.java b/common/src/main/java/org/apache/drill/common/exceptions/UserExceptionContext.java
index 7acf81d..962973b 100644
--- a/common/src/main/java/org/apache/drill/common/exceptions/UserExceptionContext.java
+++ b/common/src/main/java/org/apache/drill/common/exceptions/UserExceptionContext.java
@@ -133,24 +133,25 @@ class UserExceptionContext {
    * generate a context message
    * @return string containing all context information concatenated
    */
-  String generateContextMessage() {
+  String generateContextMessage(boolean includeErrorIdAndIdentity) {
     StringBuilder sb = new StringBuilder();
 
     for (String context : contextList) {
       sb.append(context).append("\n");
     }
 
-    // add identification infos
-    sb.append("\n[Error Id: ");
-    sb.append(errorId).append(" ");
-    if(endpoint != null) {
-      sb.append("on ")
-        .append(endpoint.getAddress())
-        .append(":")
-        .append(endpoint.getUserPort());
+    if (includeErrorIdAndIdentity) {
+      // add identification infos
+      sb.append("\n[Error Id: ");
+      sb.append(errorId).append(" ");
+      if (endpoint != null) {
+        sb.append("on ")
+            .append(endpoint.getAddress())
+            .append(":")
+            .append(endpoint.getUserPort());
+      }
+      sb.append("]");
     }
-    sb.append("]");
-
     return sb.toString();
   }
 }

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/distribution/src/resources/drillbit.sh
----------------------------------------------------------------------
diff --git a/distribution/src/resources/drillbit.sh b/distribution/src/resources/drillbit.sh
index 212d5d8..10a501b 100755
--- a/distribution/src/resources/drillbit.sh
+++ b/distribution/src/resources/drillbit.sh
@@ -147,12 +147,15 @@ JAVA=$JAVA_HOME/bin/java
 export DRILL_LOG_PREFIX=drillbit
 export DRILL_LOGFILE=$DRILL_LOG_PREFIX.log
 export DRILL_OUTFILE=$DRILL_LOG_PREFIX.out
+export DRILL_QUERYFILE=$DRILL_LOG_PREFIX_queries.json
 loggc=$DRILL_LOG_DIR/$DRILL_LOG_PREFIX.gc
 loglog="${DRILL_LOG_DIR}/${DRILL_LOGFILE}"
 logout="${DRILL_LOG_DIR}/${DRILL_OUTFILE}"
+logqueries="${DRILL_LOG_DIR}/${DRILL_QUERYFILE}"
 pid=$DRILL_PID_DIR/drillbit.pid
 
 export DRILLBIT_LOG_PATH=$loglog
+export DRILLBIT_QUERY_LOG_PATH=$logqueries
 
 if [ -n "$SERVER_GC_OPTS" ]; then
   export SERVER_GC_OPTS=${SERVER_GC_OPTS/"-Xloggc:<FILE-PATH>"/"-Xloggc:${loggc}"}

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/distribution/src/resources/logback.xml
----------------------------------------------------------------------
diff --git a/distribution/src/resources/logback.xml b/distribution/src/resources/logback.xml
index 29b0e37..350383a 100644
--- a/distribution/src/resources/logback.xml
+++ b/distribution/src/resources/logback.xml
@@ -32,6 +32,23 @@
     </encoder>
   </appender>
 
+    <appender name="QUERY" class="ch.qos.logback.core.rolling.RollingFileAppender">
+      <file>${log.query.path}</file>
+      <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
+        <fileNamePattern>${log.query.path}.%i</fileNamePattern>
+        <minIndex>1</minIndex>
+        <maxIndex>10</maxIndex>
+      </rollingPolicy>
+
+      <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
+        <maxFileSize>100MB</maxFileSize>
+      </triggeringPolicy>
+      <encoder>
+        <pattern>%msg</pattern>
+      </encoder>
+    </appender>
+    
+    
     <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
       <file>${log.path}</file>
       <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
@@ -48,11 +65,18 @@
       </encoder>
     </appender>
 
+
   <logger name="org.apache.drill" additivity="false">
     <level value="info" />
     <appender-ref ref="FILE" />
   </logger>
 
+  <logger name="query.logger" additivity="false">
+    <level value="info" />
+    <appender-ref ref="QUERY" />
+    <!--     <appender-ref ref="SOCKET" /> -->
+  </logger>
+
   <!-- 
   <logger name="org.apache.drill" additivity="false">
     <level value="debug" />

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/distribution/src/resources/runbit
----------------------------------------------------------------------
diff --git a/distribution/src/resources/runbit b/distribution/src/resources/runbit
index a8d8de8..8c54b1a 100755
--- a/distribution/src/resources/runbit
+++ b/distribution/src/resources/runbit
@@ -22,4 +22,4 @@ bin=`cd "$bin">/dev/null; pwd`
 
 DRILL_ALL_JAVA_OPTS="$DRILLBIT_JAVA_OPTS $DRILL_JAVA_OPTS $SERVER_GC_OPTS"
 
-exec $JAVA -Dlog.path=$DRILLBIT_LOG_PATH $DRILL_ALL_JAVA_OPTS -cp $CP org.apache.drill.exec.server.Drillbit
+exec $JAVA -Dlog.path=$DRILLBIT_LOG_PATH -Dlog.query.path=$DRILLBIT_QUERY_LOG_PATH $DRILL_ALL_JAVA_OPTS -cp $CP org.apache.drill.exec.server.Drillbit

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/distribution/src/resources/sqlline
----------------------------------------------------------------------
diff --git a/distribution/src/resources/sqlline b/distribution/src/resources/sqlline
index ee74057..b1b9014 100644
--- a/distribution/src/resources/sqlline
+++ b/distribution/src/resources/sqlline
@@ -41,8 +41,7 @@ bin=`cd "$bin">/dev/null; pwd`
 # so that it can still be overridden via DRILL_SHELL_JAVA_OPTS.
 DRILL_SHELL_JAVA_OPTS="-Dsqlline.isolation=TRANSACTION_NONE $DRILL_SHELL_JAVA_OPTS"
 
-DRILL_SHELL_JAVA_OPTS="$DRILL_SHELL_JAVA_OPTS -Dlog.path=$DRILL_LOG_DIR/sqlline.log"
-
+DRILL_SHELL_JAVA_OPTS="$DRILL_SHELL_JAVA_OPTS -Dlog.path=$DRILL_LOG_DIR/sqlline.log -Dlog.query.path=$DRILL_LOG_DIR/sqlline_queries.json"
 
 if [ -n "$QUERY" ] ; then
   echo $QUERY | exec "$JAVA" $DRILL_SHELL_JAVA_OPTS $DRILL_JAVA_OPTS -cp $CP sqlline.SqlLine -d org.apache.drill.jdbc.Driver  --maxWidth=10000 "${ARGS[@]}"

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/distribution/src/resources/sqlline.bat
----------------------------------------------------------------------
diff --git a/distribution/src/resources/sqlline.bat b/distribution/src/resources/sqlline.bat
index 2564b8c..3451b0e 100755
--- a/distribution/src/resources/sqlline.bat
+++ b/distribution/src/resources/sqlline.bat
@@ -176,7 +176,7 @@ rem Put our property specification before previous value of DRILL_SHELL_JAVA_OPT
 rem so that it can still be overridden via DRILL_SHELL_JAVA_OPTS.
 set DRILL_SHELL_JAVA_OPTS=-Dsqlline.isolation=TRANSACTION_NONE %DRILL_SHELL_JAVA_OPTS%
 
-set DRILL_SHELL_JAVA_OPTS=%DRILL_SHELL_JAVA_OPTS% -Dlog.path="%DRILL_LOG_DIR%\sqlline.log"
+set DRILL_SHELL_JAVA_OPTS=%DRILL_SHELL_JAVA_OPTS% -Dlog.path="%DRILL_LOG_DIR%\sqlline.log" -Dlog.query.path="%DRILL_LOG_DIR%\sqlline_queries.log"
 
 SET JAVA_CMD=%JAVA_HOME%\bin\%JAVA_EXE%
 if "%JAVA_HOME%" == "" (set JAVA_CMD=%JAVA_EXE%)

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/distribution/src/resources/submit_plan
----------------------------------------------------------------------
diff --git a/distribution/src/resources/submit_plan b/distribution/src/resources/submit_plan
index 4ed0662..0a58d8c 100755
--- a/distribution/src/resources/submit_plan
+++ b/distribution/src/resources/submit_plan
@@ -20,6 +20,6 @@ bin=`cd "$bin">/dev/null; pwd`
 
 . "$bin"/drill-config.sh
 
-DRILL_SHELL_JAVA_OPTS="$DRILL_SHELL_JAVA_OPTS -Dlog.path=$DRILL_LOG_DIR/submitter.log"
+DRILL_SHELL_JAVA_OPTS="$DRILL_SHELL_JAVA_OPTS -Dlog.path=$DRILL_LOG_DIR/submitter.log -Dlog.query.path=$DRILL_LOG_DIR/submitter_queries.json"
 
 exec $JAVA $DRILL_SHELL_JAVA_OPTS $DRILL_JAVA_OPTS -cp $CP org.apache.drill.exec.client.QuerySubmitter "$@"

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/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 c83acad..6656bf6 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
@@ -63,14 +63,20 @@ public class ProfileResources {
     private String foreman;
     private String query;
     private String state;
+    private String user;
 
-    public ProfileInfo(String queryId, long time, String foreman, String query, String state) {
+    public ProfileInfo(String queryId, long time, String foreman, String query, String state, String user) {
       this.queryId = queryId;
       this.time = new Date(time);
       this.foreman = foreman;
       this.location = "http://localhost:8047/profile/" + queryId + ".json";
       this.query = query = query.substring(0,  Math.min(query.length(), 150));
       this.state = state;
+      this.user = user;
+    }
+
+    public String getUser() {
+      return user;
     }
 
     public String getQuery(){
@@ -146,7 +152,8 @@ public class ProfileResources {
 
     for (Map.Entry<String, QueryInfo> entry : running) {
       QueryInfo profile = entry.getValue();
-      runningQueries.add(new ProfileInfo(entry.getKey(), profile.getStart(), profile.getForeman().getAddress(), profile.getQuery(), profile.getState().name()));
+      runningQueries.add(new ProfileInfo(entry.getKey(), profile.getStart(), profile.getForeman().getAddress(), profile
+          .getQuery(), profile.getState().name(), profile.getUser()));
     }
 
     Collections.sort(runningQueries, Collections.reverseOrder());
@@ -155,7 +162,8 @@ public class ProfileResources {
     List<ProfileInfo> finishedQueries = Lists.newArrayList();
     for (Map.Entry<String, QueryProfile> entry : completed) {
       QueryProfile profile = entry.getValue();
-      finishedQueries.add(new ProfileInfo(entry.getKey(), profile.getStart(), profile.getForeman().getAddress(), profile.getQuery(), profile.getState().name()));
+      finishedQueries.add(new ProfileInfo(entry.getKey(), profile.getStart(), profile.getForeman().getAddress(),
+          profile.getQuery(), profile.getState().name(), profile.getUser()));
     }
 
     return new QProfiles(runningQueries, finishedQueries);

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/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 b34bb3a..dd26a76 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
@@ -43,6 +43,10 @@ public class ProfileWrapper {
     this.id = QueryIdHelper.getQueryId(profile.getId());
   }
 
+  public boolean hasError() {
+    return profile.hasError() && profile.getError() != null;
+  }
+
   public QueryProfile getProfile() {
     return profile;
   }

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/Foreman.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/Foreman.java b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/Foreman.java
index 7b36e21..4d403b8 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/Foreman.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/Foreman.java
@@ -24,6 +24,7 @@ import io.netty.util.concurrent.GenericFutureListener;
 
 import java.io.IOException;
 import java.util.Collection;
+import java.util.Date;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
@@ -105,6 +106,8 @@ import com.google.common.collect.Sets;
  */
 public class Foreman implements Runnable {
   private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(Foreman.class);
+  private static final org.slf4j.Logger queryLogger = org.slf4j.LoggerFactory.getLogger("query.logger");
+  private static final ObjectMapper MAPPER = new ObjectMapper();
   private final static ExecutionControlsInjector injector = ExecutionControlsInjector.getInjector(Foreman.class);
   private static final int RPC_WAIT_IN_SECONDS = 90;
 
@@ -129,6 +132,7 @@ public class Foreman implements Runnable {
   private final ConnectionClosedListener closeListener = new ConnectionClosedListener();
   private final ChannelFuture closeFuture;
 
+  private String queryText;
 
   /**
    * Constructor. Sets up the Foreman, but does not initiate any execution.
@@ -209,6 +213,8 @@ public class Foreman implements Runnable {
 
     try {
       injector.injectChecked(queryContext.getExecutionControls(), "run-try-beginning", ForemanException.class);
+      queryText = queryRequest.getPlan();
+
       // convert a run query request into action
       switch (queryRequest.getType()) {
       case LOGICAL:
@@ -435,19 +441,22 @@ public class Foreman implements Runnable {
       }
 
       final long queueTimeout = optionManager.getOption(ExecConstants.QUEUE_TIMEOUT);
+      final String queueName;
 
       try {
         @SuppressWarnings("resource")
         final ClusterCoordinator clusterCoordinator = drillbitContext.getClusterCoordinator();
-        DistributedSemaphore distributedSemaphore;
+        final DistributedSemaphore distributedSemaphore;
 
         // get the appropriate semaphore
         if (totalCost > queueThreshold) {
           final int largeQueue = (int) optionManager.getOption(ExecConstants.LARGE_QUEUE_SIZE);
           distributedSemaphore = clusterCoordinator.getSemaphore("query.large", largeQueue);
+          queueName = "large";
         } else {
           final int smallQueue = (int) optionManager.getOption(ExecConstants.SMALL_QUEUE_SIZE);
           distributedSemaphore = clusterCoordinator.getSemaphore("query.small", smallQueue);
+          queueName = "small";
         }
 
 
@@ -459,14 +468,19 @@ public class Foreman implements Runnable {
       if (lease == null) {
         throw UserException
             .resourceError()
-            .message("Unable to acquire queue resources for query within timeout.  Timeout was set at %d seconds.",
-                queueTimeout / 1000)
+            .message(
+                "Unable to acquire queue resources for query within timeout.  Timeout for %s queue was set at %d seconds.",
+                queueTimeout / 1000, queueName)
             .build();
       }
 
     }
   }
 
+  Exception getCurrentException() {
+    return foremanResult.getException();
+  }
+
   private QueryWorkUnit getQueryWorkUnit(final PhysicalPlan plan) throws ExecutionSetupException {
     final PhysicalOperator rootOperator = plan.getSortedOperators(false).iterator().next();
     final Fragment rootFragment = rootOperator.accept(MakeFragmentsVisitor.INSTANCE, null);
@@ -536,7 +550,7 @@ public class Foreman implements Runnable {
    */
   private class ForemanResult implements AutoCloseable {
     private QueryState resultState = null;
-    private Exception resultException = null;
+    private volatile Exception resultException = null;
     private boolean isClosed = false;
 
     /**
@@ -589,11 +603,20 @@ public class Foreman implements Runnable {
     }
 
     /**
-     * Close the given resource, catching and adding any caught exceptions via
-     * {@link #addException(Exception)}. If an exception is caught, it will change
-     * the result state to FAILED, regardless of what its current value.
+     * Expose the current exception (if it exists). This is useful for secondary reporting to the query profile.
+     *
+     * @return the current Foreman result exception or null.
+     */
+    public Exception getException() {
+      return resultException;
+    }
+
+    /**
+     * Close the given resource, catching and adding any caught exceptions via {@link #addException(Exception)}. If an
+     * exception is caught, it will change the result state to FAILED, regardless of what its current value.
      *
-     * @param autoCloseable the resource to close
+     * @param autoCloseable
+     *          the resource to close
      */
     private void suppressingClose(final AutoCloseable autoCloseable) {
       Preconditions.checkState(!isClosed);
@@ -615,6 +638,22 @@ public class Foreman implements Runnable {
       }
     }
 
+    private void logQuerySummary() {
+      try {
+        LoggedQuery q = new LoggedQuery(
+            QueryIdHelper.getQueryId(queryId),
+            queryContext.getQueryContextInfo().getDefaultSchemaName(),
+            queryText,
+            new Date(queryContext.getQueryContextInfo().getQueryStartTime()),
+            new Date(System.currentTimeMillis()),
+            state,
+            queryContext.getSession().getCredentials().getUserName());
+        queryLogger.info(MAPPER.writeValueAsString(q));
+      } catch (Exception e) {
+        logger.error("Failure while recording query information to query log.", e);
+      }
+    }
+
     @Override
     public void close() {
       Preconditions.checkState(!isClosed);
@@ -626,6 +665,9 @@ public class Foreman implements Runnable {
       // remove the channel disconnected listener (doesn't throw)
       closeFuture.removeListener(closeListener);
 
+      // log the query summary
+      logQuerySummary();
+
       // These are straight forward removals from maps, so they won't throw.
       drillbitContext.getWorkBus().removeFragmentStatusListener(queryId);
       drillbitContext.getClusterCoordinator().removeDrillbitStatusListener(queryManager.getDrillbitStatusListener());
@@ -653,12 +695,18 @@ public class Foreman implements Runnable {
       final QueryResult.Builder resultBuilder = QueryResult.newBuilder()
           .setQueryId(queryId)
           .setQueryState(resultState);
+      final UserException uex;
       if (resultException != null) {
         final boolean verbose = queryContext.getOptions().getOption(ExecConstants.ENABLE_VERBOSE_ERRORS_KEY).bool_val;
-        final UserException uex = UserException.systemError(resultException).addIdentity(queryContext.getCurrentEndpoint()).build();
+        uex = UserException.systemError(resultException).addIdentity(queryContext.getCurrentEndpoint()).build();
         resultBuilder.addError(uex.getOrCreatePBError(verbose));
+      } else {
+        uex = null;
       }
 
+      // we store the final result here so we can capture any error/errorId in the profile for later debugging.
+      queryManager.writeFinalProfile(uex);
+
       /*
        * If sending the result fails, we don't really have any way to modify the result we tried to send;
        * it is possible it got sent but the result came from a later part of the code path. It is also
@@ -802,7 +850,7 @@ public class Foreman implements Runnable {
 
   private void recordNewState(final QueryState newState) {
     state = newState;
-    queryManager.updateQueryStateInStore(newState);
+    queryManager.updateEphemeralState(newState);
   }
 
   private void runSQL(final String sql) throws ExecutionSetupException {

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/LoggedQuery.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/LoggedQuery.java b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/LoggedQuery.java
new file mode 100644
index 0000000..f856d53
--- /dev/null
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/LoggedQuery.java
@@ -0,0 +1,80 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.drill.exec.work.foreman;
+
+import java.util.Date;
+
+import org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class LoggedQuery {
+  static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LoggedQuery.class);
+
+  private final String queryId;
+  private final String schema;
+  private final String queryText;
+  private final Date start;
+  private final Date finish;
+  private final QueryState outcome;
+  private final String username;
+
+  public LoggedQuery(String queryId, String schema, String queryText, Date start, Date finish, QueryState outcome,
+      String username) {
+    super();
+    this.queryId = queryId;
+    this.schema = schema;
+    this.queryText = queryText;
+    this.start = start;
+    this.finish = finish;
+    this.outcome = outcome;
+    this.username = username;
+  }
+
+  @JsonProperty("id")
+  public String getQueryId() {
+    return queryId;
+  }
+
+  public String getSchema() {
+    return schema;
+  }
+
+  @JsonProperty("query")
+  public String getQueryText() {
+    return queryText;
+  }
+
+  public Date getStart() {
+    return start;
+  }
+
+  public Date getFinish() {
+    return finish;
+  }
+
+  public QueryState getOutcome() {
+    return outcome;
+  }
+
+  @JsonProperty("user")
+  public String getUsername() {
+    return username;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/QueryManager.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/QueryManager.java b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/QueryManager.java
index 34fa639..c4646bd 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/QueryManager.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/QueryManager.java
@@ -26,6 +26,7 @@ import java.util.Set;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.drill.common.exceptions.DrillRuntimeException;
+import org.apache.drill.common.exceptions.UserException;
 import org.apache.drill.common.exceptions.UserRemoteException;
 import org.apache.drill.exec.ops.FragmentContext;
 import org.apache.drill.exec.proto.BitControl.FragmentStatus;
@@ -225,7 +226,7 @@ public class QueryManager {
     }
   }
 
-  QueryState updateQueryStateInStore(final QueryState queryState) {
+  QueryState updateEphemeralState(final QueryState queryState) {
     switch (queryState) {
       case PENDING:
       case RUNNING:
@@ -242,8 +243,6 @@ public class QueryManager {
           logger.warn("Failure while trying to delete the estore profile for this query.", e);
         }
 
-        // TODO(DRILL-2362) when do these ever get deleted?
-        profilePStore.put(stringQueryId, getQueryProfile());
         break;
 
       default:
@@ -253,18 +252,33 @@ public class QueryManager {
     return queryState;
   }
 
+  void writeFinalProfile(UserException ex) {
+    try {
+      // TODO(DRILL-2362) when do these ever get deleted?
+      profilePStore.put(stringQueryId, getQueryProfile(ex));
+    } catch (Exception e) {
+      logger.error("Failure while storing Query Profile", e);
+    }
+  }
+
   private QueryInfo getQueryInfo() {
     return QueryInfo.newBuilder()
-      .setQuery(runQuery.getPlan())
-      .setState(foreman.getState())
-      .setForeman(foreman.getQueryContext().getCurrentEndpoint())
-      .setStart(startTime)
-      .build();
+        .setQuery(runQuery.getPlan())
+        .setState(foreman.getState())
+        .setUser(foreman.getQueryContext().getQueryUserName())
+        .setForeman(foreman.getQueryContext().getCurrentEndpoint())
+        .setStart(startTime)
+        .build();
   }
 
   public QueryProfile getQueryProfile() {
+    return getQueryProfile(null);
+  }
+
+  private QueryProfile getQueryProfile(UserException ex) {
     final QueryProfile.Builder profileBuilder = QueryProfile.newBuilder()
         .setQuery(runQuery.getPlan())
+        .setUser(foreman.getQueryContext().getQueryUserName())
         .setType(runQuery.getType())
         .setId(queryId)
         .setState(foreman.getState())
@@ -274,6 +288,15 @@ public class QueryManager {
         .setTotalFragments(fragmentDataSet.size())
         .setFinishedFragments(finishedFragments.get());
 
+    if (ex != null) {
+      profileBuilder.setError(ex.getMessage(false));
+      profileBuilder.setVerboseError(ex.getVerboseMessage(false));
+      profileBuilder.setErrorId(ex.getErrorId());
+      if (ex.getErrorLocation() != null) {
+        profileBuilder.setErrorNode(ex.getErrorLocation());
+      }
+    }
+
     if (planText != null) {
       profileBuilder.setPlan(planText);
     }

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/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 921e52f..cf92ede 100644
--- a/exec/java-exec/src/main/resources/rest/profile/list.ftl
+++ b/exec/java-exec/src/main/resources/rest/profile/list.ftl
@@ -24,6 +24,7 @@
         <thead>
            <td>Time</td>
            <!-- <td>Query Id</td> -->
+           <td>User</td>
            <td>Query</td>
            <td>State</td>
            <td>Foreman</td>
@@ -43,6 +44,11 @@
             -->
             <td>
               <a href="/profiles/${query.getQueryId()}">
+              <div style="height:100%;width:100%;white-space:pre-line">${query.getUser()}</div>
+              </a>
+            </td> 
+            <td>
+              <a href="/profiles/${query.getQueryId()}">
               <div style="height:100%;width:100%;white-space:pre-line">${query.getQuery()}</div>
               </a>
             </td> 
@@ -72,6 +78,7 @@
     <table class="table table-hover">
       <thead>
          <td>Time</td>
+         <td>User</td>
          <!-- <td>Query Id</td> -->
          <td>Query</td>
          <td>State</td>
@@ -92,6 +99,12 @@
           -->
           <td>
             <a href="/profiles/${query.getQueryId()}">
+            <div style="height:100%;width:100%;white-space:pre-line">${query.getUser()}</div>
+            </a>
+          </td> 
+          
+          <td>
+            <a href="/profiles/${query.getQueryId()}">
               <div style="height:100%;width:100%;white-space:pre-line">${query.getQuery()}</div>
             </a>
           </td>      

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/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 42a7447..46cdc83 100644
--- a/exec/java-exec/src/main/resources/rest/profile/profile.ftl
+++ b/exec/java-exec/src/main/resources/rest/profile/profile.ftl
@@ -32,6 +32,7 @@
     <li><a href="#query-physical" role="tab" data-toggle="tab">Physical Plan</a></li>
     <li><a href="#query-visual" role="tab" data-toggle="tab">Visualized Plan</a></li>
     <li><a href="#query-edit" role="tab" data-toggle="tab">Edit Query</a></li>
+    <#if model.hasError() ><li><a href="#query-error" role="tab" data-toggle="tab">Error</a></li></#if>
   </ul>
   <div id="query-content" class="tab-content">
     <div id="query-query" class="tab-pane">
@@ -74,6 +75,30 @@
         <button type="link" class="btn btn-default">Cancel query</button>
       </form>
     </div>
+    <#if model.hasError() >
+    <div id="query-error" class="tab-pane">
+      <p>
+      <pre>
+      ${model.getProfile().error?trim}
+      </pre>
+      </p>
+      <p>ErrorId: ${model.getProfile().errorNode}</p>
+      <p>Failure node:  ${model.getProfile().errorId}</p> 
+      
+        <h3 class="panel-title">
+          <a data-toggle="collapse" href="#error-verbose">
+            Verbose Error Message...
+          </a>
+        </h3>
+      <div id="error-verbose" class="panel-collapse collapse">
+        <div class="panel-body">
+        <p></p><p></p>
+          <pre>
+            ${model.getProfile().verboseError?trim}
+          </pre>
+        </div>
+    </div>
+    </#if>
   </div>
 
   <div class="page-header"></div>

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/exec/java-exec/src/test/resources/logback.xml
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/resources/logback.xml b/exec/java-exec/src/test/resources/logback.xml
index 2dcfed9..54ccb42 100644
--- a/exec/java-exec/src/test/resources/logback.xml
+++ b/exec/java-exec/src/test/resources/logback.xml
@@ -36,6 +36,11 @@
     <appender-ref ref="SOCKET" />
   </logger>
 
+  <logger name="query.logger" additivity="false">
+    <level value="info" />
+    <appender-ref ref="SOCKET" />
+  </logger>
+
 <!--   <logger name="io.netty" additivity="false"> -->
 <!--     <level value="debug" /> -->
 <!--     <appender-ref ref="SOCKET" /> -->

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserBitShared.java
----------------------------------------------------------------------
diff --git a/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserBitShared.java b/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserBitShared.java
index eca19a0..bee2a3d 100644
--- a/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserBitShared.java
+++ b/protocol/src/main/java/org/apache/drill/exec/proto/SchemaUserBitShared.java
@@ -1778,6 +1778,16 @@ public final class SchemaUserBitShared
                 for(org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile fragmentProfile : message.getFragmentProfileList())
                     output.writeObject(11, fragmentProfile, org.apache.drill.exec.proto.SchemaUserBitShared.MajorFragmentProfile.WRITE, true);
 
+                if(message.hasUser())
+                    output.writeString(12, message.getUser(), false);
+                if(message.hasError())
+                    output.writeString(13, message.getError(), false);
+                if(message.hasVerboseError())
+                    output.writeString(14, message.getVerboseError(), false);
+                if(message.hasErrorId())
+                    output.writeString(15, message.getErrorId(), false);
+                if(message.hasErrorNode())
+                    output.writeString(16, message.getErrorNode(), false);
             }
             public boolean isInitialized(org.apache.drill.exec.proto.UserBitShared.QueryProfile message)
             {
@@ -1853,6 +1863,21 @@ public final class SchemaUserBitShared
                             builder.addFragmentProfile(input.mergeObject(org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.newBuilder(), org.apache.drill.exec.proto.SchemaUserBitShared.MajorFragmentProfile.MERGE));
 
                             break;
+                        case 12:
+                            builder.setUser(input.readString());
+                            break;
+                        case 13:
+                            builder.setError(input.readString());
+                            break;
+                        case 14:
+                            builder.setVerboseError(input.readString());
+                            break;
+                        case 15:
+                            builder.setErrorId(input.readString());
+                            break;
+                        case 16:
+                            builder.setErrorNode(input.readString());
+                            break;
                         default:
                             input.handleUnknownField(number, this);
                     }
@@ -1904,6 +1929,11 @@ public final class SchemaUserBitShared
                 case 9: return "totalFragments";
                 case 10: return "finishedFragments";
                 case 11: return "fragmentProfile";
+                case 12: return "user";
+                case 13: return "error";
+                case 14: return "verboseError";
+                case 15: return "errorId";
+                case 16: return "errorNode";
                 default: return null;
             }
         }
@@ -1926,6 +1956,11 @@ public final class SchemaUserBitShared
             fieldMap.put("totalFragments", 9);
             fieldMap.put("finishedFragments", 10);
             fieldMap.put("fragmentProfile", 11);
+            fieldMap.put("user", 12);
+            fieldMap.put("error", 13);
+            fieldMap.put("verboseError", 14);
+            fieldMap.put("errorId", 15);
+            fieldMap.put("errorNode", 16);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/protocol/src/main/java/org/apache/drill/exec/proto/UserBitShared.java
----------------------------------------------------------------------
diff --git a/protocol/src/main/java/org/apache/drill/exec/proto/UserBitShared.java b/protocol/src/main/java/org/apache/drill/exec/proto/UserBitShared.java
index a229450..ec92392 100644
--- a/protocol/src/main/java/org/apache/drill/exec/proto/UserBitShared.java
+++ b/protocol/src/main/java/org/apache/drill/exec/proto/UserBitShared.java
@@ -12012,17 +12012,17 @@ public final class UserBitShared {
      */
     org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState getState();
 
-    // optional string user = 4;
+    // optional string user = 4 [default = "-"];
     /**
-     * <code>optional string user = 4;</code>
+     * <code>optional string user = 4 [default = "-"];</code>
      */
     boolean hasUser();
     /**
-     * <code>optional string user = 4;</code>
+     * <code>optional string user = 4 [default = "-"];</code>
      */
     java.lang.String getUser();
     /**
-     * <code>optional string user = 4;</code>
+     * <code>optional string user = 4 [default = "-"];</code>
      */
     com.google.protobuf.ByteString
         getUserBytes();
@@ -12246,17 +12246,17 @@ public final class UserBitShared {
       return state_;
     }
 
-    // optional string user = 4;
+    // optional string user = 4 [default = "-"];
     public static final int USER_FIELD_NUMBER = 4;
     private java.lang.Object user_;
     /**
-     * <code>optional string user = 4;</code>
+     * <code>optional string user = 4 [default = "-"];</code>
      */
     public boolean hasUser() {
       return ((bitField0_ & 0x00000008) == 0x00000008);
     }
     /**
-     * <code>optional string user = 4;</code>
+     * <code>optional string user = 4 [default = "-"];</code>
      */
     public java.lang.String getUser() {
       java.lang.Object ref = user_;
@@ -12273,7 +12273,7 @@ public final class UserBitShared {
       }
     }
     /**
-     * <code>optional string user = 4;</code>
+     * <code>optional string user = 4 [default = "-"];</code>
      */
     public com.google.protobuf.ByteString
         getUserBytes() {
@@ -12315,7 +12315,7 @@ public final class UserBitShared {
       query_ = "";
       start_ = 0L;
       state_ = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.PENDING;
-      user_ = "";
+      user_ = "-";
       foreman_ = org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance();
     }
     private byte memoizedIsInitialized = -1;
@@ -12497,7 +12497,7 @@ public final class UserBitShared {
         bitField0_ = (bitField0_ & ~0x00000002);
         state_ = org.apache.drill.exec.proto.UserBitShared.QueryResult.QueryState.PENDING;
         bitField0_ = (bitField0_ & ~0x00000004);
-        user_ = "";
+        user_ = "-";
         bitField0_ = (bitField0_ & ~0x00000008);
         if (foremanBuilder_ == null) {
           foreman_ = org.apache.drill.exec.proto.CoordinationProtos.DrillbitEndpoint.getDefaultInstance();
@@ -12762,16 +12762,16 @@ public final class UserBitShared {
         return this;
       }
 
-      // optional string user = 4;
-      private java.lang.Object user_ = "";
+      // optional string user = 4 [default = "-"];
+      private java.lang.Object user_ = "-";
       /**
-       * <code>optional string user = 4;</code>
+       * <code>optional string user = 4 [default = "-"];</code>
        */
       public boolean hasUser() {
         return ((bitField0_ & 0x00000008) == 0x00000008);
       }
       /**
-       * <code>optional string user = 4;</code>
+       * <code>optional string user = 4 [default = "-"];</code>
        */
       public java.lang.String getUser() {
         java.lang.Object ref = user_;
@@ -12785,7 +12785,7 @@ public final class UserBitShared {
         }
       }
       /**
-       * <code>optional string user = 4;</code>
+       * <code>optional string user = 4 [default = "-"];</code>
        */
       public com.google.protobuf.ByteString
           getUserBytes() {
@@ -12801,7 +12801,7 @@ public final class UserBitShared {
         }
       }
       /**
-       * <code>optional string user = 4;</code>
+       * <code>optional string user = 4 [default = "-"];</code>
        */
       public Builder setUser(
           java.lang.String value) {
@@ -12814,7 +12814,7 @@ public final class UserBitShared {
         return this;
       }
       /**
-       * <code>optional string user = 4;</code>
+       * <code>optional string user = 4 [default = "-"];</code>
        */
       public Builder clearUser() {
         bitField0_ = (bitField0_ & ~0x00000008);
@@ -12823,7 +12823,7 @@ public final class UserBitShared {
         return this;
       }
       /**
-       * <code>optional string user = 4;</code>
+       * <code>optional string user = 4 [default = "-"];</code>
        */
       public Builder setUserBytes(
           com.google.protobuf.ByteString value) {
@@ -13109,6 +13109,81 @@ public final class UserBitShared {
      */
     org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfileOrBuilder getFragmentProfileOrBuilder(
         int index);
+
+    // optional string user = 12 [default = "-"];
+    /**
+     * <code>optional string user = 12 [default = "-"];</code>
+     */
+    boolean hasUser();
+    /**
+     * <code>optional string user = 12 [default = "-"];</code>
+     */
+    java.lang.String getUser();
+    /**
+     * <code>optional string user = 12 [default = "-"];</code>
+     */
+    com.google.protobuf.ByteString
+        getUserBytes();
+
+    // optional string error = 13;
+    /**
+     * <code>optional string error = 13;</code>
+     */
+    boolean hasError();
+    /**
+     * <code>optional string error = 13;</code>
+     */
+    java.lang.String getError();
+    /**
+     * <code>optional string error = 13;</code>
+     */
+    com.google.protobuf.ByteString
+        getErrorBytes();
+
+    // optional string verboseError = 14;
+    /**
+     * <code>optional string verboseError = 14;</code>
+     */
+    boolean hasVerboseError();
+    /**
+     * <code>optional string verboseError = 14;</code>
+     */
+    java.lang.String getVerboseError();
+    /**
+     * <code>optional string verboseError = 14;</code>
+     */
+    com.google.protobuf.ByteString
+        getVerboseErrorBytes();
+
+    // optional string error_id = 15;
+    /**
+     * <code>optional string error_id = 15;</code>
+     */
+    boolean hasErrorId();
+    /**
+     * <code>optional string error_id = 15;</code>
+     */
+    java.lang.String getErrorId();
+    /**
+     * <code>optional string error_id = 15;</code>
+     */
+    com.google.protobuf.ByteString
+        getErrorIdBytes();
+
+    // optional string error_node = 16;
+    /**
+     * <code>optional string error_node = 16;</code>
+     */
+    boolean hasErrorNode();
+    /**
+     * <code>optional string error_node = 16;</code>
+     */
+    java.lang.String getErrorNode();
+    /**
+     * <code>optional string error_node = 16;</code>
+     */
+    com.google.protobuf.ByteString
+        getErrorNodeBytes();
   }
   /**
    * Protobuf type {@code exec.shared.QueryProfile}
@@ -13247,6 +13322,31 @@ public final class UserBitShared {
               fragmentProfile_.add(input.readMessage(org.apache.drill.exec.proto.UserBitShared.MajorFragmentProfile.PARSER, extensionRegistry));
               break;
             }
+            case 98: {
+              bitField0_ |= 0x00000400;
+              user_ = input.readBytes();
+              break;
+            }
+            case 106: {
+              bitField0_ |= 0x00000800;
+              error_ = input.readBytes();
+              break;
+            }
+            case 114: {
+              bitField0_ |= 0x00001000;
+              verboseError_ = input.readBytes();
+              break;
+            }
+            case 122: {
+              bitField0_ |= 0x00002000;
+              errorId_ = input.readBytes();
+              break;
+            }
+            case 130: {
+              bitField0_ |= 0x00004000;
+              errorNode_ = input.readBytes();
+              break;
+            }
           }
         }
       } catch (com.google.protobuf.InvalidProtocolBufferException e) {
@@ -13552,6 +13652,221 @@ public final class UserBitShared {
       return fragmentProfile_.get(index);
     }
 
+    // optional string user = 12 [default = "-"];
+    public static final int USER_FIELD_NUMBER = 12;
+    private java.lang.Object user_;
+    /**
+     * <code>optional string user = 12 [default = "-"];</code>
+     */
+    public boolean hasUser() {
+      return ((bitField0_ & 0x00000400) == 0x00000400);
+    }
+    /**
+     * <code>optional string user = 12 [default = "-"];</code>
+     */
+    public java.lang.String getUser() {
+      java.lang.Object ref = user_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          user_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string user = 12 [default = "-"];</code>
+     */
+    public com.google.protobuf.ByteString
+        getUserBytes() {
+      java.lang.Object ref = user_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        user_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional string error = 13;
+    public static final int ERROR_FIELD_NUMBER = 13;
+    private java.lang.Object error_;
+    /**
+     * <code>optional string error = 13;</code>
+     */
+    public boolean hasError() {
+      return ((bitField0_ & 0x00000800) == 0x00000800);
+    }
+    /**
+     * <code>optional string error = 13;</code>
+     */
+    public java.lang.String getError() {
+      java.lang.Object ref = error_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          error_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string error = 13;</code>
+     */
+    public com.google.protobuf.ByteString
+        getErrorBytes() {
+      java.lang.Object ref = error_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        error_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional string verboseError = 14;
+    public static final int VERBOSEERROR_FIELD_NUMBER = 14;
+    private java.lang.Object verboseError_;
+    /**
+     * <code>optional string verboseError = 14;</code>
+     */
+    public boolean hasVerboseError() {
+      return ((bitField0_ & 0x00001000) == 0x00001000);
+    }
+    /**
+     * <code>optional string verboseError = 14;</code>
+     */
+    public java.lang.String getVerboseError() {
+      java.lang.Object ref = verboseError_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          verboseError_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string verboseError = 14;</code>
+     */
+    public com.google.protobuf.ByteString
+        getVerboseErrorBytes() {
+      java.lang.Object ref = verboseError_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        verboseError_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional string error_id = 15;
+    public static final int ERROR_ID_FIELD_NUMBER = 15;
+    private java.lang.Object errorId_;
+    /**
+     * <code>optional string error_id = 15;</code>
+     */
+    public boolean hasErrorId() {
+      return ((bitField0_ & 0x00002000) == 0x00002000);
+    }
+    /**
+     * <code>optional string error_id = 15;</code>
+     */
+    public java.lang.String getErrorId() {
+      java.lang.Object ref = errorId_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          errorId_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string error_id = 15;</code>
+     */
+    public com.google.protobuf.ByteString
+        getErrorIdBytes() {
+      java.lang.Object ref = errorId_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        errorId_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    // optional string error_node = 16;
+    public static final int ERROR_NODE_FIELD_NUMBER = 16;
+    private java.lang.Object errorNode_;
+    /**
+     * <code>optional string error_node = 16;</code>
+     */
+    public boolean hasErrorNode() {
+      return ((bitField0_ & 0x00004000) == 0x00004000);
+    }
+    /**
+     * <code>optional string error_node = 16;</code>
+     */
+    public java.lang.String getErrorNode() {
+      java.lang.Object ref = errorNode_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (bs.isValidUtf8()) {
+          errorNode_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>optional string error_node = 16;</code>
+     */
+    public com.google.protobuf.ByteString
+        getErrorNodeBytes() {
+      java.lang.Object ref = errorNode_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        errorNode_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
     private void initFields() {
       id_ = org.apache.drill.exec.proto.UserBitShared.QueryId.getDefaultInstance();
       type_ = org.apache.drill.exec.proto.UserBitShared.QueryType.SQL;
@@ -13564,6 +13879,11 @@ public final class UserBitShared {
       totalFragments_ = 0;
       finishedFragments_ = 0;
       fragmentProfile_ = java.util.Collections.emptyList();
+      user_ = "-";
+      error_ = "";
+      verboseError_ = "";
+      errorId_ = "";
+      errorNode_ = "";
     }
     private byte memoizedIsInitialized = -1;
     public final boolean isInitialized() {
@@ -13610,6 +13930,21 @@ public final class UserBitShared {
       for (int i = 0; i < fragmentProfile_.size(); i++) {
         output.writeMessage(11, fragmentProfile_.get(i));
       }
+      if (((bitField0_ & 0x00000400) == 0x00000400)) {
+        output.writeBytes(12, getUserBytes());
+      }
+      if (((bitField0_ & 0x00000800) == 0x00000800)) {
+        output.writeBytes(13, getErrorBytes());
+      }
+      if (((bitField0_ & 0x00001000) == 0x00001000)) {
+        output.writeBytes(14, getVerboseErrorBytes());
+      }
+      if (((bitField0_ & 0x00002000) == 0x00002000)) {
+        output.writeBytes(15, getErrorIdBytes());
+      }
+      if (((bitField0_ & 0x00004000) == 0x00004000)) {
+        output.writeBytes(16, getErrorNodeBytes());
+      }
       getUnknownFields().writeTo(output);
     }
 
@@ -13663,6 +13998,26 @@ public final class UserBitShared {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(11, fragmentProfile_.get(i));
       }
+      if (((bitField0_ & 0x00000400) == 0x00000400)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(12, getUserBytes());
+      }
+      if (((bitField0_ & 0x00000800) == 0x00000800)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(13, getErrorBytes());
+      }
+      if (((bitField0_ & 0x00001000) == 0x00001000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(14, getVerboseErrorBytes());
+      }
+      if (((bitField0_ & 0x00002000) == 0x00002000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(15, getErrorIdBytes());
+      }
+      if (((bitField0_ & 0x00004000) == 0x00004000)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBytesSize(16, getErrorNodeBytes());
+      }
       size += getUnknownFields().getSerializedSize();
       memoizedSerializedSize = size;
       return size;
@@ -13816,6 +14171,16 @@ public final class UserBitShared {
         } else {
           fragmentProfileBuilder_.clear();
         }
+        user_ = "-";
+        bitField0_ = (bitField0_ & ~0x00000800);
+        error_ = "";
+        bitField0_ = (bitField0_ & ~0x00001000);
+        verboseError_ = "";
+        bitField0_ = (bitField0_ & ~0x00002000);
+        errorId_ = "";
+        bitField0_ = (bitField0_ & ~0x00004000);
+        errorNode_ = "";
+        bitField0_ = (bitField0_ & ~0x00008000);
         return this;
       }
 
@@ -13901,6 +14266,26 @@ public final class UserBitShared {
         } else {
           result.fragmentProfile_ = fragmentProfileBuilder_.build();
         }
+        if (((from_bitField0_ & 0x00000800) == 0x00000800)) {
+          to_bitField0_ |= 0x00000400;
+        }
+        result.user_ = user_;
+        if (((from_bitField0_ & 0x00001000) == 0x00001000)) {
+          to_bitField0_ |= 0x00000800;
+        }
+        result.error_ = error_;
+        if (((from_bitField0_ & 0x00002000) == 0x00002000)) {
+          to_bitField0_ |= 0x00001000;
+        }
+        result.verboseError_ = verboseError_;
+        if (((from_bitField0_ & 0x00004000) == 0x00004000)) {
+          to_bitField0_ |= 0x00002000;
+        }
+        result.errorId_ = errorId_;
+        if (((from_bitField0_ & 0x00008000) == 0x00008000)) {
+          to_bitField0_ |= 0x00004000;
+        }
+        result.errorNode_ = errorNode_;
         result.bitField0_ = to_bitField0_;
         onBuilt();
         return result;
@@ -13977,17 +14362,42 @@ public final class UserBitShared {
             }
           }
         }
-        this.mergeUnknownFields(other.getUnknownFields());
-        return this;
-      }
-
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        if (other.hasUser()) {
+          bitField0_ |= 0x00000800;
+          user_ = other.user_;
+          onChanged();
+        }
+        if (other.hasError()) {
+          bitField0_ |= 0x00001000;
+          error_ = other.error_;
+          onChanged();
+        }
+        if (other.hasVerboseError()) {
+          bitField0_ |= 0x00002000;
+          verboseError_ = other.verboseError_;
+          onChanged();
+        }
+        if (other.hasErrorId()) {
+          bitField0_ |= 0x00004000;
+          errorId_ = other.errorId_;
+          onChanged();
+        }
+        if (other.hasErrorNode()) {
+          bitField0_ |= 0x00008000;
+          errorNode_ = other.errorNode_;
+          onChanged();
+        }
+        this.mergeUnknownFields(other.getUnknownFields());
+        return this;
+      }
+
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
         org.apache.drill.exec.proto.UserBitShared.QueryProfile parsedMessage = null;
         try {
@@ -14830,6 +15240,376 @@ public final class UserBitShared {
         return fragmentProfileBuilder_;
       }
 
+      // optional string user = 12 [default = "-"];
+      private java.lang.Object user_ = "-";
+      /**
+       * <code>optional string user = 12 [default = "-"];</code>
+       */
+      public boolean hasUser() {
+        return ((bitField0_ & 0x00000800) == 0x00000800);
+      }
+      /**
+       * <code>optional string user = 12 [default = "-"];</code>
+       */
+      public java.lang.String getUser() {
+        java.lang.Object ref = user_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          user_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string user = 12 [default = "-"];</code>
+       */
+      public com.google.protobuf.ByteString
+          getUserBytes() {
+        java.lang.Object ref = user_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          user_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string user = 12 [default = "-"];</code>
+       */
+      public Builder setUser(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000800;
+        user_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string user = 12 [default = "-"];</code>
+       */
+      public Builder clearUser() {
+        bitField0_ = (bitField0_ & ~0x00000800);
+        user_ = getDefaultInstance().getUser();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string user = 12 [default = "-"];</code>
+       */
+      public Builder setUserBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00000800;
+        user_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional string error = 13;
+      private java.lang.Object error_ = "";
+      /**
+       * <code>optional string error = 13;</code>
+       */
+      public boolean hasError() {
+        return ((bitField0_ & 0x00001000) == 0x00001000);
+      }
+      /**
+       * <code>optional string error = 13;</code>
+       */
+      public java.lang.String getError() {
+        java.lang.Object ref = error_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          error_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string error = 13;</code>
+       */
+      public com.google.protobuf.ByteString
+          getErrorBytes() {
+        java.lang.Object ref = error_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          error_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string error = 13;</code>
+       */
+      public Builder setError(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00001000;
+        error_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string error = 13;</code>
+       */
+      public Builder clearError() {
+        bitField0_ = (bitField0_ & ~0x00001000);
+        error_ = getDefaultInstance().getError();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string error = 13;</code>
+       */
+      public Builder setErrorBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00001000;
+        error_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional string verboseError = 14;
+      private java.lang.Object verboseError_ = "";
+      /**
+       * <code>optional string verboseError = 14;</code>
+       */
+      public boolean hasVerboseError() {
+        return ((bitField0_ & 0x00002000) == 0x00002000);
+      }
+      /**
+       * <code>optional string verboseError = 14;</code>
+       */
+      public java.lang.String getVerboseError() {
+        java.lang.Object ref = verboseError_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          verboseError_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string verboseError = 14;</code>
+       */
+      public com.google.protobuf.ByteString
+          getVerboseErrorBytes() {
+        java.lang.Object ref = verboseError_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          verboseError_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string verboseError = 14;</code>
+       */
+      public Builder setVerboseError(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00002000;
+        verboseError_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string verboseError = 14;</code>
+       */
+      public Builder clearVerboseError() {
+        bitField0_ = (bitField0_ & ~0x00002000);
+        verboseError_ = getDefaultInstance().getVerboseError();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string verboseError = 14;</code>
+       */
+      public Builder setVerboseErrorBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00002000;
+        verboseError_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional string error_id = 15;
+      private java.lang.Object errorId_ = "";
+      /**
+       * <code>optional string error_id = 15;</code>
+       */
+      public boolean hasErrorId() {
+        return ((bitField0_ & 0x00004000) == 0x00004000);
+      }
+      /**
+       * <code>optional string error_id = 15;</code>
+       */
+      public java.lang.String getErrorId() {
+        java.lang.Object ref = errorId_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          errorId_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string error_id = 15;</code>
+       */
+      public com.google.protobuf.ByteString
+          getErrorIdBytes() {
+        java.lang.Object ref = errorId_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          errorId_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string error_id = 15;</code>
+       */
+      public Builder setErrorId(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00004000;
+        errorId_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string error_id = 15;</code>
+       */
+      public Builder clearErrorId() {
+        bitField0_ = (bitField0_ & ~0x00004000);
+        errorId_ = getDefaultInstance().getErrorId();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string error_id = 15;</code>
+       */
+      public Builder setErrorIdBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00004000;
+        errorId_ = value;
+        onChanged();
+        return this;
+      }
+
+      // optional string error_node = 16;
+      private java.lang.Object errorNode_ = "";
+      /**
+       * <code>optional string error_node = 16;</code>
+       */
+      public boolean hasErrorNode() {
+        return ((bitField0_ & 0x00008000) == 0x00008000);
+      }
+      /**
+       * <code>optional string error_node = 16;</code>
+       */
+      public java.lang.String getErrorNode() {
+        java.lang.Object ref = errorNode_;
+        if (!(ref instanceof java.lang.String)) {
+          java.lang.String s = ((com.google.protobuf.ByteString) ref)
+              .toStringUtf8();
+          errorNode_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>optional string error_node = 16;</code>
+       */
+      public com.google.protobuf.ByteString
+          getErrorNodeBytes() {
+        java.lang.Object ref = errorNode_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          errorNode_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>optional string error_node = 16;</code>
+       */
+      public Builder setErrorNode(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00008000;
+        errorNode_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string error_node = 16;</code>
+       */
+      public Builder clearErrorNode() {
+        bitField0_ = (bitField0_ & ~0x00008000);
+        errorNode_ = getDefaultInstance().getErrorNode();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>optional string error_node = 16;</code>
+       */
+      public Builder setErrorNodeBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  bitField0_ |= 0x00008000;
+        errorNode_ = value;
+        onChanged();
+        return this;
+      }
+
       // @@protoc_insertion_point(builder_scope:exec.shared.QueryProfile)
     }
 
@@ -20109,68 +20889,70 @@ public final class UserBitShared {
       "\022\n\n\006FAILED\020\004\022\032\n\026CANCELLATION_REQUESTED\020\005" +
       "\"p\n\tQueryData\022&\n\010query_id\030\001 \001(\0132\024.exec.s" +
       "hared.QueryId\022\021\n\trow_count\030\002 \001(\005\022(\n\003def\030" +
-      "\003 \001(\0132\033.exec.shared.RecordBatchDef\"\224\001\n\tQ" +
+      "\003 \001(\0132\033.exec.shared.RecordBatchDef\"\227\001\n\tQ" +
       "ueryInfo\022\r\n\005query\030\001 \001(\t\022\r\n\005start\030\002 \001(\003\0222" +
       "\n\005state\030\003 \001(\0162#.exec.shared.QueryResult.",
-      "QueryState\022\014\n\004user\030\004 \001(\t\022\'\n\007foreman\030\005 \001(" +
-      "\0132\026.exec.DrillbitEndpoint\"\336\002\n\014QueryProfi" +
-      "le\022 \n\002id\030\001 \001(\0132\024.exec.shared.QueryId\022$\n\004" +
-      "type\030\002 \001(\0162\026.exec.shared.QueryType\022\r\n\005st" +
-      "art\030\003 \001(\003\022\013\n\003end\030\004 \001(\003\022\r\n\005query\030\005 \001(\t\022\014\n" +
-      "\004plan\030\006 \001(\t\022\'\n\007foreman\030\007 \001(\0132\026.exec.Dril" +
-      "lbitEndpoint\0222\n\005state\030\010 \001(\0162#.exec.share" +
-      "d.QueryResult.QueryState\022\027\n\017total_fragme" +
-      "nts\030\t \001(\005\022\032\n\022finished_fragments\030\n \001(\005\022;\n" +
-      "\020fragment_profile\030\013 \003(\0132!.exec.shared.Ma",
-      "jorFragmentProfile\"t\n\024MajorFragmentProfi" +
-      "le\022\031\n\021major_fragment_id\030\001 \001(\005\022A\n\026minor_f" +
-      "ragment_profile\030\002 \003(\0132!.exec.shared.Mino" +
-      "rFragmentProfile\"\350\002\n\024MinorFragmentProfil" +
-      "e\022)\n\005state\030\001 \001(\0162\032.exec.shared.FragmentS" +
-      "tate\022(\n\005error\030\002 \001(\0132\031.exec.shared.DrillP" +
-      "BError\022\031\n\021minor_fragment_id\030\003 \001(\005\0226\n\020ope" +
-      "rator_profile\030\004 \003(\0132\034.exec.shared.Operat" +
-      "orProfile\022\022\n\nstart_time\030\005 \001(\003\022\020\n\010end_tim" +
-      "e\030\006 \001(\003\022\023\n\013memory_used\030\007 \001(\003\022\027\n\017max_memo",
-      "ry_used\030\010 \001(\003\022(\n\010endpoint\030\t \001(\0132\026.exec.D" +
-      "rillbitEndpoint\022\023\n\013last_update\030\n \001(\003\022\025\n\r" +
-      "last_progress\030\013 \001(\003\"\377\001\n\017OperatorProfile\022" +
-      "1\n\rinput_profile\030\001 \003(\0132\032.exec.shared.Str" +
-      "eamProfile\022\023\n\013operator_id\030\003 \001(\005\022\025\n\ropera" +
-      "tor_type\030\004 \001(\005\022\023\n\013setup_nanos\030\005 \001(\003\022\025\n\rp" +
-      "rocess_nanos\030\006 \001(\003\022#\n\033peak_local_memory_" +
-      "allocated\030\007 \001(\003\022(\n\006metric\030\010 \003(\0132\030.exec.s" +
-      "hared.MetricValue\022\022\n\nwait_nanos\030\t \001(\003\"B\n" +
-      "\rStreamProfile\022\017\n\007records\030\001 \001(\003\022\017\n\007batch",
-      "es\030\002 \001(\003\022\017\n\007schemas\030\003 \001(\003\"J\n\013MetricValue" +
-      "\022\021\n\tmetric_id\030\001 \001(\005\022\022\n\nlong_value\030\002 \001(\003\022" +
-      "\024\n\014double_value\030\003 \001(\001*5\n\nRpcChannel\022\017\n\013B" +
-      "IT_CONTROL\020\000\022\014\n\010BIT_DATA\020\001\022\010\n\004USER\020\002*/\n\t" +
-      "QueryType\022\007\n\003SQL\020\001\022\013\n\007LOGICAL\020\002\022\014\n\010PHYSI" +
-      "CAL\020\003*\207\001\n\rFragmentState\022\013\n\007SENDING\020\000\022\027\n\023" +
-      "AWAITING_ALLOCATION\020\001\022\013\n\007RUNNING\020\002\022\014\n\010FI" +
-      "NISHED\020\003\022\r\n\tCANCELLED\020\004\022\n\n\006FAILED\020\005\022\032\n\026C" +
-      "ANCELLATION_REQUESTED\020\006*\335\005\n\020CoreOperator" +
-      "Type\022\021\n\rSINGLE_SENDER\020\000\022\024\n\020BROADCAST_SEN",
-      "DER\020\001\022\n\n\006FILTER\020\002\022\022\n\016HASH_AGGREGATE\020\003\022\r\n" +
-      "\tHASH_JOIN\020\004\022\016\n\nMERGE_JOIN\020\005\022\031\n\025HASH_PAR" +
-      "TITION_SENDER\020\006\022\t\n\005LIMIT\020\007\022\024\n\020MERGING_RE" +
-      "CEIVER\020\010\022\034\n\030ORDERED_PARTITION_SENDER\020\t\022\013" +
-      "\n\007PROJECT\020\n\022\026\n\022UNORDERED_RECEIVER\020\013\022\020\n\014R" +
-      "ANGE_SENDER\020\014\022\n\n\006SCREEN\020\r\022\034\n\030SELECTION_V" +
-      "ECTOR_REMOVER\020\016\022\027\n\023STREAMING_AGGREGATE\020\017" +
-      "\022\016\n\nTOP_N_SORT\020\020\022\021\n\rEXTERNAL_SORT\020\021\022\t\n\005T" +
-      "RACE\020\022\022\t\n\005UNION\020\023\022\014\n\010OLD_SORT\020\024\022\032\n\026PARQU" +
-      "ET_ROW_GROUP_SCAN\020\025\022\021\n\rHIVE_SUB_SCAN\020\026\022\025",
-      "\n\021SYSTEM_TABLE_SCAN\020\027\022\021\n\rMOCK_SUB_SCAN\020\030" +
-      "\022\022\n\016PARQUET_WRITER\020\031\022\023\n\017DIRECT_SUB_SCAN\020" +
-      "\032\022\017\n\013TEXT_WRITER\020\033\022\021\n\rTEXT_SUB_SCAN\020\034\022\021\n" +
-      "\rJSON_SUB_SCAN\020\035\022\030\n\024INFO_SCHEMA_SUB_SCAN" +
-      "\020\036\022\023\n\017COMPLEX_TO_JSON\020\037\022\025\n\021PRODUCER_CONS" +
-      "UMER\020 \022\022\n\016HBASE_SUB_SCAN\020!\022\n\n\006WINDOW\020\"\022\024" +
-      "\n\020NESTED_LOOP_JOIN\020#\022\021\n\rAVRO_SUB_SCAN\020$B" +
-      ".\n\033org.apache.drill.exec.protoB\rUserBitS" +
-      "haredH\001"
+      "QueryState\022\017\n\004user\030\004 \001(\t:\001-\022\'\n\007foreman\030\005" +
+      " \001(\0132\026.exec.DrillbitEndpoint\"\272\003\n\014QueryPr" +
+      "ofile\022 \n\002id\030\001 \001(\0132\024.exec.shared.QueryId\022" +
+      "$\n\004type\030\002 \001(\0162\026.exec.shared.QueryType\022\r\n" +
+      "\005start\030\003 \001(\003\022\013\n\003end\030\004 \001(\003\022\r\n\005query\030\005 \001(\t" +
+      "\022\014\n\004plan\030\006 \001(\t\022\'\n\007foreman\030\007 \001(\0132\026.exec.D" +
+      "rillbitEndpoint\0222\n\005state\030\010 \001(\0162#.exec.sh" +
+      "ared.QueryResult.QueryState\022\027\n\017total_fra" +
+      "gments\030\t \001(\005\022\032\n\022finished_fragments\030\n \001(\005" +
+      "\022;\n\020fragment_profile\030\013 \003(\0132!.exec.shared",
+      ".MajorFragmentProfile\022\017\n\004user\030\014 \001(\t:\001-\022\r" +
+      "\n\005error\030\r \001(\t\022\024\n\014verboseError\030\016 \001(\t\022\020\n\010e" +
+      "rror_id\030\017 \001(\t\022\022\n\nerror_node\030\020 \001(\t\"t\n\024Maj" +
+      "orFragmentProfile\022\031\n\021major_fragment_id\030\001" +
+      " \001(\005\022A\n\026minor_fragment_profile\030\002 \003(\0132!.e" +
+      "xec.shared.MinorFragmentProfile\"\350\002\n\024Mino" +
+      "rFragmentProfile\022)\n\005state\030\001 \001(\0162\032.exec.s" +
+      "hared.FragmentState\022(\n\005error\030\002 \001(\0132\031.exe" +
+      "c.shared.DrillPBError\022\031\n\021minor_fragment_" +
+      "id\030\003 \001(\005\0226\n\020operator_profile\030\004 \003(\0132\034.exe",
+      "c.shared.OperatorProfile\022\022\n\nstart_time\030\005" +
+      " \001(\003\022\020\n\010end_time\030\006 \001(\003\022\023\n\013memory_used\030\007 " +
+      "\001(\003\022\027\n\017max_memory_used\030\010 \001(\003\022(\n\010endpoint" +
+      "\030\t \001(\0132\026.exec.DrillbitEndpoint\022\023\n\013last_u" +
+      "pdate\030\n \001(\003\022\025\n\rlast_progress\030\013 \001(\003\"\377\001\n\017O" +
+      "peratorProfile\0221\n\rinput_profile\030\001 \003(\0132\032." +
+      "exec.shared.StreamProfile\022\023\n\013operator_id" +
+      "\030\003 \001(\005\022\025\n\roperator_type\030\004 \001(\005\022\023\n\013setup_n" +
+      "anos\030\005 \001(\003\022\025\n\rprocess_nanos\030\006 \001(\003\022#\n\033pea" +
+      "k_local_memory_allocated\030\007 \001(\003\022(\n\006metric",
+      "\030\010 \003(\0132\030.exec.shared.MetricValue\022\022\n\nwait" +
+      "_nanos\030\t \001(\003\"B\n\rStreamProfile\022\017\n\007records" +
+      "\030\001 \001(\003\022\017\n\007batches\030\002 \001(\003\022\017\n\007schemas\030\003 \001(\003" +
+      "\"J\n\013MetricValue\022\021\n\tmetric_id\030\001 \001(\005\022\022\n\nlo" +
+      "ng_value\030\002 \001(\003\022\024\n\014double_value\030\003 \001(\001*5\n\n" +
+      "RpcChannel\022\017\n\013BIT_CONTROL\020\000\022\014\n\010BIT_DATA\020" +
+      "\001\022\010\n\004USER\020\002*/\n\tQueryType\022\007\n\003SQL\020\001\022\013\n\007LOG" +
+      "ICAL\020\002\022\014\n\010PHYSICAL\020\003*\207\001\n\rFragmentState\022\013" +
+      "\n\007SENDING\020\000\022\027\n\023AWAITING_ALLOCATION\020\001\022\013\n\007" +
+      "RUNNING\020\002\022\014\n\010FINISHED\020\003\022\r\n\tCANCELLED\020\004\022\n",
+      "\n\006FAILED\020\005\022\032\n\026CANCELLATION_REQUESTED\020\006*\335" +
+      "\005\n\020CoreOperatorType\022\021\n\rSINGLE_SENDER\020\000\022\024" +
+      "\n\020BROADCAST_SENDER\020\001\022\n\n\006FILTER\020\002\022\022\n\016HASH" +
+      "_AGGREGATE\020\003\022\r\n\tHASH_JOIN\020\004\022\016\n\nMERGE_JOI" +
+      "N\020\005\022\031\n\025HASH_PARTITION_SENDER\020\006\022\t\n\005LIMIT\020" +
+      "\007\022\024\n\020MERGING_RECEIVER\020\010\022\034\n\030ORDERED_PARTI" +
+      "TION_SENDER\020\t\022\013\n\007PROJECT\020\n\022\026\n\022UNORDERED_" +
+      "RECEIVER\020\013\022\020\n\014RANGE_SENDER\020\014\022\n\n\006SCREEN\020\r" +
+      "\022\034\n\030SELECTION_VECTOR_REMOVER\020\016\022\027\n\023STREAM" +
+      "ING_AGGREGATE\020\017\022\016\n\nTOP_N_SORT\020\020\022\021\n\rEXTER",
+      "NAL_SORT\020\021\022\t\n\005TRACE\020\022\022\t\n\005UNION\020\023\022\014\n\010OLD_" +
+      "SORT\020\024\022\032\n\026PARQUET_ROW_GROUP_SCAN\020\025\022\021\n\rHI" +
+      "VE_SUB_SCAN\020\026\022\025\n\021SYSTEM_TABLE_SCAN\020\027\022\021\n\r" +
+      "MOCK_SUB_SCAN\020\030\022\022\n\016PARQUET_WRITER\020\031\022\023\n\017D" +
+      "IRECT_SUB_SCAN\020\032\022\017\n\013TEXT_WRITER\020\033\022\021\n\rTEX" +
+      "T_SUB_SCAN\020\034\022\021\n\rJSON_SUB_SCAN\020\035\022\030\n\024INFO_" +
+      "SCHEMA_SUB_SCAN\020\036\022\023\n\017COMPLEX_TO_JSON\020\037\022\025" +
+      "\n\021PRODUCER_CONSUMER\020 \022\022\n\016HBASE_SUB_SCAN\020" +
+      "!\022\n\n\006WINDOW\020\"\022\024\n\020NESTED_LOOP_JOIN\020#\022\021\n\rA" +
+      "VRO_SUB_SCAN\020$B.\n\033org.apache.drill.exec.",
+      "protoB\rUserBitSharedH\001"
     };
     com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner =
       new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() {
@@ -20260,7 +21042,7 @@ public final class UserBitShared {
           internal_static_exec_shared_QueryProfile_fieldAccessorTable = new
             com.google.protobuf.GeneratedMessage.FieldAccessorTable(
               internal_static_exec_shared_QueryProfile_descriptor,
-              new java.lang.String[] { "Id", "Type", "Start", "End", "Query", "Plan", "Foreman", "State", "TotalFragments", "FinishedFragments", "FragmentProfile", });
+              new java.lang.String[] { "Id", "Type", "Start", "End", "Query", "Plan", "Foreman", "State", "TotalFragments", "FinishedFragments", "FragmentProfile", "User", "Error", "VerboseError", "ErrorId", "ErrorNode", });
           internal_static_exec_shared_MajorFragmentProfile_descriptor =
             getDescriptor().getMessageTypes().get(14);
           internal_static_exec_shared_MajorFragmentProfile_fieldAccessorTable = new

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryInfo.java
----------------------------------------------------------------------
diff --git a/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryInfo.java b/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryInfo.java
index 1c86ae7..4080e26 100644
--- a/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryInfo.java
+++ b/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryInfo.java
@@ -25,6 +25,7 @@ import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 
+import com.dyuproject.protostuff.ByteString;
 import com.dyuproject.protostuff.GraphIOUtil;
 import com.dyuproject.protostuff.Input;
 import com.dyuproject.protostuff.Message;
@@ -46,11 +47,12 @@ public final class QueryInfo implements Externalizable, Message<QueryInfo>, Sche
 
     static final QueryInfo DEFAULT_INSTANCE = new QueryInfo();
 
+    static final String DEFAULT_USER = ByteString.stringDefaultValue("-");
     
     private String query;
     private long start;
     private QueryResult.QueryState state;
-    private String user;
+    private String user = DEFAULT_USER;
     private DrillbitEndpoint foreman;
 
     public QueryInfo()
@@ -213,7 +215,7 @@ public final class QueryInfo implements Externalizable, Message<QueryInfo>, Sche
         if(message.state != null)
              output.writeEnum(3, message.state.number, false);
 
-        if(message.user != null)
+        if(message.user != null && message.user != DEFAULT_USER)
             output.writeString(4, message.user, false);
 
         if(message.foreman != null)

http://git-wip-us.apache.org/repos/asf/drill/blob/42d5f818/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryProfile.java
----------------------------------------------------------------------
diff --git a/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryProfile.java b/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryProfile.java
index 235b6e6..c610a84 100644
--- a/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryProfile.java
+++ b/protocol/src/main/java/org/apache/drill/exec/proto/beans/QueryProfile.java
@@ -27,6 +27,7 @@ import java.io.ObjectOutput;
 import java.util.ArrayList;
 import java.util.List;
 
+import com.dyuproject.protostuff.ByteString;
 import com.dyuproject.protostuff.GraphIOUtil;
 import com.dyuproject.protostuff.Input;
 import com.dyuproject.protostuff.Message;
@@ -48,6 +49,7 @@ public final class QueryProfile implements Externalizable, Message<QueryProfile>
 
     static final QueryProfile DEFAULT_INSTANCE = new QueryProfile();
 
+    static final String DEFAULT_USER = ByteString.stringDefaultValue("-");
     
     private QueryId id;
     private QueryType type;
@@ -60,6 +62,11 @@ public final class QueryProfile implements Externalizable, Message<QueryProfile>
     private int totalFragments;
     private int finishedFragments;
     private List<MajorFragmentProfile> fragmentProfile;
+    private String user = DEFAULT_USER;
+    private String error;
+    private String verboseError;
+    private String errorId;
+    private String errorNode;
 
     public QueryProfile()
     {
@@ -211,6 +218,71 @@ public final class QueryProfile implements Externalizable, Message<QueryProfile>
         return this;
     }
 
+    // user
+
+    public String getUser()
+    {
+        return user;
+    }
+
+    public QueryProfile setUser(String user)
+    {
+        this.user = user;
+        return this;
+    }
+
+    // error
+
+    public String getError()
+    {
+        return error;
+    }
+
+    public QueryProfile setError(String error)
+    {
+        this.error = error;
+        return this;
+    }
+
+    // verboseError
+
+    public String getVerboseError()
+    {
+        return verboseError;
+    }
+
+    public QueryProfile setVerboseError(String verboseError)
+    {
+        this.verboseError = verboseError;
+        return this;
+    }
+
+    // errorId
+
+    public String getErrorId()
+    {
+        return errorId;
+    }
+
+    public QueryProfile setErrorId(String errorId)
+    {
+        this.errorId = errorId;
+        return this;
+    }
+
+    // errorNode
+
+    public String getErrorNode()
+    {
+        return errorNode;
+    }
+
+    public QueryProfile setErrorNode(String errorNode)
+    {
+        this.errorNode = errorNode;
+        return this;
+    }
+
     // java serialization
 
     public void readExternal(ObjectInput in) throws IOException
@@ -303,6 +375,21 @@ public final class QueryProfile implements Externalizable, Message<QueryProfile>
                     message.fragmentProfile.add(input.mergeObject(null, MajorFragmentProfile.getSchema()));
                     break;
 
+                case 12:
+                    message.user = input.readString();
+                    break;
+                case 13:
+                    message.error = input.readString();
+                    break;
+                case 14:
+                    message.verboseError = input.readString();
+                    break;
+                case 15:
+                    message.errorId = input.readString();
+                    break;
+                case 16:
+                    message.errorNode = input.readString();
+                    break;
                 default:
                     input.handleUnknownField(number, this);
             }   
@@ -353,6 +440,21 @@ public final class QueryProfile implements Externalizable, Message<QueryProfile>
             }
         }
 
+
+        if(message.user != null && message.user != DEFAULT_USER)
+            output.writeString(12, message.user, false);
+
+        if(message.error != null)
+            output.writeString(13, message.error, false);
+
+        if(message.verboseError != null)
+            output.writeString(14, message.verboseError, false);
+
+        if(message.errorId != null)
+            output.writeString(15, message.errorId, false);
+
+        if(message.errorNode != null)
+            output.writeString(16, message.errorNode, false);
     }
 
     public String getFieldName(int number)
@@ -370,6 +472,11 @@ public final class QueryProfile implements Externalizable, Message<QueryProfile>
             case 9: return "totalFragments";
             case 10: return "finishedFragments";
             case 11: return "fragmentProfile";
+            case 12: return "user";
+            case 13: return "error";
+            case 14: return "verboseError";
+            case 15: return "errorId";
+            case 16: return "errorNode";
             default: return null;
         }
     }
@@ -394,6 +501,11 @@ public final class QueryProfile implements Externalizable, Message<QueryProfile>
         __fieldMap.put("totalFragments", 9);
         __fieldMap.put("finishedFragments", 10);
         __fieldMap.put("fragmentProfile", 11);
+        __fieldMap.put("user", 12);
+        __fieldMap.put("error", 13);
+        __fieldMap.put("verboseError", 14);
+        __fieldMap.put("errorId", 15);
+        __fieldMap.put("errorNode", 16);
     }
     
 }