| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- #!/usr/bin/env python
- import errno
- import json
- import os
- from os import path
- import struct
- import warnings
- warnings.filterwarnings('ignore', 'libevent')
- import gevent.pywsgi
- import reloader
- DATA_DIR = path.expanduser('~/sysvitals_data')
- handlers = None
- def main():
- global handlers
- handlers = {
- 'data': get_data,
- 'datum': post_datum,
- }
- server = gevent.pywsgi.WSGIServer(('0.0.0.0', 8892), application)
- reloader.init(server)
- server.serve_forever()
- def application(environ, start_response):
- split = environ['PATH_INFO'][1:].split('/')
- if split[0] == 'v1':
- handler = handlers.get(split[2])
- if handler:
- start_response('200 OK', [('Content-type', 'text/plain')])
- return [handler(split, environ)]
- else:
- print 'no handler for', split
- else:
- print 'split was', split
- formats = {
- 'cpu': 'f',
- 'mem': 'q',
- 'net': 'q',
- 'disk': 'q',
- }
- def get_data(split, environ):
- group = int(split[1])
- client_id = int(split[3])
- data_path = path.join(DATA_DIR, str(group), str(client_id))
- with open(data_path, 'r') as f:
- buf = f.read()
- rval = {}
- index = 0
- while index < len(buf):
- # read the key
- key_size = ord(buf[index])
- fmt = '%dp' % (key_size + 1)
- data = struct.unpack(fmt, buf[index:index+key_size+1])
- key = data[0]
- # get the format_code
- split = key.split('.')
- stat_group = split[0]
- format_code = formats[stat_group]
- # read the data
- fmt = '%dp 1440%s' % (key_size + 1, format_code)
- size = struct.calcsize(fmt)
- data = struct.unpack(fmt, buf[index:index+size])
- dict_insert(rval, split, data[1:])
- index += size
- return json.dumps(rval)
- def dict_insert(d, split, value):
- if len(split) > 1:
- d.setdefault(split[0], {})
- dict_insert(d[split[0]], split[1:], value)
- else:
- d[split[0]] = value
- def post_datum(split, environ):
- group = int(split[1])
- body = json.load(environ['wsgi.input'])
- client_id = body['client_id']
- group_dir = path.join(DATA_DIR, str(group))
- try:
- os.makedirs(group_dir)
- except OSError as e:
- if e.errno != errno.EEXIST:
- raise
- with open(path.join(group_dir, str(client_id)), 'w') as f:
- for stat_group, stats in body.items():
- if stat_group == 'client_id':
- continue
- format_code = formats[stat_group]
- for stat, data in stats.items():
- key = '%s.%s' % (stat_group, stat)
- write_stat(f, key.encode('utf-8'), format_code, data)
- return '{"status": "ok"}'
- def write_stat(f, key, format_code, data):
- fmt = '%dp 1440%s' % (len(key) + 1, format_code)
- array = [-1] * 1440
- array[0] = data
- f.write(struct.pack(fmt, key, *array))
- main()
|