[systemd-devel] [PATCH] systemd-analyze: switch to python getopt for argument parsing

Shawn Landden shawnlandden at gmail.com
Mon May 14 14:55:24 PDT 2012


this uses gnu style getopt, so you can put the opts at the end: (e.g.)
systemd-analyze blame --user

v3
---
 src/analyze/systemd-analyze |  282 ++++++++++++++++++++++++-------------------
 1 file changed, 155 insertions(+), 127 deletions(-)

diff --git a/src/analyze/systemd-analyze b/src/analyze/systemd-analyze
index ad7bd9a..ecac3a2 100755
--- a/src/analyze/systemd-analyze
+++ b/src/analyze/systemd-analyze
@@ -1,6 +1,10 @@
 #!/usr/bin/python
 
-import dbus, sys
+import getopt, dbus, sys, os
+try:
+        import cairo
+except ImportError:
+        cairo = None
 
 def acquire_time_data():
 
@@ -68,7 +72,7 @@ def draw_text(context, x, y, text, size = 12, r = 0, g = 0, b = 0, vcenter = 0.5
 
         context.restore()
 
-def help():
+def usage():
         sys.stdout.write("""systemd-analyze [--user] time
 systemd-analyze [--user] blame
 systemd-analyze [--user] plot
@@ -78,16 +82,11 @@ Process systemd profiling information
   -h --help         Show this help
 """)
 
+def help():
+        usage()
+        sys.exit()
 
-bus = dbus.SystemBus()
-command_index = 1
-
-if len(sys.argv) > 1 and sys.argv[1] == '--user':
-        bus = dbus.SessionBus()
-        command_index = 2
-
-
-if len(sys.argv) <= command_index or sys.argv[command_index] == 'time':
+def time():
 
         initrd_time, start_time, finish_time = acquire_start_time()
 
@@ -104,7 +103,7 @@ if len(sys.argv) <= command_index or sys.argv[command_index] == 'time':
                         finish_time/1000)
 
 
-elif sys.argv[command_index] == 'blame':
+def blame():
 
         data = acquire_time_data()
         s = sorted(data, key = lambda i: i[2] - i[1], reverse = True)
@@ -119,164 +118,193 @@ elif sys.argv[command_index] == 'blame':
 
                 sys.stdout.write("%6lums %s\n" % ((aet - ixt) / 1000, name))
 
-elif sys.argv[command_index] == 'plot':
-        import cairo, os
+def plot():
+        if cairo:
+                initrd_time, start_time, finish_time = acquire_start_time()
+                data = acquire_time_data()
+                s = sorted(data, key = lambda i: i[1])
 
-        initrd_time, start_time, finish_time = acquire_start_time()
-        data = acquire_time_data()
-        s = sorted(data, key = lambda i: i[1])
+                # Account for kernel and initramfs bars if they exist
+                if initrd_time > 0:
+                        count = 3
+                else:
+                        count = 2
 
-        # Account for kernel and initramfs bars if they exist
-        if initrd_time > 0:
-                count = 3
-        else:
-                count = 2
+                for name, ixt, aet, axt, iet in s:
 
-        for name, ixt, aet, axt, iet in s:
+                        if (ixt >= start_time and ixt <= finish_time) or \
+                                        (aet >= start_time and aet <= finish_time) or \
+                                        (axt >= start_time and axt <= finish_time):
+                                count += 1
 
-                if (ixt >= start_time and ixt <= finish_time) or \
-                                (aet >= start_time and aet <= finish_time) or \
-                                (axt >= start_time and axt <= finish_time):
-                        count += 1
+                border = 100
+                bar_height = 20
+                bar_space = bar_height * 0.1
 
-        border = 100
-        bar_height = 20
-        bar_space = bar_height * 0.1
+                # 1000px = 10s, 1px = 10ms
+                width = finish_time/10000 + border*2
+                height = count * (bar_height + bar_space) + border * 2
 
-        # 1000px = 10s, 1px = 10ms
-        width = finish_time/10000 + border*2
-        height = count * (bar_height + bar_space) + border * 2
+                if width < 1000:
+                        width = 1000
 
-        if width < 1000:
-                width = 1000
+                surface = cairo.SVGSurface(sys.stdout, width, height)
+                context = cairo.Context(surface)
 
-        surface = cairo.SVGSurface(sys.stdout, width, height)
-        context = cairo.Context(surface)
+                draw_box(context, 0, 0, width, height, 1, 1, 1)
 
-        draw_box(context, 0, 0, width, height, 1, 1, 1)
+                context.translate(border + 0.5, border + 0.5)
 
-        context.translate(border + 0.5, border + 0.5)
+                context.save()
+                context.set_line_width(1)
+                context.set_source_rgb(0.7, 0.7, 0.7)
 
-        context.save()
-        context.set_line_width(1)
-        context.set_source_rgb(0.7, 0.7, 0.7)
+                for x in range(0, finish_time/10000 + 100, 100):
+                        context.move_to(x, 0)
+                        context.line_to(x, height-border*2)
 
