Repository: qpid-dispatch
Updated Branches:
  refs/heads/master 4742c4bfd -> cab2f5da6


DISPATCH-1216: Scraper reports all AMQP addresses during --split


Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/cab2f5da
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/cab2f5da
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/cab2f5da

Branch: refs/heads/master
Commit: cab2f5da63406086f98df41c3c5e18948f3c5c46
Parents: 4742c4b
Author: Chuck Rolke <[email protected]>
Authored: Wed Dec 12 17:25:46 2018 -0500
Committer: Chuck Rolke <[email protected]>
Committed: Wed Dec 12 17:25:46 2018 -0500

----------------------------------------------------------------------
 tools/scraper/README.md       |   2 +
 tools/scraper/log_splitter.py | 165 +++++++++++++++++++++++++++++++++----
 tools/scraper/nicknamer.py    |   3 +
 tools/scraper/parser.py       |   3 +-
 4 files changed, 156 insertions(+), 17 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cab2f5da/tools/scraper/README.md
----------------------------------------------------------------------
diff --git a/tools/scraper/README.md b/tools/scraper/README.md
index 76605d2..8461575 100644
--- a/tools/scraper/README.md
+++ b/tools/scraper/README.md
@@ -153,6 +153,8 @@ and divides the connection data. Connection names inclued 
the router instance ID
   * Total log line count
   * Connections with zero transfers
 * Per-connection files are linked from the connection lists for one-click 
viewing
+* AMQP Addresses from every every AMQP Attach are indexed. A table for each 
address
+  shows when the address was referenced and some connection details.
 
 ## Quick Start
 

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cab2f5da/tools/scraper/log_splitter.py
----------------------------------------------------------------------
diff --git a/tools/scraper/log_splitter.py b/tools/scraper/log_splitter.py
index cc5664e..0a77182 100755
--- a/tools/scraper/log_splitter.py
+++ b/tools/scraper/log_splitter.py
@@ -35,6 +35,9 @@ import sys
 import traceback
 from collections import defaultdict
 
+import common
+import parser
+import text
 
 class connection():
     def __init__(self, instance, conn_id, logfile):
@@ -42,6 +45,7 @@ class connection():
         self.conn_id = conn_id
         self.logfile = logfile
         self.lines = []
+        self.attaches = []
         self.key_name = connection.keyname(instance, conn_id)
         self.transfers = 0
         self.peer_open = ""
@@ -77,6 +81,7 @@ class LogFile:
         self.instance = 0   # incremented when router restarts in log file
         self.amqp_lines = 0 # server trace lines
         self.transfers = 0  # server transfers
+        self.attaches = 0   # server attach
 
         # restarts
         self.restarts = []
@@ -138,6 +143,7 @@ class LogFile:
         key_error = "@error(29)"
         key_openin = "<- @open(16)"
         key_xfer = "@transfer"
+        key_attach = "@attach"
         key_prod_dispatch = ':product="qpid-dispatch-router"'
         key_prod_aartemis = ':product="apache-activemq-artemis"'
         key_prod_aqpidcpp = ':product="qpid-cpp"'
@@ -173,6 +179,9 @@ class LogFile:
                                 self.broker_connections.append(curr_conn)
                                 curr_conn.peer_open = line
                                 curr_conn.peer_type = k
+                elif key_attach in line:
+                    self.attaches += 1
+                    curr_conn.attaches.append(line)
                 elif self.parse_identify(key_xfer, line):
                     self.transfers += 1
                     curr_conn.transfers += 1
@@ -222,24 +231,61 @@ class LogFile:
 
         # Write the web doc to stdout
         print ("""<!DOCTYPE html>
-        <html>
-        <head>
-        <title>%s qpid-dispatch log split</title>
-
-        <style>
-            * { 
-            font-family: sans-serif; 
-        }
-        table {
-            border-collapse: collapse;
-        }
-        table, td, th {
-            border: 1px solid black;
-            padding: 3px;
-        }
-        </style>
+<html>
+<head>
+<title>%s qpid-dispatch log split</title>
+
+<style>
+    * { 
+    font-family: sans-serif; 
+}
+table {
+    border-collapse: collapse;
+}
+table, td, th {
+    border: 1px solid black;
+    padding: 3px;
+}
+</style>
+<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js"; 
type="text/javascript"></script>
+<!-- <script 
src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js"; 
type="text/javascript"></script> -->
+<script type="text/javascript">
+function node_is_visible(node)
+{
+  if(dojo.isString(node))
+    node = dojo.byId(node);
+  if(!node) 
+    return false;
+  return node.style.display == "block";
+}
+function set_node(node, str)
+{
+  if(dojo.isString(node))
+    node = dojo.byId(node);
+  if(!node) return;
+  node.style.display = str;
+}
+function toggle_node(node)
+{
+  if(dojo.isString(node))
+    node = dojo.byId(node);
+  if(!node) return;
+  set_node(node, (node_is_visible(node)) ? 'none' : 'block');
+}
+function hide_node(node)
+{
+  set_node(node, 'none');
+}
+function show_node(node)
+{
+  set_node(node, 'block');
+}
+
 """ % self.log_fn)
 
