[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