Skip to content

Commit fddf1fa

Browse files
committed
Emit multiple reports like pidstat does
1 parent 7efa5cf commit fddf1fa

File tree

1 file changed

+114
-129
lines changed

1 file changed

+114
-129
lines changed

src/pcp/pidstat/pcp-pidstat.py

Lines changed: 114 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -590,16 +590,22 @@ def __matches_process_name(self, process):
590590
return True # all match
591591

592592
def __matches_process_priority(self, process):
593+
if not isinstance(process, ProcessPriority):
594+
return True
593595
if self.options.show_process_priority and process.priority() is not None:
594596
return process.priority() > 0
595597
return True
596598

597599
def __matches_process_memory_util(self, process):
600+
if not isinstance(process, ProcessMemoryUtil):
601+
return True
598602
if self.options.show_process_memory_util and process.vsize() is not None:
599603
return process.vsize() > 0
600604
return True
601605

602606
def __matches_process_stack_size(self, process):
607+
if not isinstance(process, ProcessStackUtil):
608+
return True
603609
if self.options.show_process_stack_util and process.stack_size() is not None:
604610
return process.stack_size() > 0
605611
return True
@@ -776,46 +782,63 @@ def Print(self, args):
776782

777783

778784
class PidstatOptions(pmapi.pmOptions):
779-
process_name = None
780-
process_name_with_args = False
781-
ps_args_flag=False
782-
show_process_cpu_util = False
783-
show_process_memory_util = False
784-
show_process_priority = False
785-
show_process_stack_util = False
786-
per_processor_usage = False
787-
show_process_user = False
788-
show_process_state = False
789-
flag_error = False
790-
filtered_process_user = None
791-
state = ""
792-
filterstate = []
793-
pid_filter = None
794-
pid_list = []
795-
timefmt = "%H:%M:%S"
785+
786+
#After reading in the provided command line options
787+
#initalize them by passing them in
788+
def __init__(self):
789+
pmapi.pmOptions.__init__(self,"a:s:t:G:IU::p:RrukVZ:z?:f:B:l")
790+
self.pmSetOptionCallback(self.extraOptions)
791+
self.pmSetOverrideCallback(self.override)
792+
self.pmSetLongOptionHeader("General options")
793+
self.pmSetLongOptionArchive()
794+
self.pmSetLongOptionSamples()
795+
self.pmSetLongOptionInterval()
796+
self.pmSetLongOption("process-name", 1, "G", "NAME",
797+
"Select process names using regular expression.")
798+
self.pmSetLongOption("", 0, "I", "", "Show CPU usage per processor.")
799+
self.pmSetLongOption("user-name", 2, "U","[USERNAME]",
800+
"Show real user name of the tasks and optionally filter by user name.")
801+
self.pmSetLongOption("pid-list", 1, "p", "PID1,PID2.. ",
802+
"Show stats for specified pids; " +
803+
"use SELF for current process and ALL for all processes.")
804+
self.pmSetLongOption("", 0, "R", "",
805+
"Report realtime priority and scheduling policy information.")
806+
self.pmSetLongOption("", 0,"r","","Report page faults and memory utilization.")
807+
self.pmSetLongOption("", 0,"u","","Report CPU utilization.")
808+
self.pmSetLongOption("", 0,"k","","Report stack utilization.")
809+
self.pmSetLongOption("", 0,"f","","Format the timestamp output")
810+
self.pmSetLongOption("", 0, "B", "state1,state2,..",
811+
"Report process state information. " +
812+
"Use -B [all] or -B [comma separated states]. " +
813+
"Use -B detail for showing time spent in every state per process")
814+
self.pmSetLongOptionVersion()
815+
self.pmSetLongOptionTimeZone()
816+
self.pmSetLongOptionHostZone()
817+
self.pmSetLongOption("", 0, "l", "", "Display the process command name and all its arguments.")
818+
self.pmSetLongOptionHelp()
819+
820+
self.process_name = None
821+
self.process_name_with_args = False
822+
self.ps_args_flag=False
823+
self.show_process_cpu_util = False
824+
self.show_process_memory_util = False
825+
self.show_process_priority = False
826+
self.show_process_stack_util = False
827+
self.per_processor_usage = False
828+
self.show_process_user = False
829+
self.show_process_state = False
830+
self.flag_error = False
831+
self.filtered_process_user = None
832+
self.state = ""
833+
self.filterstate = []
834+
self.pid_filter = None
835+
self.pid_list = []
836+
self.timefmt = "%H:%M:%S"
796837

