add print_log2_hist() from #143
authorBrendan Gregg <brendan.d.gregg@gmail.com>
Mon, 7 Sep 2015 21:34:22 +0000 (14:34 -0700)
committerBrendan Gregg <brendan.d.gregg@gmail.com>
Mon, 7 Sep 2015 21:34:22 +0000 (14:34 -0700)
examples/bitehist.py
examples/vfsreadlat.py
src/python/bcc/__init__.py

index 9bcfb5d..7ad64dc 100755 (executable)
@@ -16,7 +16,6 @@
 # 15-Aug-2015  Brendan Gregg   Created this.
 
 from bcc import BPF
-from ctypes import c_ushort, c_int, c_ulonglong
 from time import sleep
 from sys import argv
 
@@ -40,51 +39,10 @@ if len(argv) > 1:
 # load BPF program
 b = BPF(src_file = "bitehist.c")
 b.attach_kprobe(event="blk_start_request", fn_name="do_request")
-dist_max = 64
 
 # header
 print("Tracing... Hit Ctrl-C to end.")
 
-# functions
-stars_max = 38
-def stars(val, val_max, width):
-       i = 0
-       text = ""
-       while (1):
-               if (i > (width * val / val_max) - 1) or (i > width - 1):
-                       break
-               text += "*"
-               i += 1
-       if val > val_max:
-               text = text[:-1] + "+"
-       return text
-
-def print_log2_hist(dist, val_type):
-       idx_max = -1
-       val_max = 0
-       for i in range(1, dist_max + 1):
-               try:
-                       val = dist[c_int(i)].value
-                       if (val > 0):
-                               idx_max = i
-                       if (val > val_max):
-                               val_max = val
-               except:
-                       break
-       if idx_max > 0:
-               print("     %-15s : count     distribution" % val_type);
-       for i in range(1, idx_max + 1):
-               low = (1 << i) >> 1
-               high = (1 << i) - 1
-               if (low == high):
-                       low -= 1
-               try:
-                       val = dist[c_int(i)].value
-                       print("%8d -> %-8d : %-8d |%-*s|" % (low, high, val,
-                           stars_max, stars(val, val_max, stars_max)))
-               except:
-                       break
-
 # output
 loop = 0
 do_exit = 0
@@ -99,7 +57,7 @@ while (1):
                pass; do_exit = 1
 
        print
-       print_log2_hist(b["dist"], "kbytes")
+       b["dist"].print_log2_hist()
        b["dist"].clear()
        if do_exit:
                exit()
index 784b609..bd16dd5 100755 (executable)
@@ -41,51 +41,10 @@ if len(argv) > 1:
 b = BPF(src_file = "vfsreadlat.c")
 b.attach_kprobe(event="vfs_read", fn_name="do_entry")
 b.attach_kretprobe(event="vfs_read", fn_name="do_return")
-dist_max = 64
 
 # header
 print("Tracing... Hit Ctrl-C to end.")
 
-# functions
-stars_max = 38
-def stars(val, val_max, width):
-       i = 0
-       text = ""
-       while (1):
-               if (i > (width * val / val_max) - 1) or (i > width - 1):
-                       break
-               text += "*"
-               i += 1
-       if val > val_max:
-               text = text[:-1] + "+"
-       return text
-
-def print_log2_hist(dist, val_type):
-       idx_max = -1
-       val_max = 0
-       for i in range(1, dist_max + 1):
-               try:
-                       val = dist[c_int(i)].value
-                       if (val > 0):
-                               idx_max = i
-                       if (val > val_max):
-                               val_max = val
-               except:
-                       break
-       if idx_max > 0:
-               print("     %-15s : count     distribution" % val_type);
-       for i in range(1, idx_max + 1):
-               low = (1 << i) >> 1
-               high = (1 << i) - 1
-               if (low == high):
-                       low -= 1
-               try:
-                       val = dist[c_int(i)].value
-                       print("%8d -> %-8d : %-8d |%-*s|" % (low, high, val,
-                           stars_max, stars(val, val_max, stars_max)))
-               except:
-                       break
-
 # output
 loop = 0
 do_exit = 0
@@ -100,7 +59,7 @@ while (1):
                pass; do_exit = 1
 
        print
-       print_log2_hist(b["dist"], "usecs")
+       b["dist"].print_log2_hist("usecs")
        b["dist"].clear()
        if do_exit:
                exit()
index b11b94e..72d6514 100644 (file)
@@ -95,6 +95,7 @@ KALLSYMS = "/proc/kallsyms"
 ksym_addrs = []
 ksym_names = []
 ksym_loaded = 0
+stars_max = 38
 
 @atexit.register
 def cleanup_kprobes():
@@ -220,6 +221,52 @@ class BPF(object):
             else:
                 super(BPF.Table, self).clear()
 
+        @staticmethod
+        def _stars(val, val_max, width):
+            i = 0
+            text = ""
+            while (1):
+                if (i > (width * val / val_max) - 1) or (i > width - 1):
+                    break
+                text += "*"
+                i += 1
+            if val > val_max:
+                text = text[:-1] + "+"
+            return text
+
+        def print_log2_hist(self, val_type="value"):
+            """print_log2_hist(type=value)
+
+            Prints a table as a log2 histogram. The table must be stored as
+            log2. The type argument is optional, and is a column header.
+            """
+            global stars_max
+            log2_dist_max = 64
+            idx_max = -1
+            val_max = 0
+            for i in range(1, log2_dist_max + 1):
+                try:
+                    val = self[ct.c_int(i)].value
+                    if (val > 0):
+                        idx_max = i
+                    if (val > val_max):
+                        val_max = val
+                except:
+                    break
+            if idx_max > 0:
+                print("     %-15s : count     distribution" % val_type);
+            for i in range(1, idx_max + 1):
+                low = (1 << i) >> 1
+                high = (1 << i) - 1
+                if (low == high):
+                    low -= 1
+                try:
+                    val = self[ct.c_int(i)].value
+                    print("%8d -> %-8d : %-8d |%-*s|" % (low, high, val,
+                        stars_max, self._stars(val, val_max, stars_max)))
+                except:
+                    break
+
 
         def __iter__(self):
             return BPF.Table.Iter(self, self.Key)