From 1b2769996ac206b4ff9b88dcbce1e5302eed77d7 Mon Sep 17 00:00:00 2001 From: Swapnil Date: Mon, 24 Jun 2024 19:57:40 +0530 Subject: [PATCH 1/2] Added function to parse dmidecode output --- agent.py | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/agent.py b/agent.py index 4f0e9fc..23cc027 100644 --- a/agent.py +++ b/agent.py @@ -25,8 +25,70 @@ class ServerData: def __init__(self): self.hostname = os.uname().nodename self.public_ip = self.get_public_ip() + self.dmidecode_data = parse_dmidecode_output() logging.basicConfig(level=logging.INFO) + def parse_dmidecode_output(): + ''' + Example dmidecode output: + + Handle 0x0069, DMI type 20, 35 bytes + Memory Device Mapped Address + Starting Address: 0x00600000000 + Ending Address: 0x007FFFFFFFF + Range Size: 8 GB + Physical Device Handle: 0x0067 + Memory Array Mapped Address Handle: 0x006A + Partition Row Position: Unknown + Interleave Position: 2 + Interleaved Data Depth: 2 + + Handle 0x006A, DMI type 19, 31 bytes + Memory Array Mapped Address + Starting Address: 0x00000000000 + Ending Address: 0x007FFFFFFFF + Range Size: 32 GB + Physical Array Handle: 0x005E + Partition Width: 4 + ''' + if os.path.isfile('/usr/sbin/dmidecode'): + try: + # ignore error messages produced by the command + output = subprocess.check_output(['sudo', '/usr/sbin/dmidecode'], stderr=subprocess.DEVNULL).decode('utf-8') + + # each section is separated by two newlines + sections = output.split('\n\n') + parsed_sections = [] + for section in sections: + + # each line in a section is separated by a newline + lines = section.split('\n') + + # first line contains the DMI type - only need number + match = re.search(r'DMI type (\d+)', lines[0]) + if match: + dmi_type = int(match.group(1)) + else: # skip if no DMI type in this section + continue + + # each section is a dictionary with DMIType as key + section_dict = {'DMIType': dmi_type} + if len(lines) > 1: + section_dict['description'] = lines[1].strip() + + for line in lines[2:]: # skip first two lines - already processed + + # each line has tabs at the beginning and space(maybe optional) between key and value + match = re.match(r'\t(.+):\s*(.*)', line) + if match: + key, value = match.groups() + section_dict[key] = value + parsed_sections.append(section_dict) + return parsed_sections + except subprocess.CalledProcessError: + pass + return [] + def get_ram_and_disk(self): with open('/proc/meminfo', 'r') as f: meminfo = f.read() -- 2.45.1 From 52ecd2dc531a05c8fe37c53bb83d192ea78a8ecf Mon Sep 17 00:00:00 2001 From: Swapnil Date: Mon, 24 Jun 2024 20:06:21 +0530 Subject: [PATCH 2/2] Use parsed data in cpu count --- agent.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/agent.py b/agent.py index 23cc027..978ec7a 100644 --- a/agent.py +++ b/agent.py @@ -101,15 +101,11 @@ class ServerData: def get_cpu_count(self): cpu_count = 0 - if os.path.isfile('/usr/sbin/dmidecode'): - try: - output = subprocess.check_output(['sudo', '/usr/sbin/dmidecode', '-t', 'processor']).decode('utf-8') - core_match = re.search(r'Core Count: (\d+)', output) - thread_match = re.search(r'Thread Count: (\d+)', output) - if core_match and thread_match: - cpu_count = int(core_match.group(1)) * int(thread_match.group(1)) - except subprocess.CalledProcessError: - pass + for section in self.dmidecode_data: + if section['DMIType'] == 4: # 4 corresponds to processor + core_count = int(section.get('Core Count', '0')) + thread_count = int(section.get('Thread Count', '0')) + cpu_count = core_count * thread_count if cpu_count == 0: with open('/proc/cpuinfo', 'r') as f: cpuinfo = f.read() -- 2.45.1