|
9 | 9 | """Process list plugin."""
|
10 | 10 |
|
11 | 11 | import copy
|
| 12 | +import functools |
12 | 13 | import os
|
13 | 14 |
|
14 | 15 | from glances.globals import WINDOWS, key_exist_value_not_none_not_v, replace_special_chars
|
@@ -599,87 +600,127 @@ def __msg_curse_extended_process_program(self, ret, p):
|
599 | 600 | ret.append(self.curse_new_line())
|
600 | 601 | ret.append(self.curse_new_line())
|
601 | 602 |
|
602 |
| - def __msg_curse_extended_process_thread(self, ret, p): |
603 |
| - # Title |
| 603 | + def add_title_line(self, ret, prog): |
604 | 604 | ret.append(self.curse_add_line("Pinned thread ", "TITLE"))
|
605 |
| - ret.append(self.curse_add_line(p['name'], "UNDERLINE")) |
| 605 | + ret.append(self.curse_add_line(prog['name'], "UNDERLINE")) |
606 | 606 | ret.append(self.curse_add_line(" ('e' to unpin)"))
|
607 | 607 |
|
608 |
| - # First line is CPU affinity |
| 608 | + return ret |
| 609 | + |
| 610 | + def add_cpu_line(self, ret, prog): |
609 | 611 | ret.append(self.curse_new_line())
|
610 | 612 | ret.append(self.curse_add_line(' CPU Min/Max/Mean: '))
|
611 |
| - msg = '{: >7.1f}{: >7.1f}{: >7.1f}%'.format(p['cpu_min'], p['cpu_max'], p['cpu_mean']) |
| 613 | + msg = '{: >7.1f}{: >7.1f}{: >7.1f}%'.format(prog['cpu_min'], prog['cpu_max'], prog['cpu_mean']) |
612 | 614 | ret.append(self.curse_add_line(msg, decoration='INFO'))
|
613 |
| - if 'cpu_affinity' in p and p['cpu_affinity'] is not None: |
| 615 | + |
| 616 | + return ret |
| 617 | + |
| 618 | + def maybe_add_cpu_affinity_line(self, ret, prog): |
| 619 | + if 'cpu_affinity' in prog and prog['cpu_affinity'] is not None: |
614 | 620 | ret.append(self.curse_add_line(' Affinity: '))
|
615 |
| - ret.append(self.curse_add_line(str(len(p['cpu_affinity'])), decoration='INFO')) |
| 621 | + ret.append(self.curse_add_line(str(len(prog['cpu_affinity'])), decoration='INFO')) |
616 | 622 | ret.append(self.curse_add_line(' cores', decoration='INFO'))
|
617 |
| - if 'ionice' in p and p['ionice'] is not None and hasattr(p['ionice'], 'ioclass'): |
| 623 | + |
| 624 | + return ret |
| 625 | + |
| 626 | + def add_ionice_line(self, headers, default): |
| 627 | + def add_ionice_using_matches(msg, v): |
| 628 | + return msg + headers.get(v, default(v)) |
| 629 | + |
| 630 | + return add_ionice_using_matches |
| 631 | + |
| 632 | + def get_headers(self, k): |
| 633 | + # Linux: The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle. |
| 634 | + default = {0: 'No specific I/O priority', 1: k + 'Real Time', 2: k + 'Best Effort', 3: k + 'IDLE'} |
| 635 | + |
| 636 | + # Windows: On Windows only ioclass is used and it can be set to 2 (normal), 1 (low) or 0 (very low). |
| 637 | + windows = {0: k + 'Very Low', 1: k + 'Low', 2: 'No specific I/O priority'} |
| 638 | + |
| 639 | + return windows if WINDOWS else default |
| 640 | + |
| 641 | + def maybe_add_ionice_line(self, ret, prog): |
| 642 | + if 'ionice' in prog and prog['ionice'] is not None and hasattr(prog['ionice'], 'ioclass'): |
618 | 643 | msg = ' IO nice: '
|
619 | 644 | k = 'Class is '
|
620 |
| - v = p['ionice'].ioclass |
621 |
| - # Linux: The scheduling class. 0 for none, 1 for real time, 2 for best-effort, 3 for idle. |
622 |
| - # Windows: On Windows only ioclass is used and it can be set to 2 (normal), 1 (low) or 0 (very low). |
623 |
| - if WINDOWS: |
624 |
| - if v == 0: |
625 |
| - msg += k + 'Very Low' |
626 |
| - elif v == 1: |
627 |
| - msg += k + 'Low' |
628 |
| - elif v == 2: |
629 |
| - msg += 'No specific I/O priority' |
630 |
| - else: |
631 |
| - msg += k + str(v) |
632 |
| - else: |
633 |
| - if v == 0: |
634 |
| - msg += 'No specific I/O priority' |
635 |
| - elif v == 1: |
636 |
| - msg += k + 'Real Time' |
637 |
| - elif v == 2: |
638 |
| - msg += k + 'Best Effort' |
639 |
| - elif v == 3: |
640 |
| - msg += k + 'IDLE' |
641 |
| - else: |
642 |
| - msg += k + str(v) |
| 645 | + v = prog['ionice'].ioclass |
| 646 | + |
| 647 | + def default(v): |
| 648 | + return k + str(v) |
| 649 | + |
| 650 | + headers = self.get_headers(k) |
| 651 | + msg = self.add_ionice_line(headers, default)(msg, v) |
643 | 652 | # value is a number which goes from 0 to 7.
|
644 | 653 | # The higher the value, the lower the I/O priority of the process.
|
645 |
| - if hasattr(p['ionice'], 'value') and p['ionice'].value != 0: |
646 |
| - msg += ' (value {}/7)'.format(str(p['ionice'].value)) |
| 654 | + if hasattr(prog['ionice'], 'value') and prog['ionice'].value != 0: |
| 655 | + msg += ' (value {}/7)'.format(str(prog['ionice'].value)) |
647 | 656 | ret.append(self.curse_add_line(msg, splittable=True))
|
648 | 657 |
|
649 |
| - # Second line is memory info |
| 658 | + return ret |
| 659 | + |
| 660 | + def maybe_add_memory_swap_line(self, ret, prog): |
| 661 | + if 'memory_swap' in prog and prog['memory_swap'] is not None: |
| 662 | + ret.append( |
| 663 | + self.curse_add_line( |
| 664 | + self.auto_unit(prog['memory_swap'], low_precision=False), decoration='INFO', splittable=True |
| 665 | + ) |
| 666 | + ) |
| 667 | + ret.append(self.curse_add_line(' swap ', splittable=True)) |
| 668 | + |
| 669 | + return ret |
| 670 | + |
| 671 | + def add_memory_info_lines(self, ret, prog): |
| 672 | + for key, val in prog['memory_info'].items(): |
| 673 | + ret.append( |
| 674 | + self.curse_add_line( |
| 675 | + self.auto_unit(val, low_precision=False), |
| 676 | + decoration='INFO', |
| 677 | + splittable=True, |
| 678 | + ) |
| 679 | + ) |
| 680 | + ret.append(self.curse_add_line(' ' + key + ' ', splittable=True)) |
| 681 | + |
| 682 | + return ret |
| 683 | + |
| 684 | + def add_memory_line(self, ret, prog): |
650 | 685 | ret.append(self.curse_new_line())
|
651 | 686 | ret.append(self.curse_add_line(' MEM Min/Max/Mean: '))
|
652 |
| - msg = '{: >7.1f}{: >7.1f}{: >7.1f}%'.format(p['memory_min'], p['memory_max'], p['memory_mean']) |
| 687 | + msg = '{: >7.1f}{: >7.1f}{: >7.1f}%'.format(prog['memory_min'], prog['memory_max'], prog['memory_mean']) |
653 | 688 | ret.append(self.curse_add_line(msg, decoration='INFO'))
|
654 |
| - if 'memory_info' in p and p['memory_info'] is not None: |
| 689 | + if 'memory_info' in prog and prog['memory_info'] is not None: |
655 | 690 | ret.append(self.curse_add_line(' Memory info: '))
|
656 |
| - for k, v in p['memory_info'].items(): |
657 |
| - ret.append( |
658 |
| - self.curse_add_line( |
659 |
| - self.auto_unit(v, low_precision=False), |
660 |
| - decoration='INFO', |
661 |
| - splittable=True, |
662 |
| - ) |
663 |
| - ) |
664 |
| - ret.append(self.curse_add_line(' ' + k + ' ', splittable=True)) |
665 |
| - if 'memory_swap' in p and p['memory_swap'] is not None: |
666 |
| - ret.append( |
667 |
| - self.curse_add_line( |
668 |
| - self.auto_unit(p['memory_swap'], low_precision=False), decoration='INFO', splittable=True |
669 |
| - ) |
670 |
| - ) |
671 |
| - ret.append(self.curse_add_line(' swap ', splittable=True)) |
| 691 | + steps = [self.add_memory_info_lines, self.maybe_add_memory_swap_line] |
| 692 | + ret = functools.reduce(lambda ret, step: step(ret, prog), steps, ret) |
| 693 | + |
| 694 | + return ret |
672 | 695 |
|
673 |
| - # Third line is for open files/network sessions |
| 696 | + def add_io_and_network_lines(self, ret, prog): |
674 | 697 | ret.append(self.curse_new_line())
|
675 | 698 | ret.append(self.curse_add_line(' Open: '))
|
676 | 699 | for stat_prefix in ['num_threads', 'num_fds', 'num_handles', 'tcp', 'udp']:
|
677 |
| - if stat_prefix in p and p[stat_prefix] is not None: |
678 |
| - ret.append(self.curse_add_line(str(p[stat_prefix]), decoration='INFO')) |
| 700 | + if stat_prefix in prog and prog[stat_prefix] is not None: |
| 701 | + ret.append(self.curse_add_line(str(prog[stat_prefix]), decoration='INFO')) |
679 | 702 | ret.append(self.curse_add_line(' {} '.format(stat_prefix.replace('num_', ''))))
|
| 703 | + return ret |
680 | 704 |
|
681 |
| - ret.append(self.curse_new_line()) |
682 |
| - ret.append(self.curse_new_line()) |
| 705 | + def __msg_curse_extended_process_thread(self, ret, prog): |
| 706 | + # `append_newlines` has dummy arguments for piping thru `functools.reduce` |
| 707 | + def append_newlines(ret, prog): |
| 708 | + (ret.append(self.curse_new_line()),) |
| 709 | + ret.append(self.curse_new_line()) |
| 710 | + |
| 711 | + return ret |
| 712 | + |
| 713 | + steps = [ |
| 714 | + self.add_title_line, |
| 715 | + self.add_cpu_line, |
| 716 | + self.maybe_add_cpu_affinity_line, |
| 717 | + self.maybe_add_ionice_line, |
| 718 | + self.add_memory_line, |
| 719 | + self.add_io_and_network_lines, |
| 720 | + append_newlines, |
| 721 | + ] |
| 722 | + |
| 723 | + functools.reduce(lambda ret, step: step(ret, prog), steps, ret) |
683 | 724 |
|
684 | 725 | def __msg_curse_header(self, ret, process_sort_key, args=None):
|
685 | 726 | """Build the header and add it to the ret dict."""
|
|
0 commit comments