[procdockerstatsd] Convert to Python 3 (#5657)

Make procdockerstatsd Python 3-compliant and set interpreter to python3 in shebang. Also some other cleanup to improve code reuse.
This commit is contained in:
Joe LeVeque 2020-10-19 09:46:02 -07:00 committed by GitHub
parent 8011edc307
commit 678b66359d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
'''
procdockerstatsd
Daemon which periodically gathers process and docker statistics and pushes the data to STATE_DB
@ -29,7 +29,7 @@ class ProcDockerStats(daemon_base.DaemonBase):
self.state_db.connect("STATE_DB")
def run_command(self, cmd):
proc = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
proc = subprocess.Popen(cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE)
(stdout, stderr) = proc.communicate()
if proc.returncode != 0:
self.log_error("Error running command '{}'".format(cmd))
@ -38,87 +38,79 @@ class ProcDockerStats(daemon_base.DaemonBase):
return stdout
def format_docker_cmd_output(self, cmdout):
lines = re.split("\n", cmdout)
lines = cmdout.splitlines()
keys = re.split(" +", lines[0])
docker_data = dict()
docker_data_list = []
for item in lines[1:]:
values1 = re.split(" +", item)
docker_data = dict(zip(keys, values1))
for line in lines[1:]:
values = re.split(" +", line)
docker_data = {key: value for key, value in zip(keys, values)}
docker_data_list.append(docker_data)
formatted_dict = self.create_docker_dict(docker_data_list)
return formatted_dict
def format_process_cmd_output(self, cmdout):
lines = re.split("\n", cmdout)
lines = cmdout.splitlines()
keys = re.split(" +", lines[0])
keylist = list(filter(None, keys))
key_list = [key for key in keys if key]
process_data = dict()
process_data_list = []
for item in lines[1:]:
values1 = re.split(" +", str(item))
for line in lines[1:]:
values = re.split(" +", line)
# To remove extra space before UID
val = list(filter(None, values1))
val_list = [val for val in values if val]
# Merging extra columns created due to space in cmd ouput
val[8:] = [' '.join(val[8:])]
process_data = dict(zip(keylist, val))
val_list[8:] = [' '.join(val_list[8:])]
process_data = {key: value for key, value in zip(key_list, val_list)}
process_data_list.append(process_data)
return process_data_list
def convert_to_bytes(self, value):
unit_value = re.search('[a-zA-Z]+', value)
value_to_convert = float(filter(str.isdigit, value))
unit = unit_value.group(0)
UNITS_B = 'B'
UNITS_KB = 'KB'
UNITS_MB = 'MB'
UNITS_MiB = 'MiB'
UNITS_GiB = 'GiB'
if unit.lower() == UNITS_B.lower():
return int(round(value_to_convert))
elif unit.lower() == UNITS_KB.lower():
value_converted = value_to_convert * 1000
return int(round(value_converted))
elif unit.lower() == UNITS_MB.lower():
value_converted = value_to_convert * 1000 * 1000
return int(round(value_converted))
elif unit.lower() == UNITS_MiB.lower():
value_converted = value_to_convert * 1024 * 1024
return int(round(value_converted))
elif unit.lower() == UNITS_GiB.lower():
value_converted = value_to_convert * 1024 * 1024 * 1024
return int(round(value_converted))
res = re.match('(\d+\.?\d*)([a-zA-Z]+)', value)
value = float(res.groups()[0])
units = res.groups()[1]
if units.lower() == UNITS_KB.lower():
value *= 1000
elif units.lower() == UNITS_MB.lower():
value *= (1000 * 1000)
elif units.lower() == UNITS_MiB.lower():
value *= (1024 * 1024)
elif units.lower() == UNITS_GiB.lower():
value *= (1024 * 1024 * 1024)
return int(round(value))
def create_docker_dict(self, dict_list):
dockerdict = {}
for row in dict_list[0:]:
cid = row.get('CONTAINER ID')
if cid:
key = 'DOCKER_STATS|' + str(cid)
key = 'DOCKER_STATS|{}'.format(cid)
dockerdict[key] = {}
dockerdict[key]['NAME'] = row.get('NAME')
splitcol = row.get('CPU %')
cpu = re.split("%", str(splitcol))
cpu = row.get('CPU %').split("%")
dockerdict[key]['CPU%'] = str(cpu[0])
splitcol = row.get('MEM USAGE / LIMIT')
memuse = re.split(" / ", str(splitcol))
memuse = row.get('MEM USAGE / LIMIT').split(" / ")
# converting MiB and GiB to bytes
dockerdict[key]['MEM_BYTES'] = str(self.convert_to_bytes(memuse[0]))
dockerdict[key]['MEM_LIMIT_BYTES'] = str(self.convert_to_bytes(memuse[1]))
splitcol = row.get('MEM %')
mem = re.split("%", str(splitcol))
mem = row.get('MEM %').split("%")
dockerdict[key]['MEM%'] = str(mem[0])
splitcol = row.get('NET I/O')
netio = re.split(" / ", str(splitcol))
netio = row.get('NET I/O').split(" / ")
dockerdict[key]['NET_IN_BYTES'] = str(self.convert_to_bytes(netio[0]))
dockerdict[key]['NET_OUT_BYTES'] = str(self.convert_to_bytes(netio[1]))
splitcol = row.get('BLOCK I/O')
blockio = re.split(" / ", str(splitcol))
blockio = row.get('BLOCK I/O').split(" / ")
dockerdict[key]['BLOCK_IN_BYTES'] = str(self.convert_to_bytes(blockio[0]))
dockerdict[key]['BLOCK_OUT_BYTES'] = str(self.convert_to_bytes(blockio[1]))
@ -137,8 +129,8 @@ class ProcDockerStats(daemon_base.DaemonBase):
return False
# wipe out all data from state_db before updating
self.state_db.delete_all_by_pattern('STATE_DB', 'DOCKER_STATS|*')
for k1,v1 in dockerdata.iteritems():
for k2,v2 in v1.iteritems():
for k1,v1 in dockerdata.items():
for k2,v2 in v1.items():
self.update_state_db(k1, k2, v2)
return True
@ -151,7 +143,7 @@ class ProcDockerStats(daemon_base.DaemonBase):
for row in processdata[0:]:
cid = row.get('PID')
if cid:
value = 'PROCESS_STATS|' + str(cid)
value = 'PROCESS_STATS|{}'.format(cid)
uid = row.get('UID')
self.update_state_db(value, 'UID', uid)
ppid = row.get('PPID')
@ -206,4 +198,3 @@ def main():
if __name__ == '__main__':
main()