summaryrefslogtreecommitdiffstats
path: root/scripts/pybootchartgui
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/pybootchartgui')
-rw-r--r--scripts/pybootchartgui/pybootchartgui/draw.py206
-rw-r--r--scripts/pybootchartgui/pybootchartgui/parsing.py63
-rw-r--r--scripts/pybootchartgui/pybootchartgui/samples.py35
3 files changed, 289 insertions, 15 deletions
diff --git a/scripts/pybootchartgui/pybootchartgui/draw.py b/scripts/pybootchartgui/pybootchartgui/draw.py
index 53324b9f8b..16739a0fa1 100644
--- a/scripts/pybootchartgui/pybootchartgui/draw.py
+++ b/scripts/pybootchartgui/pybootchartgui/draw.py
@@ -69,6 +69,11 @@ CPU_COLOR = (0.40, 0.55, 0.70, 1.0)
69IO_COLOR = (0.76, 0.48, 0.48, 0.5) 69IO_COLOR = (0.76, 0.48, 0.48, 0.5)
70# Disk throughput color. 70# Disk throughput color.
71DISK_TPUT_COLOR = (0.20, 0.71, 0.20, 1.0) 71DISK_TPUT_COLOR = (0.20, 0.71, 0.20, 1.0)
72
73BYTES_RECEIVED_COLOR = (0.0, 0.0, 1.0, 1.0)
74BYTES_TRANSMITTED_COLOR = (1.0, 0.0, 0.0, 1.0)
75BYTES_RECEIVE_DIFF_COLOR = (0.0, 0.0, 1.0, 0.3)
76BYTES_TRANSMIT_DIFF_COLOR = (1.0, 0.0, 0.0, 0.3)
72# CPU load chart color. 77# CPU load chart color.
73FILE_OPEN_COLOR = (0.20, 0.71, 0.71, 1.0) 78FILE_OPEN_COLOR = (0.20, 0.71, 0.71, 1.0)
74# Mem cached color 79# Mem cached color
@@ -80,6 +85,22 @@ MEM_BUFFERS_COLOR = (0.4, 0.4, 0.4, 0.3)
80# Swap color 85# Swap color
81MEM_SWAP_COLOR = DISK_TPUT_COLOR 86MEM_SWAP_COLOR = DISK_TPUT_COLOR
82 87
88# avg10 CPU pressure color
89CPU_PRESSURE_AVG10_COLOR = (0.0, 0.0, 0.0, 1.0)
90# delta total CPU pressure color
91CPU_PRESSURE_TOTAL_COLOR = CPU_COLOR
92# avg10 IO pressure color
93IO_PRESSURE_AVG10_COLOR = (0.0, 0.0, 0.0, 1.0)
94# delta total IO pressure color
95IO_PRESSURE_TOTAL_COLOR = IO_COLOR
96# avg10 memory pressure color
97MEM_PRESSURE_AVG10_COLOR = (0.0, 0.0, 0.0, 1.0)
98# delta total memory pressure color
99MEM_PRESSURE_TOTAL_COLOR = DISK_TPUT_COLOR
100
101
102
103
83# Process border color. 104# Process border color.
84PROC_BORDER_COLOR = (0.71, 0.71, 0.71, 1.0) 105PROC_BORDER_COLOR = (0.71, 0.71, 0.71, 1.0)
85# Waiting process color. 106# Waiting process color.
@@ -267,11 +288,14 @@ def draw_chart(ctx, color, fill, chart_bounds, data, proc_tree, data_range):
267 # avoid divide by zero 288 # avoid divide by zero
268 if max_y == 0: 289 if max_y == 0:
269 max_y = 1.0 290 max_y = 1.0
270 xscale = float (chart_bounds[2]) / (max_x - x_shift) 291 if (max_x - x_shift):
292 xscale = float (chart_bounds[2]) / (max_x - x_shift)
293 else:
294 xscale = float (chart_bounds[2])
271 # If data_range is given, scale the chart so that the value range in 295 # If data_range is given, scale the chart so that the value range in
272 # data_range matches the chart bounds exactly. 296 # data_range matches the chart bounds exactly.
273 # Otherwise, scale so that the actual data matches the chart bounds. 297 # Otherwise, scale so that the actual data matches the chart bounds.
274 if data_range: 298 if data_range and (data_range[1] - data_range[0]):
275 yscale = float(chart_bounds[3]) / (data_range[1] - data_range[0]) 299 yscale = float(chart_bounds[3]) / (data_range[1] - data_range[0])
276 ybase = data_range[0] 300 ybase = data_range[0]
277 else: 301 else:
@@ -337,6 +361,12 @@ def extents(options, xscale, trace):
337 h += 30 + bar_h 361 h += 30 + bar_h
338 if trace.disk_stats: 362 if trace.disk_stats:
339 h += 30 + bar_h 363 h += 30 + bar_h
364 if trace.cpu_pressure:
365 h += 30 + bar_h
366 if trace.io_pressure:
367 h += 30 + bar_h
368 if trace.mem_pressure:
369 h += 30 + bar_h
340 if trace.monitor_disk: 370 if trace.monitor_disk:
341 h += 30 + bar_h 371 h += 30 + bar_h
342 if trace.mem_stats: 372 if trace.mem_stats:
@@ -412,6 +442,151 @@ def render_charts(ctx, options, clip, trace, curr_y, w, h, sec_w):
412 442
413 curr_y = curr_y + 30 + bar_h 443 curr_y = curr_y + 30 + bar_h
414 444
445 if trace.net_stats:
446 for iface, samples in trace.net_stats.items():
447 max_received_sample = max(samples, key=lambda s: s.received_bytes)
448 max_transmitted_sample = max(samples, key=lambda s: s.transmitted_bytes)
449 max_receive_diff_sample = max(samples, key=lambda s: s.receive_diff)
450 max_transmit_diff_sample = max(samples, key=lambda s: s.transmit_diff)
451
452 draw_text(ctx, "Iface: %s" % (iface), TEXT_COLOR, off_x, curr_y+20)
453 draw_legend_line(ctx, "Bytes received (max %d)" % (max_received_sample.received_bytes),
454 BYTES_RECEIVED_COLOR, off_x+150, curr_y+20, leg_s)
455 draw_legend_line(ctx, "Bytes transmitted (max %d)" % (max_transmitted_sample.transmitted_bytes),
456 BYTES_TRANSMITTED_COLOR, off_x+400, curr_y+20, leg_s)
457 draw_legend_box(ctx, "Bytes receive diff (max %d)" % (max_receive_diff_sample.receive_diff),
458 BYTES_RECEIVE_DIFF_COLOR, off_x+650, curr_y+20, leg_s)
459 draw_legend_box(ctx, "Bytes transmit diff (max %d)" % (max_transmit_diff_sample.transmit_diff),
460 BYTES_TRANSMIT_DIFF_COLOR, off_x+900, curr_y+20, leg_s)
461
462
463 chart_rect = (off_x, curr_y + 30, w, bar_h)
464 if clip_visible(clip, chart_rect):
465 draw_box_ticks(ctx, chart_rect, sec_w)
466 draw_annotations(ctx, proc_tree, trace.times, chart_rect)
467
468 if clip_visible (clip, chart_rect):
469 draw_chart (ctx, BYTES_RECEIVED_COLOR, False, chart_rect, \
470 [(sample.time, sample.received_bytes) for sample in samples], \
471 proc_tree, None)
472
473 draw_chart (ctx, BYTES_TRANSMITTED_COLOR, False, chart_rect, \
474 [(sample.time, sample.transmitted_bytes) for sample in samples], \
475 proc_tree, None)
476
477 if clip_visible (clip, chart_rect):
478 draw_chart (ctx, BYTES_RECEIVE_DIFF_COLOR, True, chart_rect, \
479 [(sample.time, sample.receive_diff) for sample in samples], \
480 proc_tree, None)
481
482 draw_chart (ctx, BYTES_TRANSMIT_DIFF_COLOR, True, chart_rect, \
483 [(sample.time, sample.transmit_diff) for sample in samples], \
484 proc_tree, None)
485
486 curr_y = curr_y + 30 + bar_h
487
488 # render CPU pressure chart
489 if trace.cpu_pressure:
490 max_sample_avg = max (trace.cpu_pressure, key = lambda s: s.avg10)
491 max_sample_total = max (trace.cpu_pressure, key = lambda s: s.deltaTotal)
492 draw_legend_line(ctx, "avg10 CPU Pressure (max %d%%)" % (max_sample_avg.avg10), CPU_PRESSURE_AVG10_COLOR, off_x, curr_y+20, leg_s)
493 draw_legend_box(ctx, "delta total CPU Pressure (max %d)" % (max_sample_total.deltaTotal), CPU_PRESSURE_TOTAL_COLOR, off_x + 240, curr_y+20, leg_s)
494
495 # render delta total cpu
496 chart_rect = (off_x, curr_y+30, w, bar_h)
497 if clip_visible (clip, chart_rect):
498 draw_box_ticks (ctx, chart_rect, sec_w)
499 draw_annotations (ctx, proc_tree, trace.times, chart_rect)
500 draw_chart (ctx, CPU_PRESSURE_TOTAL_COLOR, True, chart_rect, \
501 [(sample.time, sample.deltaTotal) for sample in trace.cpu_pressure], \
502 proc_tree, None)
503
504 # render avg10 cpu
505 if clip_visible (clip, chart_rect):
506 draw_chart (ctx, CPU_PRESSURE_AVG10_COLOR, False, chart_rect, \
507 [(sample.time, sample.avg10) for sample in trace.cpu_pressure], \
508 proc_tree, None)
509
510 pos_x = off_x + ((max_sample_avg.time - proc_tree.start_time) * w / proc_tree.duration)
511
512 shift_x, shift_y = -20, 20
513 if (pos_x < off_x + 245):
514 shift_x, shift_y = 5, 40
515
516
517 label = "%d%%" % (max_sample_avg.avg10)
518 draw_text (ctx, label, CPU_PRESSURE_AVG10_COLOR, pos_x + shift_x, curr_y + shift_y)
519
520 curr_y = curr_y + 30 + bar_h
521
522 # render I/O pressure chart
523 if trace.io_pressure:
524 max_sample_avg = max (trace.io_pressure, key = lambda s: s.avg10)
525 max_sample_total = max (trace.io_pressure, key = lambda s: s.deltaTotal)
526 draw_legend_line(ctx, "avg10 I/O Pressure (max %d%%)" % (max_sample_avg.avg10), IO_PRESSURE_AVG10_COLOR, off_x, curr_y+20, leg_s)
527 draw_legend_box(ctx, "delta total I/O Pressure (max %d)" % (max_sample_total.deltaTotal), IO_PRESSURE_TOTAL_COLOR, off_x + 240, curr_y+20, leg_s)
528
529 # render delta total io
530 chart_rect = (off_x, curr_y+30, w, bar_h)
531 if clip_visible (clip, chart_rect):
532 draw_box_ticks (ctx, chart_rect, sec_w)
533 draw_annotations (ctx, proc_tree, trace.times, chart_rect)
534 draw_chart (ctx, IO_PRESSURE_TOTAL_COLOR, True, chart_rect, \
535 [(sample.time, sample.deltaTotal) for sample in trace.io_pressure], \
536 proc_tree, None)
537
538 # render avg10 io
539 if clip_visible (clip, chart_rect):
540 draw_chart (ctx, IO_PRESSURE_AVG10_COLOR, False, chart_rect, \
541 [(sample.time, sample.avg10) for sample in trace.io_pressure], \
542 proc_tree, None)
543
544 pos_x = off_x + ((max_sample_avg.time - proc_tree.start_time) * w / proc_tree.duration)
545
546 shift_x, shift_y = -20, 20
547 if (pos_x < off_x + 245):
548 shift_x, shift_y = 5, 40
549
550
551 label = "%d%%" % (max_sample_avg.avg10)
552 draw_text (ctx, label, IO_PRESSURE_AVG10_COLOR, pos_x + shift_x, curr_y + shift_y)
553
554 curr_y = curr_y + 30 + bar_h
555
556 # render MEM pressure chart
557 if trace.mem_pressure:
558 max_sample_avg = max (trace.mem_pressure, key = lambda s: s.avg10)
559 max_sample_total = max (trace.mem_pressure, key = lambda s: s.deltaTotal)
560 draw_legend_line(ctx, "avg10 MEM Pressure (max %d%%)" % (max_sample_avg.avg10), MEM_PRESSURE_AVG10_COLOR, off_x, curr_y+20, leg_s)
561 draw_legend_box(ctx, "delta total MEM Pressure (max %d)" % (max_sample_total.deltaTotal), MEM_PRESSURE_TOTAL_COLOR, off_x + 240, curr_y+20, leg_s)
562
563 # render delta total mem
564 chart_rect = (off_x, curr_y+30, w, bar_h)
565 if clip_visible (clip, chart_rect):
566 draw_box_ticks (ctx, chart_rect, sec_w)
567 draw_annotations (ctx, proc_tree, trace.times, chart_rect)
568 draw_chart (ctx, MEM_PRESSURE_TOTAL_COLOR, True, chart_rect, \
569 [(sample.time, sample.deltaTotal) for sample in trace.mem_pressure], \
570 proc_tree, None)
571
572 # render avg10 mem
573 if clip_visible (clip, chart_rect):
574 draw_chart (ctx, MEM_PRESSURE_AVG10_COLOR, False, chart_rect, \
575 [(sample.time, sample.avg10) for sample in trace.mem_pressure], \
576 proc_tree, None)
577
578 pos_x = off_x + ((max_sample_avg.time - proc_tree.start_time) * w / proc_tree.duration)
579
580 shift_x, shift_y = -20, 20
581 if (pos_x < off_x + 245):
582 shift_x, shift_y = 5, 40
583
584
585 label = "%d%%" % (max_sample_avg.avg10)
586 draw_text (ctx, label, MEM_PRESSURE_AVG10_COLOR, pos_x + shift_x, curr_y + shift_y)
587
588 curr_y = curr_y + 30 + bar_h
589
415 # render disk space usage 590 # render disk space usage
416 # 591 #
417 # Draws the amount of disk space used on each volume relative to the 592 # Draws the amount of disk space used on each volume relative to the
@@ -493,8 +668,8 @@ def render_charts(ctx, options, clip, trace, curr_y, w, h, sec_w):
493 668
494 return curr_y 669 return curr_y
495 670
496def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w): 671def render_processes_chart(ctx, options, trace, curr_y, width, h, sec_w):
497 chart_rect = [off_x, curr_y+header_h, w, h - curr_y - 1 * off_y - header_h ] 672 chart_rect = [off_x, curr_y+header_h, width, h - curr_y - 1 * off_y - header_h ]
498 673
499 draw_legend_box (ctx, "Configure", \ 674 draw_legend_box (ctx, "Configure", \
500 TASK_COLOR_CONFIGURE, off_x , curr_y + 45, leg_s) 675 TASK_COLOR_CONFIGURE, off_x , curr_y + 45, leg_s)
@@ -519,8 +694,9 @@ def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
519 offset = trace.min or min(trace.start.keys()) 694 offset = trace.min or min(trace.start.keys())
520 for start in sorted(trace.start.keys()): 695 for start in sorted(trace.start.keys()):
521 for process in sorted(trace.start[start]): 696 for process in sorted(trace.start[start]):
697 elapsed_time = trace.processes[process][1] - start
522 if not options.app_options.show_all and \ 698 if not options.app_options.show_all and \
523 trace.processes[process][1] - start < options.app_options.mintime: 699 elapsed_time < options.app_options.mintime:
524 continue 700 continue
525 task = process.split(":")[1] 701 task = process.split(":")[1]
526 702
@@ -529,14 +705,23 @@ def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
529 #print(s) 705 #print(s)
530 706
531 x = chart_rect[0] + (start - offset) * sec_w 707 x = chart_rect[0] + (start - offset) * sec_w
532 w = ((trace.processes[process][1] - start) * sec_w) 708 w = elapsed_time * sec_w
709
710 def set_alfa(color, alfa):
711 clist = list(color)
712 clist[-1] = alfa
713 return tuple(clist)
533 714
534 #print("proc at %s %s %s %s" % (x, y, w, proc_h)) 715 #print("proc at %s %s %s %s" % (x, y, w, proc_h))
535 col = None 716 col = None
536 if task == "do_compile": 717 if task == "do_compile":
537 col = TASK_COLOR_COMPILE 718 col = TASK_COLOR_COMPILE
719 elif "do_compile" in task:
720 col = set_alfa(TASK_COLOR_COMPILE, 0.25)
538 elif task == "do_configure": 721 elif task == "do_configure":
539 col = TASK_COLOR_CONFIGURE 722 col = TASK_COLOR_CONFIGURE
723 elif "do_configure" in task:
724 col = set_alfa(TASK_COLOR_CONFIGURE, 0.25)
540 elif task == "do_install": 725 elif task == "do_install":
541 col = TASK_COLOR_INSTALL 726 col = TASK_COLOR_INSTALL
542 elif task == "do_populate_sysroot": 727 elif task == "do_populate_sysroot":
@@ -554,7 +739,10 @@ def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
554 draw_fill_rect(ctx, col, (x, y, w, proc_h)) 739 draw_fill_rect(ctx, col, (x, y, w, proc_h))
555 draw_rect(ctx, PROC_BORDER_COLOR, (x, y, w, proc_h)) 740 draw_rect(ctx, PROC_BORDER_COLOR, (x, y, w, proc_h))
556 741
557 draw_label_in_box(ctx, PROC_TEXT_COLOR, process, x, y + proc_h - 4, w, proc_h) 742 # Show elapsed time for each task
743 process = "%ds %s" % (elapsed_time, process)
744 draw_label_in_box(ctx, PROC_TEXT_COLOR, process, x, y + proc_h - 4, w, width)
745
558 y = y + proc_h 746 y = y + proc_h
559 747
560 return curr_y 748 return curr_y
@@ -695,7 +883,7 @@ def draw_processes_recursively(ctx, proc, proc_tree, y, proc_h, rect, clip) :
695 cmdString = proc.cmd 883 cmdString = proc.cmd
696 else: 884 else:
697 cmdString = '' 885 cmdString = ''
698 if (OPTIONS.show_pid or OPTIONS.show_all) and ipid is not 0: 886 if (OPTIONS.show_pid or OPTIONS.show_all) and ipid != 0:
699 cmdString = cmdString + " [" + str(ipid // 1000) + "]" 887 cmdString = cmdString + " [" + str(ipid // 1000) + "]"
700 if OPTIONS.show_all: 888 if OPTIONS.show_all:
701 if proc.args: 889 if proc.args:
@@ -793,7 +981,7 @@ class CumlSample:
793 if self.color is None: 981 if self.color is None:
794 i = self.next() % HSV_MAX_MOD 982 i = self.next() % HSV_MAX_MOD
795 h = 0.0 983 h = 0.0
796 if i is not 0: 984 if i != 0:
797 h = (1.0 * i) / HSV_MAX_MOD 985 h = (1.0 * i) / HSV_MAX_MOD
798 s = 0.5 986 s = 0.5
799 v = 1.0 987 v = 1.0
diff --git a/scripts/pybootchartgui/pybootchartgui/parsing.py b/scripts/pybootchartgui/pybootchartgui/parsing.py
index b42dac6b88..72a54c6ba5 100644
--- a/scripts/pybootchartgui/pybootchartgui/parsing.py
+++ b/scripts/pybootchartgui/pybootchartgui/parsing.py
@@ -48,7 +48,11 @@ class Trace:
48 self.filename = None 48 self.filename = None
49 self.parent_map = None 49 self.parent_map = None
50 self.mem_stats = [] 50 self.mem_stats = []
51 self.net_stats = []
51 self.monitor_disk = None 52 self.monitor_disk = None
53 self.cpu_pressure = []
54 self.io_pressure = []
55 self.mem_pressure = []
52 self.times = [] # Always empty, but expected by draw.py when drawing system charts. 56 self.times = [] # Always empty, but expected by draw.py when drawing system charts.
53 57
54 if len(paths): 58 if len(paths):
@@ -128,7 +132,7 @@ class Trace:
128 def compile(self, writer): 132 def compile(self, writer):
129 133
130 def find_parent_id_for(pid): 134 def find_parent_id_for(pid):
131 if pid is 0: 135 if pid == 0:
132 return 0 136 return 0
133 ppid = self.parent_map.get(pid) 137 ppid = self.parent_map.get(pid)
134 if ppid: 138 if ppid:
@@ -454,7 +458,7 @@ def _parse_proc_disk_stat_log(file):
454 not sda1, sda2 etc. The format of relevant lines should be: 458 not sda1, sda2 etc. The format of relevant lines should be:
455 {major minor name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq} 459 {major minor name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq}
456 """ 460 """
457 disk_regex_re = re.compile ('^([hsv]d.|mtdblock\d|mmcblk\d|cciss/c\d+d\d+.*)$') 461 disk_regex_re = re.compile (r'^([hsv]d.|mtdblock\d|mmcblk\d|cciss/c\d+d\d+.*)$')
458 462
459 # this gets called an awful lot. 463 # this gets called an awful lot.
460 def is_relevant_line(linetokens): 464 def is_relevant_line(linetokens):
@@ -555,6 +559,44 @@ def _parse_monitor_disk_log(file):
555 return disk_stats 559 return disk_stats
556 560
557 561
562def _parse_reduced_net_log(file):
563 net_stats = {}
564 for time, lines in _parse_timed_blocks(file):
565
566 for line in lines:
567 parts = line.split()
568 iface = parts[0][:-1]
569 if iface not in net_stats:
570 net_stats[iface] = [NetSample(time, iface, int(parts[1]), int(parts[2]), int(parts[3]), int(parts[4]))]
571 else:
572 net_stats[iface].append(NetSample(time, iface, int(parts[1]), int(parts[2]), int(parts[3]), int(parts[4])))
573 return net_stats
574
575
576def _parse_pressure_logs(file, filename):
577 """
578 Parse file for "some" pressure with 'avg10', 'avg60' 'avg300' and delta total values
579 (in that order) directly stored on one line for both CPU and IO, based on filename.
580 """
581 pressure_stats = []
582 if filename == "cpu.log":
583 SamplingClass = CPUPressureSample
584 elif filename == "memory.log":
585 SamplingClass = MemPressureSample
586 else:
587 SamplingClass = IOPressureSample
588 for time, lines in _parse_timed_blocks(file):
589 for line in lines:
590 if not line: continue
591 tokens = line.split()
592 avg10 = float(tokens[0])
593 avg60 = float(tokens[1])
594 avg300 = float(tokens[2])
595 delta = float(tokens[3])
596 pressure_stats.append(SamplingClass(time, avg10, avg60, avg300, delta))
597
598 return pressure_stats
599
558# if we boot the kernel with: initcall_debug printk.time=1 we can 600# if we boot the kernel with: initcall_debug printk.time=1 we can
559# get all manner of interesting data from the dmesg output 601# get all manner of interesting data from the dmesg output
560# We turn this into a pseudo-process tree: each event is 602# We turn this into a pseudo-process tree: each event is
@@ -568,8 +610,8 @@ def _parse_monitor_disk_log(file):
568# [ 0.039993] calling migration_init+0x0/0x6b @ 1 610# [ 0.039993] calling migration_init+0x0/0x6b @ 1
569# [ 0.039993] initcall migration_init+0x0/0x6b returned 1 after 0 usecs 611# [ 0.039993] initcall migration_init+0x0/0x6b returned 1 after 0 usecs
570def _parse_dmesg(writer, file): 612def _parse_dmesg(writer, file):
571 timestamp_re = re.compile ("^\[\s*(\d+\.\d+)\s*]\s+(.*)$") 613 timestamp_re = re.compile (r"^\[\s*(\d+\.\d+)\s*]\s+(.*)$")
572 split_re = re.compile ("^(\S+)\s+([\S\+_-]+) (.*)$") 614 split_re = re.compile (r"^(\S+)\s+([\S\+_-]+) (.*)$")
573 processMap = {} 615 processMap = {}
574 idx = 0 616 idx = 0
575 inc = 1.0 / 1000000 617 inc = 1.0 / 1000000
@@ -614,7 +656,7 @@ def _parse_dmesg(writer, file):
614# print "foo: '%s' '%s' '%s'" % (type, func, rest) 656# print "foo: '%s' '%s' '%s'" % (type, func, rest)
615 if type == "calling": 657 if type == "calling":
616 ppid = kernel.pid 658 ppid = kernel.pid
617 p = re.match ("\@ (\d+)", rest) 659 p = re.match (r"\@ (\d+)", rest)
618 if p is not None: 660 if p is not None:
619 ppid = float (p.group(1)) // 1000 661 ppid = float (p.group(1)) // 1000
620# print "match: '%s' ('%g') at '%s'" % (func, ppid, time_ms) 662# print "match: '%s' ('%g') at '%s'" % (func, ppid, time_ms)
@@ -716,7 +758,7 @@ def get_num_cpus(headers):
716 cpu_model = headers.get("system.cpu") 758 cpu_model = headers.get("system.cpu")
717 if cpu_model is None: 759 if cpu_model is None:
718 return 1 760 return 1
719 mat = re.match(".*\\((\\d+)\\)", cpu_model) 761 mat = re.match(r".*\\((\\d+)\\)", cpu_model)
720 if mat is None: 762 if mat is None:
721 return 1 763 return 1
722 return max (int(mat.group(1)), 1) 764 return max (int(mat.group(1)), 1)
@@ -741,6 +783,15 @@ def _do_parse(writer, state, filename, file):
741 state.cmdline = _parse_cmdline_log(writer, file) 783 state.cmdline = _parse_cmdline_log(writer, file)
742 elif name == "monitor_disk.log": 784 elif name == "monitor_disk.log":
743 state.monitor_disk = _parse_monitor_disk_log(file) 785 state.monitor_disk = _parse_monitor_disk_log(file)
786 elif name == "reduced_proc_net.log":
787 state.net_stats = _parse_reduced_net_log(file)
788 #pressure logs are in a subdirectory
789 elif name == "cpu.log":
790 state.cpu_pressure = _parse_pressure_logs(file, name)
791 elif name == "io.log":
792 state.io_pressure = _parse_pressure_logs(file, name)
793 elif name == "memory.log":
794 state.mem_pressure = _parse_pressure_logs(file, name)
744 elif not filename.endswith('.log'): 795 elif not filename.endswith('.log'):
745 _parse_bitbake_buildstats(writer, state, filename, file) 796 _parse_bitbake_buildstats(writer, state, filename, file)
746 t2 = time.process_time() 797 t2 = time.process_time()
diff --git a/scripts/pybootchartgui/pybootchartgui/samples.py b/scripts/pybootchartgui/pybootchartgui/samples.py
index 9fc309b3ab..7c92d2ce6a 100644
--- a/scripts/pybootchartgui/pybootchartgui/samples.py
+++ b/scripts/pybootchartgui/pybootchartgui/samples.py
@@ -37,6 +37,41 @@ class CPUSample:
37 return str(self.time) + "\t" + str(self.user) + "\t" + \ 37 return str(self.time) + "\t" + str(self.user) + "\t" + \
38 str(self.sys) + "\t" + str(self.io) + "\t" + str (self.swap) 38 str(self.sys) + "\t" + str(self.io) + "\t" + str (self.swap)
39 39
40
41class NetSample:
42 def __init__(self, time, iface, received_bytes, transmitted_bytes, receive_diff, transmit_diff):
43 self.time = time
44 self.iface = iface
45 self.received_bytes = received_bytes
46 self.transmitted_bytes = transmitted_bytes
47 self.receive_diff = receive_diff
48 self.transmit_diff = transmit_diff
49
50class CPUPressureSample:
51 def __init__(self, time, avg10, avg60, avg300, deltaTotal):
52 self.time = time
53 self.avg10 = avg10
54 self.avg60 = avg60
55 self.avg300 = avg300
56 self.deltaTotal = deltaTotal
57
58class IOPressureSample:
59 def __init__(self, time, avg10, avg60, avg300, deltaTotal):
60 self.time = time
61 self.avg10 = avg10
62 self.avg60 = avg60
63 self.avg300 = avg300
64 self.deltaTotal = deltaTotal
65
66class MemPressureSample:
67 def __init__(self, time, avg10, avg60, avg300, deltaTotal):
68 self.time = time
69 self.avg10 = avg10
70 self.avg60 = avg60
71 self.avg300 = avg300
72 self.deltaTotal = deltaTotal
73
74
40class MemSample: 75class MemSample:
41 used_values = ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree',) 76 used_values = ('MemTotal', 'MemFree', 'Buffers', 'Cached', 'SwapTotal', 'SwapFree',)
42 77