diff mbox

[nfs-utils,v3,06/17] mountstats: Make ms-iostat output match that of nfs-iostat.py

Message ID 1418068645-10134-7-git-send-email-smayhew@redhat.com (mailing list archive)
State New, archived
Headers show

Commit Message

Scott Mayhew Dec. 8, 2014, 7:57 p.m. UTC
Changes mostly lifted straight from nfs-iostat.py.

Signed-off-by: Scott Mayhew <smayhew@redhat.com>
---
 tools/mountstats/mountstats.py | 104 ++++++++++++++++++++++++-----------------
 1 file changed, 61 insertions(+), 43 deletions(-)
diff mbox

Patch

diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
index 384af99..ee68b24 100644
--- a/tools/mountstats/mountstats.py
+++ b/tools/mountstats/mountstats.py
@@ -457,60 +457,78 @@  class DeviceData:
             result.__nfs_data[key] -= old_stats.__nfs_data[key]
         return result
 
+    def __print_rpc_op_stats(self, op, sample_time):
+        """Print generic stats for one RPC op
+        """
+        if op not in self.__rpc_data:
+            return
+
+        rpc_stats = self.__rpc_data[op]
+        ops = float(rpc_stats[0])
+        retrans = float(rpc_stats[1] - rpc_stats[0])
+        kilobytes = float(rpc_stats[3] + rpc_stats[4]) / 1024
+        rtt = float(rpc_stats[6])
+        exe = float(rpc_stats[7])
+
+        # prevent floating point exceptions
+        if ops != 0:
+            kb_per_op = kilobytes / ops
+            retrans_percent = (retrans * 100) / ops
+            rtt_per_op = rtt / ops
+            exe_per_op = exe / ops
+        else:
+            kb_per_op = 0.0
+            retrans_percent = 0.0
+            rtt_per_op = 0.0
+            exe_per_op = 0.0
+
+        op += ':'
+        print(format(op.lower(), '<16s'), end='')
+        print(format('ops/s', '>8s'), end='')
+        print(format('kB/s', '>16s'), end='')
+        print(format('kB/op', '>16s'), end='')
+        print(format('retrans', '>16s'), end='')
+        print(format('avg RTT (ms)', '>16s'), end='')
+        print(format('avg exe (ms)', '>16s'))
+
+        print(format((ops / sample_time), '>24.3f'), end='')
+        print(format((kilobytes / sample_time), '>16.3f'), end='')
+        print(format(kb_per_op, '>16.3f'), end='')
+        retransmits = '{0:>10.0f} ({1:>3.1f}%)'.format(retrans, retrans_percent).strip()
+        print(format(retransmits, '>16'), end='')
+        print(format(rtt_per_op, '>16.3f'), end='')
+        print(format(exe_per_op, '>16.3f'))
+
     def display_iostats(self, sample_time):
         """Display NFS and RPC stats in an iostat-like way
         """
         sends = float(self.__rpc_data['rpcsends'])
         if sample_time == 0:
             sample_time = float(self.__nfs_data['age'])
+        #  sample_time could still be zero if the export was just mounted.
+        #  Set it to 1 to avoid divide by zero errors in this case since we'll
+        #  likely still have relevant mount statistics to show.
+        #
+        if sample_time == 0:
+            sample_time = 1;
+        if sends != 0:
+            backlog = (float(self.__rpc_data['backlogutil']) / sends) / sample_time
+        else:
+            backlog = 0.0
 
         print()
         print('%s mounted on %s:' % \
             (self.__nfs_data['export'], self.__nfs_data['mountpoint']))
+        print()
 
-        print('\top/s\trpc bklog')
-        print('\t%.2f' % (sends / sample_time), end=' ')
-        if sends != 0:
-            print('\t%.2f' % \
-                ((float(self.__rpc_data['backlogutil']) / sends) / sample_time))
-        else:
-            print('\t0.00')
-
-        # reads:  ops/s, kB/s, avg rtt, and avg exe
-        # XXX: include avg xfer size and retransmits?
-        read_rpc_stats = self.__rpc_data['READ']
-        ops = float(read_rpc_stats[0])
-        kilobytes = float(self.__nfs_data['serverreadbytes']) / 1024
-        rtt = float(read_rpc_stats[6])
-        exe = float(read_rpc_stats[7])
-
-        print('\treads:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)')
-        print('\t\t%.2f' % (ops / sample_time), end=' ')
-        print('\t\t%.2f' % (kilobytes / sample_time), end=' ')
-        if ops != 0:
-            print('\t\t%.2f' % (rtt / ops), end=' ')
-            print('\t\t%.2f' % (exe / ops))
-        else:
-            print('\t\t0.00', end=' ')
-            print('\t\t0.00')
-
-        # writes:  ops/s, kB/s, avg rtt, and avg exe
-        # XXX: include avg xfer size and retransmits?
-        write_rpc_stats = self.__rpc_data['WRITE']
-        ops = float(write_rpc_stats[0])
-        kilobytes = float(self.__nfs_data['serverwritebytes']) / 1024
-        rtt = float(write_rpc_stats[6])
-        exe = float(write_rpc_stats[7])
-
-        print('\twrites:\tops/s\t\tkB/s\t\tavg RTT (ms)\tavg exe (ms)')
-        print('\t\t%.2f' % (ops / sample_time), end=' ')
-        print('\t\t%.2f' % (kilobytes / sample_time), end=' ')
-        if ops != 0:
-            print('\t\t%.2f' % (rtt / ops), end=' ')
-            print('\t\t%.2f' % (exe / ops))
-        else:
-            print('\t\t0.00', end=' ')
-            print('\t\t0.00')
+        print(format('ops/s', '>16') + format('rpc bklog', '>16'))
+        print(format((sends / sample_time), '>16.3f'), end='')
+        print(format(backlog, '>16.3f'))
+        print()
+
+        self.__print_rpc_op_stats('READ', sample_time)
+        self.__print_rpc_op_stats('WRITE', sample_time)
+        sys.stdout.flush()
 
 def parse_stats_file(filename):
     """pop the contents of a mountstats file into a dictionary,