You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ch...@apache.org on 2018/12/05 19:11:15 UTC
qpid-dispatch git commit: DISPATCH-1210: Find and show unsettled
messages; improve large dataset display controls
Repository: qpid-dispatch
Updated Branches:
refs/heads/master 588a35db0 -> 53631c8d0
DISPATCH-1210: Find and show unsettled messages; improve large dataset display controls
Project: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/commit/53631c8d
Tree: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/tree/53631c8d
Diff: http://git-wip-us.apache.org/repos/asf/qpid-dispatch/diff/53631c8d
Branch: refs/heads/master
Commit: 53631c8d0321d36a7eb6ed2439ac96356b8a8be3
Parents: 588a35d
Author: Chuck Rolke <cr...@redhat.com>
Authored: Wed Dec 5 14:11:03 2018 -0500
Committer: Chuck Rolke <cr...@redhat.com>
Committed: Wed Dec 5 14:11:03 2018 -0500
----------------------------------------------------------------------
tools/scraper/README.md | 21 +++++++++++++++++++--
tools/scraper/amqp_detail.py | 26 ++++++++++++++++----------
tools/scraper/parser.py | 3 +++
tools/scraper/scraper.py | 28 ++++++++++++++++++++++++++++
tools/scraper/text.py | 1 +
5 files changed, 67 insertions(+), 12 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/53631c8d/tools/scraper/README.md
----------------------------------------------------------------------
diff --git a/tools/scraper/README.md b/tools/scraper/README.md
index 6c59a0d..afde3bf 100644
--- a/tools/scraper/README.md
+++ b/tools/scraper/README.md
@@ -58,7 +58,19 @@ From each log file Scraper extracts:
* Connection data lists are searched to discover router-to-router and router-to-client
connection pairs.
* Per connection data are subdivided into per-session and per-link lists, sorting
- the AMQP data into per-link-only views.
+ the AMQP data into per-link-only views. This information is shown in the _Connection
+ Details_ section. Clicking on the lozenge will expand a connection into a view that
+ shows all the sessions. Clicking on a session lozenge will expand into a view that
+ shows all the links.
+
+ Each link shows a lozenge that will toggle the link data visibility and a hyperlink
+ that will go to the link data. When the table of links is small and visible on one
+ screen then it's easy to see what's going on. But when the table of links is large,
+ say 2000 links, then the data for each link is 2000 lines later in the web page.
+ When you click the lozenge you don't see the data. For larger data sets the usage
+ rule is to first click the lozenge to expose the data, and then click the hyperlink
+ go make the data visible.
+
* Bulk AMQP data may be shown or hidden on arbitrary per-connection selections.
* Noteworthy AMQP frames are identified. By hand these are hard to find.
* AMQP errors
@@ -67,9 +79,14 @@ From each log file Scraper extracts:
* Resumed transfers
* Aborted transfers
* Flow with 'drain' set
+ * Probable unsettled transfers.
+ * Possible unsettled transfers. When log files are truncated and not all log lines
+ for this connection, session, and link are present then settlement calculations
+ are compromised. Transfers may appear to be unsettled but the settlement could
+ not be correlated properly with the transfer.
* Transfer messages are sorted by signature. Then a table is made showing where
each message leaves or arrives over a connection. The signature is limited to the
- body of the message as shown in the Proton log text.
+ body of the message as shown in the Qpid Proton log text.
* Settlement state for each unsettled transfer is identified, displayed, and
shown with delta and elapsed time values. See example in the Advanced section.
* Link name propagation for each named link is shown in a table.
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/53631c8d/tools/scraper/amqp_detail.py
----------------------------------------------------------------------
diff --git a/tools/scraper/amqp_detail.py b/tools/scraper/amqp_detail.py
index 72da87f..fd64234 100755
--- a/tools/scraper/amqp_detail.py
+++ b/tools/scraper/amqp_detail.py
@@ -385,21 +385,21 @@ class AllDetails():
"connid:%s, line:%s\n" %
(snd_disposition.data.conn_id, snd_disposition.lineno))
else:
- result = "rcvr: absent"
+ result = "receive settlement absent"
else:
# two settlements expected
if rcv_disposition is not None:
- result = "rcvr: " + rtext
+ result = "receiver: " + rtext
if snd_disposition is not None:
- result += ", sndr: " + stext
+ result += ", sender: " + stext
else:
- result += ", sndr: absent"
+ result += ", sender settlement absent"
else:
- result = "rcvr: absent"
+ result = "receiver settlement absent"
if snd_disposition is not None:
- result += ", sndr: " + stext
+ result += ", sender: " + stext
else:
- result += ", sndr: absent"
+ result += ", sender settlement absent"
return result
def __init__(self, _router, _common):
@@ -513,11 +513,13 @@ class AllDetails():
ns = conn_details.FindSession(channel)
if ns is None:
conn_details.unaccounted_frame_list.append(plf)
+ plf.no_parent_link = True
continue
handle = plf.data.handle
nl = ns.FindLinkByHandle(handle, plf.data.direction_is_in())
if nl is None:
ns.session_frame_list.append(plf)
+ plf.no_parent_link = True
else:
if plf.data.amqp_error:
nl.amqp_errors += 1
@@ -572,7 +574,7 @@ class AllDetails():
# loop to print session details
for sess in conn_detail.session_list:
- # show the session toggle and title
+ # show the session 'toggle goto' and title
print("<a href=\"javascript:toggle_node('%s_sess_%s')\">%s%s</a>" %
(id, sess.conn_epoch, text.lozenge(), text.nbsp()))
print("Session %s: channel: %s, peer channel: %s; Time: start %s, Counts: frames: %d %s<br>" % \
@@ -599,11 +601,13 @@ class AllDetails():
for link in sess.link_list:
# show the link toggle and title
showthis = ("<a href=\"javascript:toggle_node('%s_sess_%s_link_%s')\">%s</a>" %
+ (id, sess.conn_epoch, link.session_seq, text.lozenge()))
+ visitthis = ("<a href=\"#%s_sess_%s_link_%s_data\">%s</a>" %
(id, sess.conn_epoch, link.session_seq, link.display_name))
role = "receiver" if link.is_receiver else "sender"
- print("<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>"
+ print("<tr><td>%s %s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td>"
"<td>%s</td><td>%d</td><td>%s</td></tr>" % \
- (showthis, link.direction, role, link.first_address,
+ (showthis, visitthis, link.direction, role, link.first_address,
(link.sender_class + '-' + link.receiver_class), link.snd_settle_mode,
link.rcv_settle_mode, link.time_start, link.FrameCount(),
self.format_errors(link.amqp_errors)))
@@ -613,6 +617,8 @@ class AllDetails():
print(
"<div id=\"%s_sess_%s_link_%s\" style=\"display:none; margin-top: 2px; margin-bottom: 2px; margin-left: 10px\">" %
(id, sess.conn_epoch, link.session_seq))
+ print("<a name=\"%s_sess_%s_link_%s_data\"></a>" %
+ (id, sess.conn_epoch, link.session_seq))
print("<h4>Connection %s Session %s Link %s</h4>" %
(id, sess.conn_epoch, link.display_name))
for plf in link.frame_list:
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/53631c8d/tools/scraper/parser.py
----------------------------------------------------------------------
diff --git a/tools/scraper/parser.py b/tools/scraper/parser.py
index 518be95..d33a0c7 100755
--- a/tools/scraper/parser.py
+++ b/tools/scraper/parser.py
@@ -127,6 +127,7 @@ class LogLineData:
self.disposition_state = "?absent?"
self.snd_settle_mode = "" # Attach
self.rcv_settle_mode = "" # Attach
+ self.transfer = False
self.transfer_data = "" # protonized transfer data value
self.transfer_bare = "" # bare message from transfer_data
self.transfer_hdr_annos = "" # header and annotation sections
@@ -146,6 +147,7 @@ class LogLineData:
self.link_class = "normal" # attach sees: normal, router, router-data (, management?)
self.disposition_display = ""
self.final_disposition = None
+ self.no_parent_link = False
class DescribedType:
@@ -486,6 +488,7 @@ class ParsedLogLine(object):
elif perf == 0x14:
# Performative: transfer [channel,handle] (id)
res.name = "transfer"
+ res.transfer = True
res.handle = resdict["handle"]
res.channel_handle = "[%s,%s]" % (res.channel, res.handle)
res.delivery_id = self.resdict_value(resdict, "delivery-id", "none")
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/53631c8d/tools/scraper/scraper.py
----------------------------------------------------------------------
diff --git a/tools/scraper/scraper.py b/tools/scraper/scraper.py
index 6536ac8..2e998b1 100755
--- a/tools/scraper/scraper.py
+++ b/tools/scraper/scraper.py
@@ -392,6 +392,7 @@ def main_except(argv):
(tConn, tLines, tLinks, tBytes, tErrs))
print("</table>")
+ print("<a name=\"c_connectchrono\"></a>")
print("<h3>Router Restart and Connection chronology</h3>")
cl = []
@@ -454,6 +455,8 @@ def main_except(argv):
n_resume = 0
n_aborted = 0
n_drain = 0
+ n_unsettled = 0
+ n_unsettled_no_parent = 0 # without link/session can't match xfers with dispositions
for plf in tree:
if plf.data.amqp_error:
n_errors += 1
@@ -467,6 +470,11 @@ def main_except(argv):
n_aborted += 1
if plf.data.flow_drain:
n_drain += 1
+ if plf.data.transfer and not (plf.data.transfer_settled or plf.data.final_disposition is not None):
+ if plf.data.no_parent_link:
+ n_unsettled_no_parent += 1 # possibly unsettled
+ else:
+ n_unsettled += 1 # probably unsettled
# amqp errors
print("<a href=\"javascript:toggle_node('noteworthy_errors')\">%s%s</a> AMQP errors: %d<br>" %
(text.lozenge(), text.nbsp(), n_errors))
@@ -527,6 +535,26 @@ def main_except(argv):
if plf.data.flow_drain:
show_noteworthy_line(plf, comn)
print("</div>")
+ # probable unsettled transfers
+ print("<a href=\"javascript:toggle_node('noteworthy_unsettled')\">%s%s</a> Probable unsettled transfers: %d<br>" %
+ (text.lozenge(), text.nbsp(), n_unsettled))
+ print(" <div width=\"100%%\"; "
+ "style=\"display:none; font-weight: normal; margin-bottom: 2px; margin-left: 10px\" "
+ "id=\"noteworthy_unsettled\">")
+ for plf in tree:
+ if plf.data.transfer and not (plf.data.transfer_settled or plf.data.final_disposition is not None) and not plf.data.no_parent_link:
+ show_noteworthy_line(plf, comn)
+ print("</div>")
+ # possible unsettled transfers
+ print("<a href=\"javascript:toggle_node('noteworthy_unsettled_qm')\">%s%s</a> Possible unsettled transfers: %d<br>" %
+ (text.lozenge(), text.nbsp(), n_unsettled_no_parent))
+ print(" <div width=\"100%%\"; "
+ "style=\"display:none; font-weight: normal; margin-bottom: 2px; margin-left: 10px\" "
+ "id=\"noteworthy_unsettled_qm\">")
+ for plf in tree:
+ if plf.data.transfer and not (plf.data.transfer_settled or plf.data.final_disposition is not None) and plf.data.no_parent_link:
+ show_noteworthy_line(plf, comn)
+ print("</div>")
print("<hr>")
# the proton log lines
http://git-wip-us.apache.org/repos/asf/qpid-dispatch/blob/53631c8d/tools/scraper/text.py
----------------------------------------------------------------------
diff --git a/tools/scraper/text.py b/tools/scraper/text.py
index ba6a1f8..da05221 100755
--- a/tools/scraper/text.py
+++ b/tools/scraper/text.py
@@ -118,6 +118,7 @@ def web_page_toc():
<tr><td><a href=\"#c_logfiles\" >Log files</a></td> <td>Router and log file info</td></tr>
<tr><td><a href=\"#c_rtrinstances\" >Router Instances</a></td> <td>Router reboot chronology</td></tr>
<tr><td><a href=\"#c_connections\" >Connections</a></td> <td>Connection overview; per connection log data view control</td></tr>
+<tr><td><a href=\"#c_connectchrono\" >Connection Chronology</a></td> <td>Router restart and connection chronology</td></tr>
<tr><td><a href=\"#c_conndetails\" >Connection Details</a></td> <td>Connection details; frames sorted by link</td></tr>
<tr><td><a href=\"#c_noteworthy\" >Noteworthy log lines</a></td> <td>AMQP errors and interesting flags</td></tr>
<tr><td><a href=\"#c_logdata\" >Log data</a></td> <td>Main AMQP traffic table</td></tr>
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org