blob: cdbe9fc2dadbc9897c799d9e2871c9231ade4dda [file] [log] [blame]
koder aka kdanilovdda86d32015-03-16 11:20:04 +02001import os
2import sys
3import time
4import json
koder aka kdanilove06762a2015-03-22 23:32:09 +02005import glob
koder aka kdanilovdda86d32015-03-16 11:20:04 +02006import signal
7import os.path
8import argparse
9
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030010from .sensors.utils import SensorInfo
11from .daemonize import Daemonize
12from .discover import all_sensors
13from .protocol import create_protocol
koder aka kdanilovdda86d32015-03-16 11:20:04 +020014
15
koder aka kdanilove06762a2015-03-22 23:32:09 +020016# load all sensors
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030017from . import sensors
koder aka kdanilove06762a2015-03-22 23:32:09 +020018sensors_dir = os.path.dirname(sensors.__file__)
19for fname in glob.glob(os.path.join(sensors_dir, "*.py")):
20 mod_name = os.path.basename(fname[:-3])
koder aka kdanilovcff7b2e2015-04-18 20:48:15 +030021 __import__("sensors.sensors." + mod_name)
koder aka kdanilove06762a2015-03-22 23:32:09 +020022
23
koder aka kdanilovdda86d32015-03-16 11:20:04 +020024def get_values(required_sensors):
25 result = {}
26 for sensor_name, params in required_sensors:
27 if sensor_name in all_sensors:
28 result.update(all_sensors[sensor_name](**params))
29 else:
30 msg = "Sensor {0!r} isn't available".format(sensor_name)
31 raise ValueError(msg)
32 return time.time(), result
33
34
35def parse_args(args):
36 parser = argparse.ArgumentParser()
37 parser.add_argument('-d', '--daemon',
38 choices=('start', 'stop', 'status'),
39 default=None)
40
41 parser.add_argument('-u', '--url', default='stdout://')
42 parser.add_argument('-t', '--timeout', type=float, default=1)
koder aka kdanilov8097a4e2015-03-18 11:07:35 +020043 parser.add_argument('-l', '--list-sensors', action='store_true')
koder aka kdanilovdda86d32015-03-16 11:20:04 +020044 parser.add_argument('sensors_config', type=argparse.FileType('r'),
45 default=None, nargs='?')
46 return parser.parse_args(args[1:])
47
48
49def daemon_main(required_sensors, opts):
koder aka kdanilove87ae652015-04-20 02:14:35 +030050 try:
51 source_id = str(required_sensors.pop('source_id'))
52 except KeyError:
53 source_id = None
koder aka kdanilov168f6092015-04-19 02:33:38 +030054
Alyona Kiseleva7f6de4f2015-04-21 01:04:20 +030055 sender = create_protocol(opts.url)
56 prev = {}
57
koder aka kdanilove87ae652015-04-20 02:14:35 +030058 while True:
koder aka kdanilovdda86d32015-03-16 11:20:04 +020059 gtime, data = get_values(required_sensors.items())
60 curr = {'time': SensorInfo(gtime, True)}
61 for name, val in data.items():
62 if val.is_accumulated:
63 if name in prev:
64 curr[name] = SensorInfo(val.value - prev[name], True)
65 prev[name] = val.value
66 else:
67 curr[name] = SensorInfo(val.value, False)
koder aka kdanilov168f6092015-04-19 02:33:38 +030068
69 if source_id is not None:
70 curr['source_id'] = source_id
71
koder aka kdanilovdda86d32015-03-16 11:20:04 +020072 sender.send(curr)
Alyona Kiseleva7f6de4f2015-04-21 01:04:20 +030073
koder aka kdanilovdda86d32015-03-16 11:20:04 +020074 time.sleep(opts.timeout)
75
76
koder aka kdanilov2c473092015-03-29 17:12:13 +030077def pid_running(pid):
78 return os.path.exists("/proc/" + str(pid))
79
80
koder aka kdanilovdda86d32015-03-16 11:20:04 +020081def main(argv):
82 opts = parse_args(argv)
83
koder aka kdanilov8097a4e2015-03-18 11:07:35 +020084 if opts.list_sensors:
koder aka kdanilove06762a2015-03-22 23:32:09 +020085 print "\n".join(sorted(all_sensors))
koder aka kdanilov8097a4e2015-03-18 11:07:35 +020086 return 0
87
koder aka kdanilovdda86d32015-03-16 11:20:04 +020088 if opts.daemon is not None:
89 pid_file = "/tmp/sensors.pid"
90 if opts.daemon == 'start':
91 required_sensors = json.loads(opts.sensors_config.read())
92
Alyona Kiseleva7f6de4f2015-04-21 01:04:20 +030093 if "protocol_data" not in required_sensors:
94 raise ValueError("No protocol data provided in config")
95
koder aka kdanilovdda86d32015-03-16 11:20:04 +020096 def root_func():
97 daemon_main(required_sensors, opts)
98
99 daemon = Daemonize(app="perfcollect_app",
100 pid=pid_file,
101 action=root_func)
102 daemon.start()
103 elif opts.daemon == 'stop':
104 if os.path.isfile(pid_file):
105 pid = int(open(pid_file).read())
koder aka kdanilov2c473092015-03-29 17:12:13 +0300106 if pid_running(pid):
koder aka kdanilovdda86d32015-03-16 11:20:04 +0200107 os.kill(pid, signal.SIGTERM)
108
109 time.sleep(0.1)
110
koder aka kdanilov2c473092015-03-29 17:12:13 +0300111 if pid_running(pid):
koder aka kdanilovdda86d32015-03-16 11:20:04 +0200112 os.kill(pid, signal.SIGKILL)
113
114 if os.path.isfile(pid_file):
115 os.unlink(pid_file)
116 elif opts.daemon == 'status':
117 if os.path.isfile(pid_file):
118 pid = int(open(pid_file).read())
koder aka kdanilov2c473092015-03-29 17:12:13 +0300119 if pid_running(pid):
koder aka kdanilovdda86d32015-03-16 11:20:04 +0200120 print "running"
121 return
122 print "stopped"
123 else:
124 raise ValueError("Unknown daemon operation {}".format(opts.daemon))
125 else:
126 required_sensors = json.loads(opts.sensors_config.read())
127 daemon_main(required_sensors, opts)
128 return 0
129
130if __name__ == "__main__":
131 exit(main(sys.argv))