797838
def checkOptions(self):
798-
if self.show_process_priority and self.show_process_memory_util:
799-
print("Error: -R is incompatible with -r")
800-
return False
801-
elif self.show_process_priority and self.show_process_stack_util:
802-
print("Error: -R is incompatible with -k")
803-
return False
804-
elif self.show_process_priority and self.show_process_cpu_util:
805-
print("Error: -R is incompatible with -u")
806-
return False
807-
elif self.show_process_memory_util and self.show_process_stack_util:
808-
print("Error: -r is incompatible with -k")
809-
return False
810-
elif self.show_process_memory_util and self.show_process_cpu_util:
811-
print("Error: -r is incompatible with -u")
812-
return False
813-
elif self.show_process_cpu_util and self.show_process_stack_util:
814-
print("Error: -u is incompatible with -k")
815-
return False
816-
elif (self.show_process_memory_util or self.show_process_stack_util or
817-
self.show_process_priority or self.show_process_cpu_util) and
818-
self.show_process_state:
839+
if ((self.show_process_memory_util or self.show_process_stack_util or
840+
self.show_process_priority or self.show_process_cpu_util) and
841+
self.show_process_state):
819842
print("Error: Incompatible flags provided")
820843
return False
821844
elif self.flag_error:
@@ -824,12 +847,12 @@ def checkOptions(self):
824847
elif self.ps_args_flag:
825848
print("Error: Incorrect usage of the -l flag")
826849
return False
827-
828-
if not self.show_process_state and not self.show_process_cpu_util:
829-
# Determine if we are defaulting to -u.
830-
if not any(self.show_process_memory_util, self.show_process_stack_util,
831-
self.show_process_priority):
832-
self.show_process_cpu_util = True
850+
elif self.show_process_state or self.show_process_cpu_util:
851+
return True
852+
# Determine if we are defaulting to -u.
853+
if not any([self.show_process_memory_util, self.show_process_stack_util,
854+
self.show_process_priority]):
855+
self.show_process_cpu_util = True
833856
return True
834857

835858
def extraOptions(self, opt, optarg, index):
@@ -902,44 +925,14 @@ def override(self, opt):
902925
""" Override standard PCP options to match pidstat(1) """
903926
return bool(opt == 'p')
904927

905-
#After reading in the provided command line options
906-
#initalize them by passing them in
907-
def __init__(self):
908-
pmapi.pmOptions.__init__(self,"a:s:t:G:IU::p:RrukVZ:z?:f:B:l")
909-
self.pmSetOptionCallback(self.extraOptions)
910-
self.pmSetOverrideCallback(self.override)
911-
self.pmSetLongOptionHeader("General options")
912-
self.pmSetLongOptionArchive()
913-
self.pmSetLongOptionSamples()
914-
self.pmSetLongOptionInterval()
915-
self.pmSetLongOption("process-name", 1, "G", "NAME",
916-
"Select process names using regular expression.")
917-
self.pmSetLongOption("", 0, "I", "", "Show CPU usage per processor.")
918-
self.pmSetLongOption("user-name", 2, "U","[USERNAME]",
919-
"Show real user name of the tasks and optionally filter by user name.")
920-
self.pmSetLongOption("pid-list", 1, "p", "PID1,PID2.. ",
921-
"Show stats for specified pids; " +
922-
"use SELF for current process and ALL for all processes.")
923-
self.pmSetLongOption("", 0, "R", "",
924-
"Report realtime priority and scheduling policy information.")
925-
self.pmSetLongOption("", 0,"r","","Report page faults and memory utilization.")
926-
self.pmSetLongOption("", 0,"u","","Report CPU utilization.")
927-
self.pmSetLongOption("", 0,"k","","Report stack utilization.")
928-
self.pmSetLongOption("", 0,"f","","Format the timestamp output")
929-
self.pmSetLongOption("", 0, "B", "state1,state2,..",
930-
"Report process state information. " +
931-
"Use -B [all] or -B [comma separated states]. " +
932-
"Use -B detail for showing time spent in every state per process")
933-
self.pmSetLongOptionVersion()
934-
self.pmSetLongOptionTimeZone()
935-
self.pmSetLongOptionHostZone()
936-
self.pmSetLongOption("", 0, "l", "", "Display the process command name and all its arguments.")
937-
self.pmSetLongOptionHelp()
938-
939928