-        for x in range(0, finish_time/10000 + 100, 100):
-                context.move_to(x, 0)
-                context.line_to(x, height-border*2)
+                context.move_to(0, 0)
+                context.line_to(width-border*2, 0)
 
-        context.move_to(0, 0)
-        context.line_to(width-border*2, 0)
+                context.move_to(0, height-border*2)
+                context.line_to(width-border*2, height-border*2)
 
-        context.move_to(0, height-border*2)
-        context.line_to(width-border*2, height-border*2)
+                context.stroke()
+                context.restore()
 
-        context.stroke()
-        context.restore()
+                osrel = "Linux"
+                if os.path.exists("/etc/os-release"):
+                        for line in open("/etc/os-release"):
+                                if line.startswith('PRETTY_NAME='):
+                                        osrel = line[12:]
+                                        osrel = osrel.strip('\"\n')
+                                        break
 
-        osrel = "Linux"
-        if os.path.exists("/etc/os-release"):
-                for line in open("/etc/os-release"):
-                        if line.startswith('PRETTY_NAME='):
-                                osrel = line[12:]
-                                osrel = osrel.strip('\"\n')
-                                break
+                banner = "{} {} ({} {}) {}".format(osrel, *(os.uname()[1:5]))
+                draw_text(context, 0, -15, banner, hcenter = 0, vcenter = 1)
 
-        banner = "{} {} ({} {}) {}".format(osrel, *(os.uname()[1:5]))
-        draw_text(context, 0, -15, banner, hcenter = 0, vcenter = 1)
+                for x in range(0, finish_time/10000 + 100, 100):
+                        draw_text(context, x, -5, "%lus" % (x/100), vcenter = 0, hcenter = 0)
 
-        for x in range(0, finish_time/10000 + 100, 100):
-                draw_text(context, x, -5, "%lus" % (x/100), vcenter = 0, hcenter = 0)
+                y = 0
 
-        y = 0
+                # draw boxes for kernel and initramfs boot time
+                if initrd_time > 0:
+                        draw_box(context, 0, y, initrd_time/10000, bar_height, 0.7, 0.7, 0.7)
+                        draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0)
+                        y += bar_height + bar_space
 
-        # draw boxes for kernel and initramfs boot time
-        if initrd_time > 0:
-                draw_box(context, 0, y, initrd_time/10000, bar_height, 0.7, 0.7, 0.7)
-                draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0)
-                y += bar_height + bar_space
+                        draw_box(context, initrd_time/10000, y, start_time/10000-initrd_time/10000, bar_height, 0.7, 0.7, 0.7)
+                        draw_text(context, initrd_time/10000 + 10, y + bar_height/2, "initramfs", hcenter = 0)
+                        y += bar_height + bar_space
 
-                draw_box(context, initrd_time/10000, y, start_time/10000-initrd_time/10000, bar_height, 0.7, 0.7, 0.7)
-                draw_text(context, initrd_time/10000 + 10, y + bar_height/2, "initramfs", hcenter = 0)
-                y += bar_height + bar_space
+                else:
+                        draw_box(context, 0, y, start_time/10000, bar_height, 0.6, 0.6, 0.6)
+                        draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0)
+                        y += bar_height + bar_space
 
-        else:
-                draw_box(context, 0, y, start_time/10000, bar_height, 0.6, 0.6, 0.6)
-                draw_text(context, 10, y + bar_height/2, "kernel", hcenter = 0)
+                draw_box(context, start_time/10000, y, finish_time/10000-start_time/10000, bar_height, 0.7, 0.7, 0.7)
+                draw_text(context, start_time/10000 + 10, y + bar_height/2, "userspace", hcenter = 0)
                 y += bar_height + bar_space
 
-        draw_box(context, start_time/10000, y, finish_time/10000-start_time/10000, bar_height, 0.7, 0.7, 0.7)
-        draw_text(context, start_time/10000 + 10, y + bar_height/2, "userspace", hcenter = 0)
-        y += bar_height + bar_space
+                for name, ixt, aet, axt, iet in s:
 
-        for name, ixt, aet, axt, iet in s:
+                        drawn = False
+                        left = -1
 
-                drawn = False
-                left = -1
+                        if ixt >= start_time and ixt <= finish_time:
 
-                if ixt >= start_time and ixt <= finish_time:
+                                # Activating
+                                a = ixt
+                                b = min(filter(lambda x: x >= ixt, (aet, axt, iet, finish_time))) - ixt
 
-                        # Activating
-                        a = ixt
-                        b = min(filter(lambda x: x >= ixt, (aet, axt, iet, finish_time))) - ixt
+                                draw_box(context, a/10000, y, b/10000, bar_height, 1, 0, 0)
+                                drawn = True
 
-                        draw_box(context, a/10000, y, b/10000, bar_height, 1, 0, 0)
-                        drawn = True
+                                if left < 0:
+                                        left = a
 
