forked from samuel/python-munin
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmunin-node.py
More file actions
executable file
·150 lines (133 loc) · 4.96 KB
/
Copy pathmunin-node.py
File metadata and controls
executable file
·150 lines (133 loc) · 4.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python
import os
import socket
import SocketServer
import sys
import threading
import time
from subprocess import Popen, PIPE
PLUGIN_PATH = "/etc/munin/plugins"
def parse_args():
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-p", "--pluginpath", dest="plugin_path",
help="path to plugins", default=PLUGIN_PATH)
(options, args) = parser.parse_args()
return options, args
def execute_plugin(path, cmd=""):
args = [path]
if cmd:
args.append(cmd)
p = Popen(args, stdout=PIPE)
output = p.communicate()[0]
return output
if os.name == 'posix':
def become_daemon(our_home_dir='.', out_log='/dev/null',
err_log='/dev/null', umask=022):
"Robustly turn into a UNIX daemon, running in our_home_dir."
# First fork
try:
if os.fork() > 0:
sys.exit(0) # kill off parent
except OSError, e:
sys.stderr.write("fork #1 failed: (%d) %s\n" % (e.errno, e.strerror))
sys.exit(1)
os.setsid()
os.chdir(our_home_dir)
os.umask(umask)
# Second fork
try:
if os.fork() > 0:
os._exit(0)
except OSError, e:
sys.stderr.write("fork #2 failed: (%d) %s\n" % (e.errno, e.strerror))
os._exit(1)
si = open('/dev/null', 'r')
so = open(out_log, 'a+', 0)
se = open(err_log, 'a+', 0)
os.dup2(si.fileno(), sys.stdin.fileno())
os.dup2(so.fileno(), sys.stdout.fileno())
os.dup2(se.fileno(), sys.stderr.fileno())
# Set custom file descriptors so that they get proper buffering.
sys.stdout, sys.stderr = so, se
else:
def become_daemon(our_home_dir='.', out_log=None, err_log=None, umask=022):
"""
If we're not running under a POSIX system, just simulate the daemon
mode by doing redirections and directory changing.
"""
os.chdir(our_home_dir)
os.umask(umask)
sys.stdin.close()
sys.stdout.close()
sys.stderr.close()
if err_log:
sys.stderr = open(err_log, 'a', 0)
else:
sys.stderr = NullDevice()
if out_log:
sys.stdout = open(out_log, 'a', 0)
else:
sys.stdout = NullDevice()
class NullDevice:
"A writeable object that writes to nowhere -- like /dev/null."
def write(self, s):
pass
class MuninRequestHandler(SocketServer.StreamRequestHandler):
def handle(self):
# self.rfile is a file-like object created by the handler;
# we can now use e.g. readline() instead of raw recv() calls
plugins = []
for x in os.listdir(self.server.options.plugin_path):
if x.startswith('.'):
continue
fullpath = os.path.join(self.server.options.plugin_path, x)
if not os.path.isfile(fullpath):
continue
plugins.append(x)
node_name = socket.gethostname().split('.')[0]
self.wfile.write("# munin node at %s\n" % node_name)
while True:
line = self.rfile.readline()
if not line:
break
line = line.strip()
cmd = line.split(' ', 1)
plugin = (len(cmd) > 1) and cmd[1] or None
if cmd[0] == "list":
self.wfile.write("%s\n" % " ".join(plugins))
elif cmd[0] == "nodes":
self.wfile.write("nodes\n%s\n.\n" % (node_name))
elif cmd[0] == "version":
self.wfile.write("munins node on chatter1 version: 1.2.6\n")
elif cmd[0] in ("fetch", "config"):
if plugin not in plugins:
self.wfile.write("# Unknown service\n.\n")
continue
c = (cmd[0] == "config") and "config" or ""
out = execute_plugin(os.path.join(self.server.options.plugin_path, plugin), c)
self.wfile.write(out)
if out and out[-1] != "\n":
self.wfile.write("\n")
self.wfile.write(".\n")
elif cmd[0] == "quit":
break
else:
self.wfile.write("# Unknown command. Try list, nodes, config, fetch, version or quit\n")
class MuninServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
pass
if __name__ == "__main__":
HOST, PORT = "0.0.0.0", 4949
if sys.version_info[:3] >= (2, 6, 0):
server = MuninServer((HOST, PORT), MuninRequestHandler, bind_and_activate=False)
server.allow_reuse_address = True
server.server_bind()
server.server_activate()
else:
server = MuninServer((HOST, PORT), MuninRequestHandler)
ip, port = server.server_address
options, args = parse_args()
options.plugin_path = os.path.abspath(options.plugin_path)
server.options = options
become_daemon()
server.serve_forever()