+        print("</script>")
+        print("</head>")
+        print("<body>")
         print("""
 <h3>Contents</h3>
 <table>
@@ -252,6 +298,7 @@ class LogFile:
 <tr><td><a href=\"#c_conn_xfersize\"  >Conn by N transfers</a></td>       
<td>Connections sorted by transfer log count</td></tr>
 <tr><td><a href=\"#c_conn_xfer0\"     >Conn with no transfers</a></td>    
<td>Connections with no transfers</td></tr>
 <tr><td><a href=\"#c_conn_logsize\"   >Conn by N log lines</a></td>       
<td>Connections sorted by total log line count</td></tr>
+<tr><td><a href=\"#c_addresses\"      >Addresses</a></td>                 
<td>AMQP address usage</td></tr>
 </table>
 <hr>
 """)
@@ -265,6 +312,7 @@ class LogFile:
         print("<tr><td>AMQP log lines</td>     <td>%s</td></tr>" % 
str(self.amqp_lines))
         print("<tr><td>AMQP errors</td>        <td>%s</td></tr>" % 
str(len(self.errors)))
         print("<tr><td>AMQP transfers</td>     <td>%s</td></tr>" % 
str(self.transfers))
+        print("<tr><td>AMQP attaches</td>     <td>%s</td></tr>" % 
str(self.attaches))
         print("</table>")
         print("<hr>")
 
@@ -386,6 +434,90 @@ class LogFile:
         print("</table>")
         print("<hr>")
 
