fileio.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import copy
  2. import struct
  3. fields = [
  4. ('cpu', 'f', [
  5. 'num_cpus',
  6. 'user', 'iowait', 'system', 'nice',
  7. 'guest', 'guest_nice',
  8. 'irq', 'softirq', 'steal', 'idle',
  9. ]),
  10. ('mem', 'q', ['total', 'used', 'buffers', 'cached']),
  11. ('net', 'q', [
  12. 'bytes_recv', 'bytes_sent',
  13. 'dropin', 'dropout', 'errin', 'errout',
  14. ]),
  15. ('disk', 'q', ['total', 'used']),
  16. ]
  17. def gen_template(val):
  18. template = {}
  19. for stat_group, _, subfields in fields:
  20. field_data = {}
  21. if stat_group != 'disk':
  22. for field in subfields:
  23. field_data[field] = copy.copy(val)
  24. template[stat_group] = field_data
  25. return template
  26. TEMPLATE = gen_template([-1] * 1440)
  27. def read_stats(f):
  28. stats = {}
  29. for stat_group, format_code, subfields in fields:
  30. field_data = {}
  31. fmt = '1440' + format_code
  32. if stat_group != 'disk':
  33. size = struct.calcsize(fmt)
  34. for field in subfields:
  35. field_data[field] = struct.unpack(fmt, f.read(size))
  36. else:
  37. buf = f.read() # disk is last, so we can read everything
  38. index = 0
  39. while index < len(buf):
  40. mountpoint_size = ord(buf[index])
  41. disk_fmt = '%dp %s %s' % (mountpoint_size + 1, fmt, fmt)
  42. size = struct.calcsize(disk_fmt)
  43. data = struct.unpack_from(disk_fmt, buf, index)
  44. mountpoint = data[0]
  45. total = data[1:1441]
  46. used = data[1441:]
  47. field_data[mountpoint] = {'used': used, 'total': total}
  48. index += size
  49. stats[stat_group] = field_data
  50. return stats
  51. def dict_insert(d, split, value):
  52. if len(split) > 1:
  53. d.setdefault(split[0], {})
  54. dict_insert(d[split[0]], split[1:], value)
  55. else:
  56. d[split[0]] = value
  57. def write_datum(f, data):
  58. for stat_group, format_code, subfields in fields:
  59. fmt = '1440' + format_code
  60. if stat_group != 'disk':
  61. for field in subfields:
  62. array = data[stat_group][field]
  63. f.write(struct.pack(fmt, *array))
  64. else:
  65. for mountpoint, disk_data in data['disk'].items():
  66. mountpoint = mountpoint.encode('utf-8')
  67. disk_fmt = '%dp %s %s' % (len(mountpoint) + 1, fmt, fmt)
  68. array = disk_data['total'] + disk_data['used']
  69. f.write(struct.pack(disk_fmt, mountpoint, *array))