]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemd-analyze
5 def acquire_time_data():
7 manager
= dbus
.Interface(bus
.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1'), 'org.freedesktop.systemd1.Manager')
8 units
= manager
.ListUnits()
16 properties
= dbus
.Interface(bus
.get_object('org.freedesktop.systemd1', i
[6]), 'org.freedesktop.DBus.Properties')
18 ixt
= int(properties
.Get('org.freedesktop.systemd1.Unit', 'InactiveExitTimestampMonotonic'))
19 aet
= int(properties
.Get('org.freedesktop.systemd1.Unit', 'ActiveEnterTimestampMonotonic'))
20 axt
= int(properties
.Get('org.freedesktop.systemd1.Unit', 'ActiveExitTimestampMonotonic'))
21 iet
= int(properties
.Get('org.freedesktop.systemd1.Unit', 'InactiveEnterTimestampMonotonic'))
23 l
.append((str(i
[0]), ixt
, aet
, axt
, iet
))
27 def acquire_start_time():
28 properties
= dbus
.Interface(bus
.get_object('org.freedesktop.systemd1', '/org/freedesktop/systemd1'), 'org.freedesktop.DBus.Properties')
30 initrd_time
= int(properties
.Get('org.freedesktop.systemd1.Manager', 'InitRDTimestampMonotonic'))
31 startup_time
= int(properties
.Get('org.freedesktop.systemd1.Manager', 'StartupTimestampMonotonic'))
32 finish_time
= int(properties
.Get('org.freedesktop.systemd1.Manager', 'FinishTimestampMonotonic'))
34 assert initrd_time
<= startup_time
35 assert startup_time
<= finish_time
37 return initrd_time
, startup_time
, finish_time
39 def draw_box(context
, j
, k
, l
, m
, r
= 0, g
= 0, b
= 0):
41 context
.set_source_rgb(r
, g
, b
)
42 context
.rectangle(j
, k
, l
, m
)
46 def draw_text(context
, x
, y
, text
, size
= 12, r
= 0, g
= 0, b
= 0, vcenter
= 0.5, hcenter
= 0.5):
49 context
.set_source_rgb(r
, g
, b
)
50 context
.select_font_face("Sans", cairo
.FONT_SLANT_NORMAL
, cairo
.FONT_WEIGHT_NORMAL
)
51 context
.set_font_size(size
)
53 if vcenter
or hcenter
:
54 x_bearing
, y_bearing
, width
, height
= context
.text_extents(text
)[:4]
57 x
= x
- width
*hcenter
- x_bearing
60 y
= y
- height
*vcenter
- y_bearing
63 context
.show_text(text
)
68 sys
.stdout
.write("""systemd-analyze time
72 Process systemd profiling information
74 -h --help Show this help
78 bus
= dbus
.SystemBus()
80 if len(sys
.argv
) <= 1 or sys
.argv
[1] == 'time':
82 initrd_time
, start_time
, finish_time
= acquire_start_time()
85 print "Startup finished in %lums (kernel) + %lums (initramfs) + %lums (userspace) = %lums" % ( \
87 (start_time
- initrd_time
)/1000, \
88 (finish_time
- start_time
)/1000, \
91 print "Startup finished in %lums (kernel) + %lums (userspace) = %lums" % ( \
93 (finish_time
- start_time
)/1000, \
97 elif sys
.argv
[1] == 'blame':
99 data
= acquire_time_data()
100 s
= sorted(data
, key
= lambda i
: i
[2] - i
[1], reverse
= True)
102 for name
, ixt
, aet
, axt
, iet
in s
:
104 if ixt
<= 0 or aet
<= 0:
110 sys
.stdout
.write("%6lums %s\n" % ((aet
- ixt
) / 1000, name
))
112 elif sys
.argv
[1] == 'plot':
115 initrd_time
, start_time
, finish_time
= acquire_start_time()
116 data
= acquire_time_data()
117 s
= sorted(data
, key
= lambda i
: i
[1])
119 # Account for kernel and initramfs bars if they exist
125 for name
, ixt
, aet
, axt
, iet
in s
:
127 if (ixt
>= start_time
and ixt
<= finish_time
) or \
128 (aet
>= start_time
and aet
<= finish_time
) or \
129 (axt
>= start_time
and axt
<= finish_time
):
134 bar_space
= bar_height
* 0.1
136 # 1000px = 10s, 1px = 10ms
137 width
= finish_time
/10000 + border
*2
138 height
= count
* (bar_height
+ bar_space
) + border
* 2
143 surface
= cairo
.SVGSurface(sys
.stdout
, width
, height
)
144 context
= cairo
.Context(surface
)
146 draw_box(context
, 0, 0, width
, height
, 1, 1, 1)
148 context
.translate(border
+ 0.5, border
+ 0.5)
151 context
.set_line_width(1)
152 context
.set_source_rgb(0.7, 0.7, 0.7)
154 for x
in range(0, finish_time
/10000 + 100, 100):
155 context
.move_to(x
, 0)
156 context
.line_to(x
, height
-border
*2)
158 context
.move_to(0, 0)
159 context
.line_to(width
-border
*2, 0)
161 context
.move_to(0, height
-border
*2)
162 context
.line_to(width
-border
*2, height
-border
*2)
168 if os
.path
.exists("/etc/os-release"):
169 for line
in open("/etc/os-release"):
170 if line
.startswith('PRETTY_NAME='):
172 osrel
= osrel
.strip('\"\n')
175 banner
= "{} {} ({} {}) {}".format(osrel
, *(os
.uname()[1:5]))
176 draw_text(context
, 0, -15, banner
, hcenter
= 0, vcenter
= 1)
178 for x
in range(0, finish_time
/10000 + 100, 100):
179 draw_text(context
, x
, -5, "%lus" % (x
/100), vcenter
= 0, hcenter
= 0)
183 # draw boxes for kernel and initramfs boot time
185 draw_box(context
, 0, y
, initrd_time
/10000, bar_height
, 0.7, 0.7, 0.7)
186 draw_text(context
, 10, y
+ bar_height
/2, "kernel", hcenter
= 0)
187 y
+= bar_height
+ bar_space
189 draw_box(context
, initrd_time
/10000, y
, start_time
/10000-initrd_time
/10000, bar_height
, 0.7, 0.7, 0.7)
190 draw_text(context
, initrd_time
/10000 + 10, y
+ bar_height
/2, "initramfs", hcenter
= 0)
191 y
+= bar_height
+ bar_space
194 draw_box(context
, 0, y
, start_time
/10000, bar_height
, 0.6, 0.6, 0.6)
195 draw_text(context
, 10, y
+ bar_height
/2, "kernel", hcenter
= 0)
196 y
+= bar_height
+ bar_space
198 draw_box(context
, start_time
/10000, y
, finish_time
/10000-start_time
/10000, bar_height
, 0.7, 0.7, 0.7)
199 draw_text(context
, start_time
/10000 + 10, y
+ bar_height
/2, "userspace", hcenter
= 0)
200 y
+= bar_height
+ bar_space
202 for name
, ixt
, aet
, axt
, iet
in s
:
207 if ixt
>= start_time
and ixt
<= finish_time
:
211 b
= min(filter(lambda x
: x
>= ixt
, (aet
, axt
, iet
, finish_time
))) - ixt
213 draw_box(context
, a
/10000, y
, b
/10000, bar_height
, 1, 0, 0)
219 if aet
>= start_time
and aet
<= finish_time
:
223 b
= min(filter(lambda x
: x
>= aet
, (axt
, iet
, finish_time
))) - aet
225 draw_box(context
, a
/10000, y
, b
/10000, bar_height
, .8, .6, .6)
231 if axt
>= start_time
and axt
<= finish_time
:
235 b
= min(filter(lambda x
: x
>= axt
, (iet
, finish_time
))) - axt
237 draw_box(context
, a
/10000, y
, b
/10000, bar_height
, .6, .4, .4)
246 if x
< width
/2-border
:
247 draw_text(context
, x
+ 10, y
+ bar_height
/2, name
, hcenter
= 0)
249 draw_text(context
, x
- 10, y
+ bar_height
/2, name
, hcenter
= 1)
251 y
+= bar_height
+ bar_space
253 draw_text(context
, 0, height
-border
*2, "Legend: Red = Activating; Pink = Active; Dark Pink = Deactivating", hcenter
= 0, vcenter
= -1)
256 draw_text(context
, 0, height
-border
*2 + bar_height
, "Startup finished in %lums (kernel) + %lums (initramfs) + %lums (userspace) = %lums" % ( \
258 (start_time
- initrd_time
)/1000, \
259 (finish_time
- start_time
)/1000, \
260 finish_time
/1000), hcenter
= 0, vcenter
= -1)
262 draw_text(context
, 0, height
-border
*2 + bar_height
, "Startup finished in %lums (kernel) + %lums (userspace) = %lums" % ( \
264 (finish_time
- start_time
)/1000, \
265 finish_time
/1000), hcenter
= 0, vcenter
= -1)
268 elif sys
.argv
[1] in ("help", "--help", "-h"):
271 sys
.stderr
.write("Unknown verb '%s'.\n" % sys
.argv
[1])