-                        if left < 0:
-                                left = a
+                        if aet >= start_time and aet <= finish_time:
 
-                if aet >= start_time and aet <= finish_time:
+                                # Active
+                                a = aet
+                                b = min(filter(lambda x: x >= aet, (axt, iet, finish_time))) - aet
 
-                        # Active
-                        a = aet
-                        b = min(filter(lambda x: x >= aet, (axt, iet, finish_time))) - aet
+                                draw_box(context, a/10000, y, b/10000, bar_height, .8, .6, .6)
+                                drawn = True
 
-                        draw_box(context, a/10000, y, b/10000, bar_height, .8, .6, .6)
-                        drawn = True
+                                if left < 0:
+                                        left = a
 
-                        if left < 0:
-                                left = a
+                        if axt >= start_time and axt <= finish_time:
 
-                if axt >= start_time and axt <= finish_time:
+                                # Deactivating
+                                a = axt
+                                b = min(filter(lambda x: x >= axt, (iet, finish_time))) - axt
 
-                        # Deactivating
-                        a = axt
-                        b = min(filter(lambda x: x >= axt, (iet, finish_time))) - axt
+                                draw_box(context, a/10000, y, b/10000, bar_height, .6, .4, .4)
+                                drawn = True
 
-                        draw_box(context, a/10000, y, b/10000, bar_height, .6, .4, .4)
-                        drawn = True
+                                if left < 0:
+                                        left = a
 
-                        if left < 0:
-                                left = a
+                        if drawn:
+                                x = left/10000
 
-                if drawn:
-                        x = left/10000
+                                if x < width/2-border:
+                                        draw_text(context, x + 10, y + bar_height/2, name, hcenter = 0)
+                                else:
+                                        draw_text(context, x - 10, y + bar_height/2, name, hcenter = 1)
 
-                        if x < width/2-border:
-                                draw_text(context, x + 10, y + bar_height/2, name, hcenter = 0)
-                        else:
-                                draw_text(context, x - 10, y + bar_height/2, name, hcenter = 1)
+                                y += bar_height + bar_space
 
-                        y += bar_height + bar_space
+                draw_text(context, 0, height-border*2, "Legend: Red = Activating; Pink = Active; Dark Pink = Deactivating", hcenter = 0, vcenter = -1)
 
-        draw_text(context, 0, height-border*2, "Legend: Red = Activating; Pink = Active; Dark Pink = Deactivating", hcenter = 0, vcenter = -1)
+                if initrd_time > 0:
+                        draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (initramfs) + %lums (userspace) = %lums" % ( \
+                                initrd_time/1000, \
+                                (start_time - initrd_time)/1000, \
+                                (finish_time - start_time)/1000, \
+                                finish_time/1000), hcenter = 0, vcenter = -1)
+                else:
+                        draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (userspace) = %lums" % ( \
+                                start_time/1000, \
+                                (finish_time - start_time)/1000, \
+                                finish_time/1000), hcenter = 0, vcenter = -1)
 
-        if initrd_time > 0:
-                draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (initramfs) + %lums (userspace) = %lums" % ( \
-                        initrd_time/1000, \
-                        (start_time - initrd_time)/1000, \
-                        (finish_time - start_time)/1000, \
-                        finish_time/1000), hcenter = 0, vcenter = -1)
+                surface.finish()
+        else: #if cairo:
+                sys.stderr.write("Failed to initilize python-cairo required for 'plot' verb.\n")
+                sys.exit(1)
+
+def unknown_verb():
+        sys.stderr.write("Unknown verb '%s'.\n" % args[0])
+        usage()
+        sys.exit(1)
+
+bus = dbus.SystemBus()
+
+try:
+        opts, args = getopt.gnu_getopt(sys.argv[1:], "h", ["help", "user"])
+except getopt.GetoptError, err:
+        print str(err)
+        usage()
+        sys.exit(2)
+for o, a in opts:
+        if o in ("-h", "--help"):
+                help()
+        elif o == '--user':
+                bus = dbus.SessionBus()
         else:
-                draw_text(context, 0, height-border*2 + bar_height, "Startup finished in %lums (kernel) + %lums (userspace) = %lums" % ( \
-                        start_time/1000, \
-                        (finish_time - start_time)/1000, \
-                        finish_time/1000), hcenter = 0, vcenter = -1)
+                assert False, "unhandled option"
 
-        surface.finish()
-elif sys.argv[command_index] in ("help", "--help", "-h"):
-        help()
+verb = {'time' : time,
+	'blame': blame,
+	'plot' : plot,
+	'help' : help,
+	}
+
+if len(args) == 0:
+        time()
 else:
-        sys.stderr.write("Unknown verb '%s'.\n" % sys.argv[command_index])
-        sys.exit(1)
+        verb.get(args[0], unknown_verb)()
-- 
1.7.9.5



More information about the systemd-devel mailing list