4 Setup symlinks for pvl.verkko-rrd -> collectd based on define host/interface names |
4 Setup symlinks for pvl.verkko-rrd -> collectd based on define host/interface names |
5 """ |
5 """ |
6 |
6 |
7 __version__ = '0.1' |
7 __version__ = '0.1' |
8 |
8 |
9 import shlex |
|
10 import os |
9 import os |
11 |
10 |
12 import pvl.args |
11 import pvl.args |
|
12 import pvl.rrd.hosts |
|
13 from pvl.rrd.hosts import hostreverse |
13 |
14 |
14 import optparse |
15 import optparse |
15 import logging; log = logging.getLogger('main') |
16 import logging; log = logging.getLogger('main') |
16 |
|
17 def hostjoin (*hosts) : |
|
18 """ |
|
19 DNS hostname join. |
|
20 """ |
|
21 |
|
22 return '.'.join(hosts) |
|
23 |
|
24 def hostreverse (host) : |
|
25 """ |
|
26 Reverse hostname. |
|
27 """ |
|
28 |
|
29 return '.'.join(reversed(host.split('.'))) |
|
30 |
|
31 def collectd_interfaces (options, file, collectd_domain, collectd_plugin) : |
|
32 """ |
|
33 Read collectd (host, type-instance, name) items, and yield (collectd-rrd, out-rrd) tuples. |
|
34 |
|
35 file - read host/ports from file |
|
36 collectd_domain - append given domain to collectd hostname |
|
37 collectd_plugin - use given collectd plugin's type-instances |
|
38 """ |
|
39 |
|
40 host = None |
|
41 |
|
42 log.info("scanning %s/<host>.%s/%s/%s-<port>.rrd", options.collectd_rrd, collectd_domain, collectd_plugin, options.collectd_type) |
|
43 |
|
44 for idx, line in enumerate(file, 1) : |
|
45 line = line.rstrip() |
|
46 |
|
47 if not line : |
|
48 continue |
|
49 |
|
50 # comment? |
|
51 if line.startswith('#') : |
|
52 continue |
|
53 |
|
54 # line |
|
55 parts = shlex.split(line) |
|
56 |
|
57 if not line[0].isspace() : |
|
58 host = parts.pop(0) |
|
59 |
|
60 # host-spec? |
|
61 if '=' in host : |
|
62 collectd_host, interface_host = host.split('=') |
|
63 else : |
|
64 collectd_host = interface_host = host |
|
65 |
|
66 # flip from DNS-ordering -> path-ordering |
|
67 if options.reverse_host : |
|
68 interface_host = hostreverse(interface_host) |
|
69 |
|
70 # host has domain in collectd? |
|
71 if collectd_domain : |
|
72 collectd_host = hostjoin(collectd_host, collectd_domain) |
|
73 |
|
74 if not parts : |
|
75 # keep host for following lines |
|
76 continue |
|
77 |
|
78 port = parts.pop(0) |
|
79 |
|
80 # possibly multiple tags.. |
|
81 for tag in parts : |
|
82 if options.collectd_instance == 'type' : |
|
83 type = options.collectd_type + '-' + port |
|
84 else : |
|
85 type = options.collectd_type |
|
86 |
|
87 if options.collectd_instance == 'plugin' : |
|
88 plugin = collectd_plugin + '-' + port |
|
89 else : |
|
90 plugin = collectd_plugin |
|
91 |
|
92 collectd_rrd = os.path.join(options.collectd_rrd, collectd_host, plugin, type) + '.rrd' |
|
93 |
|
94 if not os.path.exists(collectd_rrd) : |
|
95 log.warn("%s: missing collectd rrd: %s", idx, collectd_rrd) |
|
96 continue |
|
97 |
|
98 # out |
|
99 interface_rrd = os.path.join(interface_host, tag + '.rrd') |
|
100 |
|
101 log.debug("%s: %s", interface_rrd, collectd_rrd) |
|
102 |
|
103 yield collectd_rrd, interface_rrd |
|
104 |
|
105 def sync_links (options, links, dir) : |
|
106 """ |
|
107 Sync given (collectd, name) symlinks in given dir. |
|
108 """ |
|
109 |
|
110 log.info("%s", dir) |
|
111 |
|
112 for path, name in links : |
|
113 link = os.path.join(dir, name) |
|
114 |
|
115 # sync |
|
116 if os.path.exists(link) : |
|
117 continue |
|
118 |
|
119 log.info("%s: %s: %s", dir, name, path) |
|
120 |
|
121 yield link, path |
|
122 |
|
123 def apply_links (options, links) : |
|
124 """ |
|
125 Apply given symlinks |
|
126 """ |
|
127 |
|
128 for link, path in links : |
|
129 linkdir = os.path.dirname(link) |
|
130 |
|
131 # do |
|
132 if not os.path.exists(linkdir) : |
|
133 log.warn("mkdir: %s", linkdir) |
|
134 os.mkdir(linkdir) |
|
135 |
|
136 print path |
|
137 |
|
138 os.symlink(path, link) |
|
139 |
17 |
140 COLLECTD_RRD = '/var/lib/collectd/rrd' |
18 COLLECTD_RRD = '/var/lib/collectd/rrd' |
141 COLLECTD_PLUGIN = 'interfaces' |
19 COLLECTD_PLUGIN = 'interfaces' |
142 COLLECTD_TYPE = 'if_octets' |
20 COLLECTD_TYPE = 'if_octets' |
143 |
21 |
199 # apply |
77 # apply |
200 pvl.args.apply(options) |
78 pvl.args.apply(options) |
201 |
79 |
202 return options, args |
80 return options, args |
203 |
81 |
|
82 def sync_links (options, links, dir) : |
|
83 """ |
|
84 Sync given (collectd, name) symlinks in given dir. |
|
85 """ |
|
86 |
|
87 log.info("%s", dir) |
|
88 |
|
89 for path, name in links : |
|
90 link = os.path.join(dir, name) |
|
91 |
|
92 # sync |
|
93 if os.path.exists(link) : |
|
94 continue |
|
95 |
|
96 log.info("%s: %s: %s", dir, name, path) |
|
97 |
|
98 yield link, path |
|
99 |
|
100 def apply_links (options, links) : |
|
101 """ |
|
102 Apply given symlinks |
|
103 """ |
|
104 |
|
105 for link, path in links : |
|
106 linkdir = os.path.dirname(link) |
|
107 |
|
108 # do |
|
109 if not os.path.exists(linkdir) : |
|
110 log.warn("mkdir: %s", linkdir) |
|
111 os.mkdir(linkdir) |
|
112 |
|
113 print path |
|
114 |
|
115 os.symlink(path, link) |
|
116 |
204 def main (argv) : |
117 def main (argv) : |
205 options, args = parse_argv(argv) |
118 options, args = parse_argv(argv) |
206 |
119 |
207 for txt in args : |
120 for txt in args : |
208 # <path>/<domain>-<plugin>.txt -> <path>/<domain>-<plugin> |
121 # <path>/<domain>-<plugin>.txt -> <path>/<domain>-<plugin> |
231 rrd = os.path.join(options.rrd, rrd_domain) |
144 rrd = os.path.join(options.rrd, rrd_domain) |
232 else : |
145 else : |
233 rrd = basepath |
146 rrd = basepath |
234 |
147 |
235 # generate links from spec |
148 # generate links from spec |
236 links = list(collectd_interfaces(options, open(txt), |
149 links = list(pvl.rrd.hosts.collectd_interfaces(options, open(txt), |
237 collectd_domain = domain, |
150 collectd_domain = domain, |
238 collectd_plugin = options.collectd_plugin or collectd_plugin or COLLECTD_PLUGIN, |
151 collectd_plugin = options.collectd_plugin or collectd_plugin or COLLECTD_PLUGIN, |
239 )) |
152 )) |
240 |
153 |
241 if not os.path.exists(rrd) : |
154 if not os.path.exists(rrd) : |