Skip to content

Commit 7efa5cf

Browse files
committed
Add the pcp pidstat -u option
1 parent 8c1d05c commit 7efa5cf

File tree

1 file changed

+63
-43
lines changed

1 file changed

+63
-43
lines changed

src/pcp/pidstat/pcp-pidstat.py

Lines changed: 63 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -779,6 +779,7 @@ class PidstatOptions(pmapi.pmOptions):
779779
process_name = None
780780
process_name_with_args = False
781781
ps_args_flag=False
782+
show_process_cpu_util = False
782783
show_process_memory_util = False
783784
show_process_priority = False
784785
show_process_stack_util = False
@@ -800,11 +801,21 @@ def checkOptions(self):
800801
elif self.show_process_priority and self.show_process_stack_util:
801802
print("Error: -R is incompatible with -k")
802803
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
803807
elif self.show_process_memory_util and self.show_process_stack_util:
804808
print("Error: -r is incompatible with -k")
805809
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
806816
elif (self.show_process_memory_util or self.show_process_stack_util or
807-
self.show_process_priority) and self.show_process_state:
817+
self.show_process_priority or self.show_process_cpu_util) and
818+
self.show_process_state:
808819
print("Error: Incompatible flags provided")
809820
return False
810821
elif self.flag_error:
@@ -813,72 +824,79 @@ def checkOptions(self):
813824
elif self.ps_args_flag:
814825
print("Error: Incorrect usage of the -l flag")
815826
return False
816-
else:
817-
return True
818827

819-
def extraOptions(self, opt,optarg, index):
820-
if opt == 'k':
821-
PidstatOptions.show_process_stack_util = True
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
833+
return True
834+
835+
def extraOptions(self, opt, optarg, index):
836+
if opt == 'u':
837+
self.show_process_cpu_util = True
838+
elif opt == 'k':
839+
self.show_process_stack_util = True
822840
elif opt == 'r':
823-
PidstatOptions.show_process_memory_util = True
841+
self.show_process_memory_util = True
824842
elif opt == 'R':
825-
PidstatOptions.show_process_priority = True
826-
#process state
843+
self.show_process_priority = True
827844
elif opt == 'B':
828-
if PidstatOptions.show_process_state:
845+
#process state
846+
if self.show_process_state:
829847
#print("Error: Cannot use -B multiple times")
830-
PidstatOptions.flag_error = True
831-
PidstatOptions.show_process_state = True
848+
self.flag_error = True
849+
self.show_process_state = True
832850
if optarg in ["All", "all"]:
833-
PidstatOptions.filterstate = "all"
851+
self.filterstate = "all"
834852
elif optarg in ["detail", "Detail"]:
835-
PidstatOptions.filterstate = "detail"
853+
self.filterstate = "detail"
836854
else:
837855
# tried to handle the error usage like pcp-pidstat.py -B all R,S
838856
# or pcp-pidstat.py -B detail all
839857
# or pcp-pidstat.py -B R all, etc but seems like the first optarg is all we have and
840858
# we ignore the following ones. So pcp-pidstat.py -B detail all will treat it as
841859
# pcp.pidstat.py -B detail
842860

843-
#if not PidstatOptions.flag_error:
844-
# if (PidstatOptions.filterstate == "all" or PidstatOptions.filterstate == "detail"):
861+
#if not self.flag_error:
862+
# if (self.filterstate == "all" or self.filterstate == "detail"):
845863
# print("Error: Use either all/detail or specific filters for states")
846-
# PidstatOptions.flag_error = True
864+
# self.flag_error = True
847865
# else:
848866

849867
# need to put checks for correct states in this string like UN,TT
850868
# shouldnt be accepted because TT isnt a valid state
851869
# TODO: make sure only R,S,T,D,Z are part of this optarg so if
852870
# anything other than these exists in
853-
# PidstatOptions.filterstate, we might want to flag error of usage ?
871+
# self.filterstate, we might want to flag error of usage ?
854872

855-
PidstatOptions.filterstate += optarg.replace(',', ' ').split(' ')
873+
self.filterstate += optarg.replace(',', ' ').split(' ')
856874
elif opt == 'G':
857-
PidstatOptions.process_name = optarg
875+
self.process_name = optarg
858876
elif opt == 'I':
859-
PidstatOptions.per_processor_usage = True
877+
self.per_processor_usage = True
860878
elif opt == 'U':
861-
PidstatOptions.show_process_user = True
862-
PidstatOptions.filtered_process_user = optarg
879+
self.show_process_user = True
880+
self.filtered_process_user = optarg
863881
elif opt == 'p':
864882
if optarg == "ALL":
865-
PidstatOptions.pid_filter = None
883+
self.pid_filter = None
866884
elif optarg == "SELF":
867-
PidstatOptions.pid_filter = "SELF"
868-
PidstatOptions.pid_list = os.getpid()
885+
self.pid_filter = "SELF"
886+
self.pid_list = os.getpid()
869887
else:
870-
PidstatOptions.pid_filter = "LIST"
888+
self.pid_filter = "LIST"
871889
try:
872-
PidstatOptions.pid_list = list(map(lambda x:int(x),optarg.split(',')))
890+
self.pid_list = list(map(lambda x:int(x),optarg.split(',')))
873891
except ValueError:
874892
print("Invalid Process Id List: use comma separated pids without whitespaces")
875893
sys.exit(1)
876894
elif opt == 'f':
877-
PidstatOptions.timefmt = optarg
895+
self.timefmt = optarg
878896
elif opt == 'l':
879-
if PidstatOptions.process_name_with_args:
880-
PidstatOptions.ps_args_flag=True
881-
PidstatOptions.process_name_with_args = True
897+
if self.process_name_with_args:
898+
self.ps_args_flag=True
899+
self.process_name_with_args = True
882900