+    def aggregate_addresses(self):
+        class dummy_args():
+            skip_all_data = False
+            skip_detail = False
+            skip_msg_progress = False
+            split = False
+            time_start = None
+            time_end = None
+
+        comn = common.Common()
+        comn.args = dummy_args
+
+        print("<a name=\"c_addresses\"></a>")
+
+        # Aggregate link source/target addresses where the names are 
referenced in the attach:
+        #  observe source and target addresses regardless of the role of the 
link
+        # TODO speed this up a little
+        nn2 = defaultdict(list)
+        for k, conn in dict_iteritems(self.connections):
+            for aline in conn.attaches:
+                try:
+                    pl = parser.ParsedLogLine(0, conn.instance, 0, aline, 
comn, None, k)
+                except Exception as e:
+                    # t, v, tb = sys.exc_info()
+                    if hasattr(e, 'message'):
+                        sys.stderr.write("Failed to parse %s. Analysis 
continuing...\n" % (e.message))
+                    else:
+                        sys.stderr.write("Failed to parse %s. Analysis 
continuing...\n" % (e))
+                if pl is not None:
+                    nn2[pl.data.source].append(pl)
+                    if pl.data.source != pl.data.target:
+                        nn2[pl.data.target].append(pl)
+
+        print("<h3>Verbose AMQP Addresses Overview (N=%d)</h3>" % len(nn2))
+        showthis = ("<a 
href=\"javascript:toggle_node('addr_table_2')\">%s</a>" %
+                    (text.lozenge()))
+        print(" %s This table shows addresses that referenced in Attach 
performatives. <br>" % showthis)
+        print("<div id=\"addr_table_2\" style=\"display:none; margin-top: 2px; 
margin-bottom: 2px; margin-left: 10px\">")
+        addr_many = []
+        addr_few = []
+        ADDR_LEVEL = 4
+        n = 0
+        for k, plfs in dict_iteritems(nn2):
+            showthis = ("<a 
href=\"javascript:toggle_node('@@addr2_%d')\">%s</a>" %
+                        (n, text.lozenge()))
+            visitthis = ("<a href=\"#@@addr2_%d_data\">%s</a>" %
+                         (n, k))
+            line = ("<tr><td>%s %s</td> <td>%d</td> </tr>" %
+                  (showthis, visitthis, len(plfs)))
+            if len(plfs) <= ADDR_LEVEL:
+                addr_few.append(line)
+            else:
+                addr_many.append(line)
+            n += 1
+        print("<h4>Addresses with many links (N=%d)</h4>" % (len(addr_many)))
+        print("<table><tr> <th>Address</th> <th>N References</th> </tr>")
+        for line in addr_many: print(line)
+        print("</table>")
+
+        print("<h4>Addresses with few links (N=%d)</h4>" % (len(addr_few)))
+        print("<table><tr> <th>Address</th> <th>N References</th> </tr>")
+        for line in addr_few: print(line)
+        print("</table>")
+
+        # loop to print expandable sub tables
+        print("<h3>AMQP Addresses Details</h3>")
+        n = 0
+        for k, plfss in dict_iteritems(nn2):
+            plfs = sorted(plfss, key=lambda lfl: lfl.datetime)
+            print("<div id=\"@@addr2_%d\" style=\"display:none; margin-top: 
2px; margin-bottom: 2px; margin-left: 10px\">" %
+                  (n))
+            print("<a name=\"@@addr2_%d_data\"></a>" % (n))
+            print("<h4>Address %s</h4>" % (k))
+            print("<table><tr><th>Time</th> <th>Connection</th> <th>Dir</th> 
<th>Peer</th> <th>Role</th> <th>Source</th> <th>Target</th> </tr>")
+            for plf in plfs:
+                print("<tr><td>%s</td> <td>%s</td> <td>%s</td> <td>%s</td> 
<td>%s</td> <td>%s</td> <td>%s</td> </tr>" %
+                      (plf.datetime, plf.data.conn_id,
+                       plf.data.direction, 
self.connections[plf.opaque].peer_type,
+                       plf.data.role, plf.data.source, plf.data.target))
+            print("</table>")
+            print("</div>")
+            n += 1
+        print("</div>")
+
 
 # py 2-3 compat
 
@@ -428,6 +560,7 @@ def main_except(log_fn):
     for lf in log_files:
         lf.summarize_connections() # prints web page to console
         lf.write_subfiles()        # generates split files one-per-connection
+        lf.aggregate_addresses()   # print address table html to console
     pass
 
 def main(argv):

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cab2f5da/tools/scraper/nicknamer.py
----------------------------------------------------------------------
diff --git a/tools/scraper/nicknamer.py b/tools/scraper/nicknamer.py
index f198270..df0f9a0 100755
--- a/tools/scraper/nicknamer.py
+++ b/tools/scraper/nicknamer.py
@@ -126,6 +126,9 @@ class ShortNames():
     def customers(self, sname):
         return self.customer_dict[sname]
 
+    def sorted_indexes(self):
+        return [self.longnames.index(sln) for sln in sorted(self.longnames)]
+
 class Shorteners():
     def __init__(self):
         self.short_link_names = ShortNames("link", 15)

http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/cab2f5da/tools/scraper/parser.py
----------------------------------------------------------------------
diff --git a/tools/scraper/parser.py b/tools/scraper/parser.py
index 382bf3c..67eb0c8 100755
--- a/tools/scraper/parser.py
+++ b/tools/scraper/parser.py
@@ -720,7 +720,7 @@ class ParsedLogLine(object):
         return "<a href=\"#%s\">%s</a>" % (self.fid, "%s%d_%s" %
                                            (common.log_letter_of(self.index), 
self.instance, str(self.lineno)))
 
-    def __init__(self, _log_index, _instance, _lineno, _line, _comn, _router):
+    def __init__(self, _log_index, _instance, _lineno, _line, _comn, _router, 
opaque):
         """
         Process a naked qpid-dispatch log line
         A log line looks like this:
@@ -758,6 +758,7 @@ class ParsedLogLine(object):
         self.lineno = _lineno  # log line number
         self.comn = _comn
         self.router = _router
+        self.opaque = opaque
         self.prefixi = common.log_letter_of(self.index) + str(self.instance)  
# prefix+instance A0
         self.fid = "f_" + self.prefixi + "_" + str(self.lineno)  # frame id 
A0_100
         self.shorteners = _comn.shorteners  # name shorteners


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to