You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@accumulo.apache.org by mm...@apache.org on 2018/10/12 17:14:16 UTC

[accumulo] branch master updated: Cleanup Monitor log page (#688)

This is an automated email from the ASF dual-hosted git repository.

mmiller pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/accumulo.git


The following commit(s) were added to refs/heads/master by this push:
     new e946cc2  Cleanup Monitor log page (#688)
e946cc2 is described below

commit e946cc2485b95f0dc45c5ded22c3e3baaf4f7572
Author: Mike Miller <mm...@apache.org>
AuthorDate: Fri Oct 12 13:14:08 2018 -0400

    Cleanup Monitor log page (#688)
    
    * Added stacktrace column and expand button to view whole stacktrace
    * Add string abbrev for warning wrapped errors msgs
---
 .../accumulo/monitor/rest/logs/LogEvent.java       |   5 +-
 .../accumulo/monitor/rest/logs/LogResource.java    |  35 ++++++-----
 .../accumulo/monitor/resources/css/screen.css      |   8 +++
 .../monitor/resources/images/details_close.png     | Bin 0 -> 686 bytes
 .../monitor/resources/images/details_open.png      | Bin 0 -> 709 bytes
 .../org/apache/accumulo/monitor/templates/log.ftl  |  65 +++++++++++++++++++--
 6 files changed, 92 insertions(+), 21 deletions(-)

diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/logs/LogEvent.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/logs/LogEvent.java
index fd56514..6d2a8ec 100644
--- a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/logs/LogEvent.java
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/logs/LogEvent.java
@@ -28,6 +28,7 @@ public class LogEvent {
   public Object application;
   public int count;
   public String level, message;
+  public String[] stacktrace;
 
   public LogEvent() {}
 
@@ -45,11 +46,13 @@ public class LogEvent {
    * @param message
    *          log event message
    */
-  public LogEvent(long timestamp, Object application, int count, String level, String message) {
+  public LogEvent(long timestamp, Object application, int count, String level, String message,
+      String[] stacktrace) {
     this.timestamp = timestamp;
     this.application = application;
     this.count = count;
     this.level = level;
     this.message = message;
+    this.stacktrace = stacktrace;
   }
 }
diff --git a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/logs/LogResource.java b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/logs/LogResource.java
index 68e0ad2..ba0b301 100644
--- a/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/logs/LogResource.java
+++ b/server/monitor/src/main/java/org/apache/accumulo/monitor/rest/logs/LogResource.java
@@ -27,6 +27,7 @@ import javax.ws.rs.core.MediaType;
 
 import org.apache.accumulo.server.monitor.DedupedLogEvent;
 import org.apache.accumulo.server.monitor.LogService;
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.spi.LoggingEvent;
 
 /**
@@ -54,29 +55,31 @@ public class LogResource {
       if (application == null)
         application = "";
       String msg = ev.getMessage().toString();
-      StringBuilder text = new StringBuilder();
-      for (int i = 0; i < msg.length(); i++) {
-        char c = msg.charAt(i);
-        int type = Character.getType(c);
-        boolean notPrintable = type == Character.UNASSIGNED || type == Character.LINE_SEPARATOR
-            || type == Character.NON_SPACING_MARK || type == Character.PRIVATE_USE;
-        text.append(notPrintable ? '?' : c);
-      }
-      StringBuilder builder = new StringBuilder(text.toString());
-      if (ev.getThrowableStrRep() != null)
-        for (String line : ev.getThrowableStrRep())
-          builder.append("\n\t").append(line);
-      msg = sanitize(builder.toString().trim());
+      // truncate if full hadoop errors get logged as a message
+      msg = StringUtils.abbreviate(sanitize(msg), 300);
+
+      String[] stacktrace = ev.getThrowableStrRep();
+      if (stacktrace != null)
+        for (int i = 0; i < stacktrace.length; i++)
+          stacktrace[i] = sanitize(stacktrace[i]);
 
       // Add a new log event to the list
       logEvents.add(new LogEvent(ev.getTimeStamp(), application, dev.getCount(),
-          ev.getLevel().toString(), msg.toString().trim()));
+          ev.getLevel().toString(), msg.trim(), stacktrace));
     }
     return logEvents;
   }
 
-  private String sanitize(String xml) {
-    return xml.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
+  private String sanitize(String s) {
+    StringBuilder text = new StringBuilder();
+    for (int i = 0; i < s.length(); i++) {
+      char c = s.charAt(i);
+      int type = Character.getType(c);
+      boolean notPrintable = type == Character.UNASSIGNED || type == Character.LINE_SEPARATOR
+          || type == Character.NON_SPACING_MARK || type == Character.PRIVATE_USE;
+      text.append(notPrintable ? '?' : c);
+    }
+    return text.toString().replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;");
   }
 
   /**
diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/css/screen.css b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/css/screen.css
index 3612317..f1874e5 100644
--- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/css/screen.css
+++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/css/screen.css
@@ -228,6 +228,14 @@ th.sortable {
   color: blue;
 }
 
+td.details-control {
+    background: url('../images/details_open.png') no-repeat center center;
+    cursor: pointer;
+}
+tr.details td.details-control {
+    background: url('../images/details_close.png') no-repeat center center;
+}
+
 a {
   text-decoration: none;
   color: #0000ff;
diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/images/details_close.png b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/images/details_close.png
new file mode 100644
index 0000000..9c7d698
Binary files /dev/null and b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/images/details_close.png differ
diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/images/details_open.png b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/images/details_open.png
new file mode 100644
index 0000000..c0edf44
Binary files /dev/null and b/server/monitor/src/main/resources/org/apache/accumulo/monitor/resources/images/details_open.png differ
diff --git a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/log.ftl b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/log.ftl
index 4645d0b..c393786 100644
--- a/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/log.ftl
+++ b/server/monitor/src/main/resources/org/apache/accumulo/monitor/templates/log.ftl
@@ -15,7 +15,7 @@
   limitations under the License.
 -->
      <script>
-      var logList;
+        var logList;
         /**
          * Creates DataTables table
          *   - uses ajax call for data source and saves sort state in session
@@ -45,10 +45,66 @@
                   return data;
                 }
               },
-              { "data": "message" }
+              { "data": "message" },
+              {
+                "class":          "details-control",
+                "orderable":      false,
+                "data":           null,
+                "defaultContent": ""
+              }
             ]
           });
-        });
+          // Array to track the ids of the details displayed rows
+          var detailRows = [];
+
+          $("#logTable tbody").on( 'click', 'tr td.details-control', function () {
+            var tr = $(this).closest('tr');
+            var row = logList.row( tr );
+            var idx = $.inArray( tr.attr('id'), detailRows );
+
+            if ( row.child.isShown() ) {
+                tr.removeClass( 'details' );
+                row.child.hide();
+
+                // Remove from the 'open' array
+                detailRows.splice( idx, 1 );
+            }
+            else {
+                tr.addClass( 'details' );
+                row.child( formatStacktrace(row.data().stacktrace) ).show();
+
+                // Add to the 'open' array
+                if ( idx === -1 ) {
+                    detailRows.push( tr.attr('id') );
+                }
+            }
+          });
+
+          logList.on( 'draw', function () {
+              // remove the details button for rows without a stacktrace
+              $("#logTable tr").each(function( i, element) {
+                var r = logList.row(element).data();
+                if (r && r.stacktrace == null) {
+                  var c = $(element).find('td:last-child');
+                  c.removeClass('details-control');
+                }
+              });
+              // On each draw, loop over the `detailRows` array and show any child rows
+              $.each( detailRows, function ( i, id ) {
+                  $('#'+id+' td.details-control').trigger( 'click' );
+              });
+          });
+        }); // end document ready
+
+        // format stacktrace
+        function formatStacktrace(d) {
+          var str = new String("<pre>");
+          $.each(d, function( index, value ) {
+            str = str + value + "<br>";
+          });
+          str = str + "</pre>";
+          return str;
+        }
 
         /**
          * Used to refresh the table
@@ -65,7 +121,8 @@
               <th>Application</th>
               <th>Count</th>
               <th>Level</th>
-              <th class="logevent">Message</th></tr>
+              <th class="logevent">Message</th>
+              <th>Stacktrace</th></tr>
             </thead>
             <tbody></tbody>
         </table>