scripts/munin/scripts/link_plugins.py
Daniel STAN 203d78afbb [munin] monitoring du temps
Ignore-this: 51119867ce3ba5b95f103b1ca855ac5b
On met un plugin qui mesure la dérivée du temps, tel que vu par le client,
grossièrement. L'intérêt est de voir le drift des serveurs et en particulier
des domU (ntp marche moyen dessus, on veut voir à quel point).

darcs-hash:20130125031212-28565-5b472c789107580f74612eac7efc39aa31516f7b.gz
2013-01-25 04:12:12 +01:00

232 lines
7.1 KiB
Python
Executable file
Raw Blame History

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Liste les liens à créer pour les plugins munin.
#
# Utilise la liste de plugins classiques renvoyée par
# munin-node-configure, filtrée, et les plugins customisés Cr@ns
# configurés dans hosts_plugins.py
#
# Copyright © 2009 Nicolas Dandrimont <Nicolas.Dandrimont@crans.org>
#
# Licence: MIT
#
import optparse
import os
import shutil
import socket
import subprocess
import sys
import tempfile
from hosts_plugins import hosts_plugins, general_plugins
# Plugins munin classiques à ignorer
IGNORE_PLUGINS = (
'apt_all',
'if_',
'if_err_',
'multips',
'nfs4_client',
'port_',
'sensors_',
'squid_icp',
'tomcat_',
'vlan_',
)
# Chemin d'accès aux plugins munin
MUNIN_PATH = "/usr/share/munin/plugins"
# Hacks crades
QUIRKS = []
if sys.version_info < (2, 5):
def any(genexpr):
"""Retourne True si quelque chose est vrai dans genexpr"""
for truc in genexpr:
if truc:
return True
return False
def register_quirk(f):
QUIRKS.append(f)
def get_munin_plugins():
"""Liste les plugins munin créés par le système
Retourne un dictionnaire dont la clé est le lien dans
/etc/munin/plugins, et la valeur le fichier à lier.
"""
# Dictionnaire de sortie
output = {}
# Crée un répertoire vide pour faire croire à Munin qu'on veut
# créer tous les liens...
tempdir = tempfile.mkdtemp()
# Demande à Munin quels plugins il lui semble bon nous faire
# utiliser. --families=auto,manual permet de récupérer plus de
# plugins (qu'il faut ensuite filtrer)
munin = subprocess.Popen(["/usr/sbin/munin-node-configure",
"--families=manual",
"--families=auto",
"--servicedir", tempdir,
"--shell"],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE
)
munin_stdout, munin_stderr = munin.communicate()
# if munin.returncode != 0:
# raise RuntimeError, "munin-node-configure... Stderr:\n%s" % munin_stderr
munin_output_lines = munin_stdout.splitlines()
for line in munin_output_lines:
if line.startswith("ln -s"):
dst, src = line.split()[-2:]
if dst[0] == "'":
dst = dst[1:-1]
src = src[1:-1]
src = os.path.basename(src)
# filtrage
if not os.path.basename(dst) in IGNORE_PLUGINS:
output[src] = dst
os.rmdir(tempdir)
# Exécute les hacks sales sur la sortie
for quirk in QUIRKS:
quirk(output)
return output
def get_all_plugins():
"""Liste les liens de plugins munin à créer
Retourne un dictionnaire dont la clé est le lien dans
/etc/munin/plugins, et la valeur le fichier à lier.
"""
hostname = socket.gethostname()
result = get_munin_plugins()
custom_plugins = hosts_plugins.get(hostname, {})
custom_plugins.update(general_plugins)
for plugin, dest_file in custom_plugins.iteritems():
if dest_file.startswith('/'):
result[plugin] = dest_file
else:
result[plugin] = os.path.join('/usr/scripts/munin', dest_file)
return result
def list_plugins(plugins, directory):
"""Liste les plugins comme s'ils allaient être liés dans
directory"""
for name, path in sorted(plugins.items()):
print os.path.join(directory, name), '->', path
def link_plugins(plugins, directory):
"""Lie les plugins dans le répertoire directory"""
for name, path in plugins.iteritems():
try:
os.symlink(path, os.path.join(directory, name))
if options.verbose:
print "%s install<6C> avec succ<63>s!" % name
except OSError:
print "Echec <20> l'installation de %s (d<>j<EFBFBD> install<6C>?)" % name
# Hack propre
def add_plugin(plugin):
"""Crée une fonction qui ajoute le plugin à la liste"""
# Les clôtures en Python, ça fait rêver...
def f(plugins, plugin=plugin):
plugins[plugin] = os.path.join(MUNIN_PATH, plugin)
return f
register_quirk(add_plugin("uptime")) # Coucou MoSaN
register_quirk(add_plugin("netstat"))
register_quirk(add_plugin("apt"))
register_quirk(add_plugin("nfs_client"))
# Hacks sales
@register_quirk
def add_ifaces(plugins):
"""Ajoute les interfaces à la liste des plugins si munin n'a pas
trouvé d'interface (ou si elles ont été filtrées)"""
if not any(plugin.startswith('if_') for plugin in plugins):
# Liste les interfaces configurées sur le système
interfaces_file = None
interfaces = []
try:
interfaces_file = file('/etc/network/interfaces', 'r')
for line in interfaces_file:
line = line.split()
# Recherche d'une ligne type "iface eth0 inet static"
if line and line[0] == 'iface' and line[-1] == 'static':
interface_name = line[1]
# on dégage les interfaces sur vlan spéciaux et
# aliasées (leur nom contient ':' ou '.')
if not set('.:') & set(interface_name):
interfaces.append(interface_name)
finally:
if interfaces_file is not None:
interfaces_file.close()
for interface in interfaces:
plugins['if_%s' % interface] = os.path.join(MUNIN_PATH,'if_')
plugins['if_err_%s' % interface] = os.path.join(MUNIN_PATH, 'if_err_')
@register_quirk
def use_correct_postfix_mailstats(plugins):
"""Utilise un postfix_mailstats non buggué sur etch"""
if "postfix_mailstats" in plugins:
try:
debver_file = open('/etc/debian_version')
except IOError:
return
else:
debver = debver_file.read()
debver_file.close()
if debver.startswith('4'):
plugins["postfix_mailstats"] = "/usr/scripts/munin/postfix_mailstats"
if __name__ == "__main__":
parser = optparse.OptionParser()
parser.add_option('-d', '--directory',
help = 'Write plugin symlinks to DIR',
metavar = 'DIR',
default = '/etc/munin/plugins'
)
parser.add_option('-f', '--force',
action = 'store_true',
help = 'Remove destination directory'
)
parser.add_option('-p', '--pretend',
action = 'store_true',
help = 'Do not actually make links'
)
parser.add_option('-v', '--verbose',
action = 'store_true',
help = 'Increase verbosity'
)
(options, args) = parser.parse_args()
plugins = get_all_plugins()
if options.pretend:
list_plugins(plugins, options.directory)
else:
if options.force:
shutil.rmtree(options.directory)
os.mkdir(options.directory)
link_plugins(plugins, options.directory)