883901
def override(self, opt):
884902
""" Override standard PCP options to match pidstat(1) """
@@ -887,7 +905,7 @@ def override(self, opt):
887905
#After reading in the provided command line options
888906
#initalize them by passing them in
889907
def __init__(self):
890-
pmapi.pmOptions.__init__(self,"a:s:t:G:IU::p:RrkVZ:z?:f:B:l")
908+
pmapi.pmOptions.__init__(self,"a:s:t:G:IU::p:RrukVZ:z?:f:B:l")
891909
self.pmSetOptionCallback(self.extraOptions)
892910
self.pmSetOverrideCallback(self.override)
893911
self.pmSetLongOptionHeader("General options")
@@ -905,6 +923,7 @@ def __init__(self):
905923
self.pmSetLongOption("", 0, "R", "",
906924
"Report realtime priority and scheduling policy information.")
907925
self.pmSetLongOption("", 0,"r","","Report page faults and memory utilization.")
926+
self.pmSetLongOption("", 0,"u","","Report CPU utilization.")
908927
self.pmSetLongOption("", 0,"k","","Report stack utilization.")
909928
self.pmSetLongOption("", 0,"f","","Format the timestamp output")
910929
self.pmSetLongOption("", 0, "B", "state1,state2,..",
@@ -979,6 +998,8 @@ def report(self,manager):
979998
printdecorator.Print, PidstatOptions)
980999

9811000
report.print_report(timestamp, header_indentation, value_indentation)
1001+
1002+
#===========================================================================================================
9821003
elif PidstatOptions.show_process_memory_util:
9831004
process_memory_util = CpuProcessMemoryUtil(metric_repository)
9841005
process_filter = ProcessFilter(PidstatOptions)
@@ -989,6 +1010,8 @@ def report(self,manager):
9891010
printdecorator.Print, PidstatOptions)
9901011

9911012
report.print_report(timestamp, header_indentation, value_indentation)
1013+
1014+
#===========================================================================================================
9921015
elif PidstatOptions.show_process_priority:
9931016
process_priority = CpuProcessPriorities(metric_repository)
9941017
process_filter = ProcessFilter(PidstatOptions)
@@ -1010,8 +1033,9 @@ def report(self,manager):
10101033
printdecorator.Print, PidstatOptions)
10111034

10121035
report.print_report(timestamp, header_indentation, value_indentation)
1036+
10131037
#===========================================================================================================
1014-
else:
1038+
elif PidstatOptions.show_process_cpu_util:
10151039
cpu_usage = CpuUsage(metric_repository)
10161040
process_filter = ProcessFilter(PidstatOptions)
10171041
stdout = StdoutPrinter()
@@ -1028,20 +1052,16 @@ def report(self,manager):
10281052
if not opts.checkOptions():
10291053
raise pmapi.pmUsageErr
10301054
if opts.show_process_state:
1031-
missing = manager.checkMissingMetrics(PIDSTAT_METRICS_B)
1055+
metrics_list = PIDSTAT_METRICS_B
10321056
elif opts.process_name_with_args:
1033-
missing = manager.checkMissingMetrics(PIDSTAT_METRICS_L)
1057+
metrics_list = PIDSTAT_METRICS_L
10341058
else:
1035-
missing = manager.checkMissingMetrics(PIDSTAT_METRICS)
1059+
metrics_list = PIDSTAT_METRICS
1060+
missing = manager.checkMissingMetrics(metrics_list)
10361061
if missing is not None:
10371062
sys.stderr.write('Error: not all required metrics are available\nMissing %s\n' % (missing))
10381063
sys.exit(1)
1039-
if opts.process_name_with_args:
1040-
manager['pidstat'] = PIDSTAT_METRICS_L
1041-
elif opts.show_process_state:
1042-
manager['pidstat'] = PIDSTAT_METRICS_B
1043-
else:
1044-
manager['pidstat'] = PIDSTAT_METRICS
1064+
manager['pidstat'] = metrics_list
10451065
manager.printer = PidstatReport()
10461066
sts = manager.run()
10471067
sys.exit(sts)

0 commit comments

Comments
 (0)