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()