940929
class PidstatReport(pmcc.MetricGroupPrinter):
941930
Machine_info_count = 0
942931

932+
def __init__(self, opts):
933+
pmcc.MetricGroupPrinter.__init__(self)
934+
self.opts = opts
935+
943936
def timeStampDelta(self, group):
944937
s = group.timestamp.tv_sec - group.prevTimestamp.tv_sec
945938
u = group.timestamp.tv_usec - group.prevTimestamp.tv_usec
@@ -982,73 +975,65 @@ def report(self,manager):
982975
return
983976

984977
ts = group.contextCache.pmLocaltime(int(group.timestamp))
985-
timestamp = time.strftime(PidstatOptions.timefmt, ts.struct_time())
978+
timestamp = time.strftime(self.opts.timefmt, ts.struct_time())
986979
interval_in_seconds = self.timeStampDelta(group)
987980
header_indentation = " " if len(timestamp)<9 else (len(timestamp)-7)*" "
988981
value_indentation = ((len(header_indentation)+9)-len(timestamp))*" "
989982

990983
metric_repository = ReportingMetricRepository(group)
991984

992-
if PidstatOptions.show_process_stack_util:
993-
process_stack_util = CpuProcessStackUtil(metric_repository)
994-
process_filter = ProcessFilter(PidstatOptions)
995-
stdout = StdoutPrinter()
996-
printdecorator = NoneHandlingPrinterDecorator(stdout)
997-
report = CpuProcessStackUtilReporter(process_stack_util, process_filter,
998-
printdecorator.Print, PidstatOptions)
999-
1000-
report.print_report(timestamp, header_indentation, value_indentation)
1001-
1002-
#===========================================================================================================
1003-
elif PidstatOptions.show_process_memory_util:
1004-
process_memory_util = CpuProcessMemoryUtil(metric_repository)
1005-
process_filter = ProcessFilter(PidstatOptions)
1006-
stdout = StdoutPrinter()
1007-
printdecorator = NoneHandlingPrinterDecorator(stdout)
1008-
report = CpuProcessMemoryUtilReporter(process_memory_util, process_filter,
1009-
interval_in_seconds,
1010-
printdecorator.Print, PidstatOptions)
1011-
1012-
report.print_report(timestamp, header_indentation, value_indentation)
1013-
1014-
#===========================================================================================================
1015-
elif PidstatOptions.show_process_priority:
1016-
process_priority = CpuProcessPriorities(metric_repository)
1017-
process_filter = ProcessFilter(PidstatOptions)
1018-
stdout = StdoutPrinter()
1019-
printdecorator = NoneHandlingPrinterDecorator(stdout)
1020-
report = CpuProcessPrioritiesReporter(process_priority, process_filter,
1021-
printdecorator.Print, PidstatOptions)
1022-
1023-
report.print_report(timestamp, header_indentation, value_indentation)
1024-
1025-
#===========================================================================================================
1026-
elif PidstatOptions.show_process_state:
985+
if self.opts.show_process_state:
1027986
process_state = CpuProcessState(metric_repository)
1028-
process_filter = ProcessFilter(PidstatOptions)
987+
process_filter = ProcessFilter(self.opts)
1029988
stdout = StdoutPrinter()
1030989
printdecorator = NoneHandlingPrinterDecorator(stdout)
1031990
report = CpuProcessStateReporter(process_state, process_filter,
1032991
interval_in_seconds,
1033-
printdecorator.Print, PidstatOptions)
1034-
992+
printdecorator.Print, self.opts)
1035993
report.print_report(timestamp, header_indentation, value_indentation)
1036-
1037-
#===========================================================================================================
1038-
elif PidstatOptions.show_process_cpu_util:
1039-
cpu_usage = CpuUsage(metric_repository)
1040-
process_filter = ProcessFilter(PidstatOptions)
1041-
stdout = StdoutPrinter()
1042-
printdecorator = NoneHandlingPrinterDecorator(stdout)
1043-
report = CpuUsageReporter(cpu_usage, process_filter, interval_in_seconds,
1044-
printdecorator.Print, PidstatOptions)
1045-
report.print_report(timestamp, ncpu, header_indentation, value_indentation)
994+
else:
995+
if self.opts.show_process_stack_util:
996+
process_stack_util = CpuProcessStackUtil(metric_repository)
997+
process_filter = ProcessFilter(self.opts)
998+
stdout = StdoutPrinter()
999+
printdecorator = NoneHandlingPrinterDecorator(stdout)
1000+
report = CpuProcessStackUtilReporter(process_stack_util, process_filter,
1001+
printdecorator.Print, self.opts)
1002+
report.print_report(timestamp, header_indentation, value_indentation)
1003+
1004+
if self.opts.show_process_memory_util:
1005+
process_memory_util = CpuProcessMemoryUtil(metric_repository)
1006+
process_filter = ProcessFilter(self.opts)
1007+
stdout = StdoutPrinter()
1008+
printdecorator = NoneHandlingPrinterDecorator(stdout)
1009+
report = CpuProcessMemoryUtilReporter(process_memory_util, process_filter,
1010+
interval_in_seconds,
1011+
printdecorator.Print, self.opts)
1012+
report.print_report(timestamp, header_indentation, value_indentation)
1013+
1014+
if self.opts.show_process_priority:
1015+
process_priority = CpuProcessPriorities(metric_repository)
1016+
process_filter = ProcessFilter(self.opts)
1017+
stdout = StdoutPrinter()
1018+
printdecorator = NoneHandlingPrinterDecorator(stdout)
1019+
report = CpuProcessPrioritiesReporter(process_priority, process_filter,
1020+
printdecorator.Print, self.opts)
1021+
report.print_report(timestamp, header_indentation, value_indentation)
1022+
1023+
if self.opts.show_process_cpu_util:
1024+
cpu_usage = CpuUsage(metric_repository)
1025+
process_filter = ProcessFilter(self.opts)
1026+
stdout = StdoutPrinter()
1027+
printdecorator = NoneHandlingPrinterDecorator(stdout)
1028+
report = CpuUsageReporter(cpu_usage, process_filter, interval_in_seconds,
1029+
printdecorator.Print, self.opts)
1030+
report.print_report(timestamp, ncpu, header_indentation, value_indentation)
10461031

10471032

10481033
if __name__ == "__main__":
10491034
try:
10501035
opts = PidstatOptions()
1051-
manager = pmcc.MetricGroupManager.builder(opts,sys.argv)
1036+
manager = pmcc.MetricGroupManager.builder(opts, sys.argv)
10521037
if not opts.checkOptions():
10531038
raise pmapi.pmUsageErr
10541039
if opts.show_process_state:
@@ -1062,7 +1047,7 @@ def report(self,manager):
10621047
sys.stderr.write('Error: not all required metrics are available\nMissing %s\n' % (missing))
10631048
sys.exit(1)
10641049
manager['pidstat'] = metrics_list
1065-
manager.printer = PidstatReport()
1050+
manager.printer = PidstatReport(opts)
10661051
sts = manager.run()
10671052
sys.exit(sts)
10681053
except pmapi.pmErr as pmerror:

0 commit comments

Comments
 (0)