summaryrefslogtreecommitdiffstats
path: root/scripts/pybootchartgui
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/pybootchartgui')
-rw-r--r--scripts/pybootchartgui/pybootchartgui/draw.py210
-rw-r--r--scripts/pybootchartgui/pybootchartgui/parsing.py63
-rw-r--r--scripts/pybootchartgui/pybootchartgui/samples.py35
3 files changed, 292 insertions, 16 deletions
diff --git a/scripts/pybootchartgui/pybootchartgui/draw.py b/scripts/pybootchartgui/pybootchartgui/draw.py
index 53324b9f8b..4d76ce6e8e 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,10 +361,18 @@ 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:
343 h += meminfo_bar_h 373 h += meminfo_bar_h
374 if trace.net_stats:
375 h += (30 + bar_h) * len(trace.net_stats)
344 376
345 # Allow for width of process legend and offset 377 # Allow for width of process legend and offset
346 if w < (720 + off_x): 378 if w < (720 + off_x):
@@ -412,6 +444,151 @@ def render_charts(ctx, options, clip, trace, curr_y, w, h, sec_w):
412 444
413 curr_y = curr_y + 30 + bar_h 445 curr_y = curr_y + 30 + bar_h
414 446
447 if trace.net_stats:
448 for iface, samples in trace.net_stats.items():
449 max_received_sample = max(samples, key=lambda s: s.received_bytes)
450 max_transmitted_sample = max(samples, key=lambda s: s.transmitted_bytes)
451 max_receive_diff_sample = max(samples, key=lambda s: s.receive_diff)
452 max_transmit_diff_sample = max(samples, key=lambda s: s.transmit_diff)
453
454 draw_text(ctx, "Iface: %s" % (iface), TEXT_COLOR, off_x, curr_y+20)
455 draw_legend_line(ctx, "Bytes received (max %d)" % (max_received_sample.received_bytes),
456 BYTES_RECEIVED_COLOR, off_x+150, curr_y+20, leg_s)
457 draw_legend_line(ctx, "Bytes transmitted (max %d)" % (max_transmitted_sample.transmitted_bytes),
458 BYTES_TRANSMITTED_COLOR, off_x+400, curr_y+20, leg_s)
459 draw_legend_box(ctx, "Bytes receive diff (max %d)" % (max_receive_diff_sample.receive_diff),
460 BYTES_RECEIVE_DIFF_COLOR, off_x+650, curr_y+20, leg_s)
461 draw_legend_box(ctx, "Bytes transmit diff (max %d)" % (max_transmit_diff_sample.transmit_diff),
462 BYTES_TRANSMIT_DIFF_COLOR, off_x+900, curr_y+20, leg_s)
463
464
465 chart_rect = (off_x, curr_y + 30, w, bar_h)
466 if clip_visible(clip, chart_rect):
467 draw_box_ticks(ctx, chart_rect, sec_w)
468 draw_annotations(ctx, proc_tree, trace.times, chart_rect)
469
470 if clip_visible (clip, chart_rect):
471 draw_chart (ctx, BYTES_RECEIVED_COLOR, False, chart_rect, \
472 [(sample.time, sample.received_bytes) for sample in samples], \
473 proc_tree, None)
474
475 draw_chart (ctx, BYTES_TRANSMITTED_COLOR, False, chart_rect, \
476 [(sample.time, sample.transmitted_bytes) for sample in samples], \
477 proc_tree, None)
478
479 if clip_visible (clip, chart_rect):
480 draw_chart (ctx, BYTES_RECEIVE_DIFF_COLOR, True, chart_rect, \
481 [(sample.time, sample.receive_diff) for sample in samples], \
482 proc_tree, None)
483
484 draw_chart (ctx, BYTES_TRANSMIT_DIFF_COLOR, True, chart_rect, \
485 [(sample.time, sample.transmit_diff) for sample in samples], \
486 proc_tree, None)
487
488 curr_y = curr_y + 30 + bar_h
489
490 # render CPU pressure chart
491 if trace.cpu_pressure:
492 max_sample_avg = max (trace.cpu_pressure, key = lambda s: s.avg10)
493 max_sample_total = max (trace.cpu_pressure, key = lambda s: s.deltaTotal)
494 draw_legend_line(ctx, "avg10 CPU Pressure (max %d%%)" % (max_sample_avg.avg10), CPU_PRESSURE_AVG10_COLOR, off_x, curr_y+20, leg_s)
495 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)
496
497 # render delta total cpu
498 chart_rect = (off_x, curr_y+30, w, bar_h)
499 if clip_visible (clip, chart_rect):
500 draw_box_ticks (ctx, chart_rect, sec_w)
501 draw_annotations (ctx, proc_tree, trace.times, chart_rect)
502 draw_chart (ctx, CPU_PRESSURE_TOTAL_COLOR, True, chart_rect, \
503 [(sample.time, sample.deltaTotal) for sample in trace.cpu_pressure], \
504 proc_tree, None)
505
506 # render avg10 cpu
507 if clip_visible (clip, chart_rect):
508 draw_chart (ctx, CPU_PRESSURE_AVG10_COLOR, False, chart_rect, \
509 [(sample.time, sample.avg10) for sample in trace.cpu_pressure], \
510 proc_tree, None)
511
512 pos_x = off_x + ((max_sample_avg.time - proc_tree.start_time) * w / proc_tree.duration)
513
514 shift_x, shift_y = -20, 20
515 if (pos_x < off_x + 245):
516 shift_x, shift_y = 5, 40
517
518
519 label = "%d%%" % (max_sample_avg.avg10)
520 draw_text (ctx, label, CPU_PRESSURE_AVG10_COLOR, pos_x + shift_x, curr_y + shift_y)
521
522 curr_y = curr_y + 30 + bar_h
523
524 # render I/O pressure chart
525 if trace.io_pressure:
526 max_sample_avg = max (trace.io_pressure, key = lambda s: s.avg10)
527 max_sample_total = max (trace.io_pressure, key = lambda s: s.deltaTotal)
528 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)
529 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)
530
531 # render delta total io
532 chart_rect = (off_x, curr_y+30, w, bar_h)
533 if clip_visible (clip, chart_rect):
534 draw_box_ticks (ctx, chart_rect, sec_w)
535 draw_annotations (ctx, proc_tree, trace.times, chart_rect)
536 draw_chart (ctx, IO_PRESSURE_TOTAL_COLOR, True, chart_rect, \
537 [(sample.time, sample.deltaTotal) for sample in trace.io_pressure], \
538 proc_tree, None)
539
540 # render avg10 io
541 if clip_visible (clip, chart_rect):
542 draw_chart (ctx, IO_PRESSURE_AVG10_COLOR, False, chart_rect, \
543 [(sample.time, sample.avg10) for sample in trace.io_pressure], \
544 proc_tree, None)
545
546 pos_x = off_x + ((max_sample_avg.time - proc_tree.start_time) * w / proc_tree.duration)
547
548 shift_x, shift_y = -20, 20
549 if (pos_x < off_x + 245):
550 shift_x, shift_y = 5, 40
551
552
553 label = "%d%%" % (max_sample_avg.avg10)
554 draw_text (ctx, label, IO_PRESSURE_AVG10_COLOR, pos_x + shift_x, curr_y + shift_y)
555
556 curr_y = curr_y + 30 + bar_h
557
558 # render MEM pressure chart
559 if trace.mem_pressure:
560 max_sample_avg = max (trace.mem_pressure, key = lambda s: s.avg10)
561 max_sample_total = max (trace.mem_pressure, key = lambda s: s.deltaTotal)
562 draw_legend_line(ctx, "avg10 MEM Pressure (max %d%%)" % (max_sample_avg.avg10), MEM_PRESSURE_AVG10_COLOR, off_x, curr_y+20, leg_s)
563 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)
564
565 # render delta total mem
566 chart_rect = (off_x, curr_y+30, w, bar_h)
567 if clip_visible (clip, chart_rect):
568 draw_box_ticks (ctx, chart_rect, sec_w)
569 draw_annotations (ctx, proc_tree, trace.times, chart_rect)
570 draw_chart (ctx, MEM_PRESSURE_TOTAL_COLOR, True, chart_rect, \
571 [(sample.time, sample.deltaTotal) for sample in trace.mem_pressure], \
572 proc_tree, None)
573
574 # render avg10 mem
575 if clip_visible (clip, chart_rect):
576 draw_chart (ctx, MEM_PRESSURE_AVG10_COLOR, False, chart_rect, \
577 [(sample.time, sample.avg10) for sample in trace.mem_pressure], \
578 proc_tree, None)
579
580 pos_x = off_x + ((max_sample_avg.time - proc_tree.start_time) * w / proc_tree.duration)
581
582 shift_x, shift_y = -20, 20
583 if (pos_x < off_x + 245):
584 shift_x, shift_y = 5, 40
585
586
587 label = "%d%%" % (max_sample_avg.avg10)
588 draw_text (ctx, label, MEM_PRESSURE_AVG10_COLOR, pos_x + shift_x, curr_y + shift_y)
589
590 curr_y = curr_y + 30 + bar_h
591
415 # render disk space usage 592 # render disk space usage
416 # 593 #
417 # Draws the amount of disk space used on each volume relative to the 594 # Draws the amount of disk space used on each volume relative to the
@@ -493,8 +670,8 @@ def render_charts(ctx, options, clip, trace, curr_y, w, h, sec_w):
493 670
494 return curr_y 671 return curr_y
495 672
496def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w): 673def 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 ] 674 chart_rect = [off_x, curr_y+header_h, width, h - curr_y - 1 * off_y - header_h ]
498 675
499 draw_legend_box (ctx, "Configure", \ 676 draw_legend_box (ctx, "Configure", \
500 TASK_COLOR_CONFIGURE, off_x , curr_y + 45, leg_s) 677 TASK_COLOR_CONFIGURE, off_x , curr_y + 45, leg_s)
@@ -519,8 +696,9 @@ def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
519 offset = trace.min or min(trace.start.keys()) 696 offset = trace.min or min(trace.start.keys())
520 for start in sorted(trace.start.keys()): 697 for start in sorted(trace.start.keys()):
521 for process in sorted(trace.start[start]): 698 for process in sorted(trace.start[start]):
699 elapsed_time = trace.processes[process][1] - start
522 if not options.app_options.show_all and \ 700 if not options.app_options.show_all and \
523 trace.processes[process][1] - start < options.app_options.mintime: 701 elapsed_time < options.app_options.mintime:
524 continue 702 continue
525 task = process.split(":")[1] 703 task = process.split(":")[1]
526 704
@@ -529,14 +707,23 @@ def render_processes_chart(ctx, options, trace, curr_y, w, h, sec_w):
529 #print(s) 707 #print(s)
530 708
531 x = chart_rect[0] + (start - offset) * sec_w 709 x = chart_rect[0] + (start - offset) * sec_w
532 w = ((trace.processes[process][1] - start) * sec_w) 710 w = elapsed_time * sec_w
711
712 def set_alfa(color, alfa):
713 clist = list(color)
714 clist[-1] = alfa
715 return tuple(clist)
533 716
534 #print("proc at %s %s %s %s" % (x, y, w, proc_h)) 717 #print("proc at %s %s %s %s" % (x, y, w, proc_h))
535 col = None 718 col = None
536 if task == "do_compile": 719 if task == "do_compile":
537 col = TASK_COLOR_COMPILE 720 col = TASK_COLOR_COMPILE
721 elif "do_compile" in task:
722 col = set_alfa(TASK_COLOR_COMPILE, 0.25)
538 elif task == "do_configure": 723 elif task == "do_configure":
539 col = TASK_COLOR_CONFIGURE 724 col = TASK_COLOR_CONFIGURE
725 elif "do_configure" in task:
726 col = set_alfa(TASK_COLOR_CONFIGURE, 0.25)
540 elif task == "do_install": 727 elif task == "do_install":
541 col = TASK_COLOR_INSTALL 728 col = TASK_COLOR_INSTALL
542 elif task == "do_populate_sysroot": 729 elif task == "do_populate_sysroot":
@@ -554,7 +741,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)) 741 draw_fill_rect(ctx, col, (x, y, w, proc_h))
555 draw_rect(ctx, PROC_BORDER_COLOR, (x, y, w, proc_h)) 742 draw_rect(ctx, PROC_BORDER_COLOR, (x, y, w, proc_h))
556 743
557 draw_label_in_box(ctx, PROC_TEXT_COLOR, process, x, y + proc_h - 4, w, proc_h) 744 # Show elapsed time for each task
745 process = "%ds %s" % (elapsed_time, process)
746 draw_label_in_box(ctx, PROC_TEXT_COLOR, process, x, y + proc_h - 4, w, width)
747
558 y = y + proc_h 748 y = y + proc_h
559 749
560 return curr_y 750 return curr_y
@@ -656,7 +846,7 @@ def draw_header (ctx, headers, duration):
656 toshow = [ 846 toshow = [
657 ('system.uname', 'uname', lambda s: s), 847 ('system.uname', 'uname', lambda s: s),
658 ('system.release', 'release', lambda s: s), 848 ('system.release', 'release', lambda s: s),
659 ('system.cpu', 'CPU', lambda s: re.sub('model name\s*:\s*', '', s, 1)), 849 ('system.cpu', 'CPU', lambda s: re.sub(r'model name\s*:\s*', '', s, 1)),
660 ('system.kernel.options', 'kernel options', lambda s: s), 850 ('system.kernel.options', 'kernel options', lambda s: s),
661 ] 851 ]
662 852
@@ -695,7 +885,7 @@ def draw_processes_recursively(ctx, proc, proc_tree, y, proc_h, rect, clip) :
695 cmdString = proc.cmd 885 cmdString = proc.cmd
696 else: 886 else:
697 cmdString = '' 887 cmdString = ''
698 if (OPTIONS.show_pid or OPTIONS.show_all) and ipid is not 0: 888 if (OPTIONS.show_pid or OPTIONS.show_all) and ipid != 0:
699 cmdString = cmdString + " [" + str(ipid // 1000) + "]" 889 cmdString = cmdString + " [" + str(ipid // 1000) + "]"
700 if OPTIONS.show_all: 890 if OPTIONS.show_all:
701 if proc.args: 891 if proc.args:
@@ -793,7 +983,7 @@ class CumlSample:
793 if self.color is None: 983 if self.color is None:
794 i = self.next() % HSV_MAX_MOD 984 i = self.next() % HSV_MAX_MOD
795 h = 0.0 985 h = 0.0
796 if i is not 0: 986 if i != 0:
797 h = (1.0 * i) / HSV_MAX_MOD 987 h = (1.0 * i) / HSV_MAX_MOD
798 s = 0.5 988 s = 0.5
799 v = 1.0 989 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