scripts/surveillance/analyse.py
glondu 7428178ab9 Dans affich_tools, tableau_ng remplace dornavant tableau.
darcs-hash:20060326160011-68412-d87c57d6e2edf22dd78fd5c78e07793a19421ff5.gz
2006-03-26 18:00:11 +02:00

265 lines
8.8 KiB
Python
Executable file

#! /usr/bin/env python
# -*- coding: iso8859-15 -*-
import socket
import sys, re
from pyPgSQL import PgSQL
sys.path.append('/usr/scripts/gestion/')
from affich_tools import tableau
def stats(ip_crans=[], ip_ext=[], show=['ip_crans','ip_ext','port_crans','port_ext'], upload_mini=0, show_limit=10, begin_time=24, end_time=0):
"""
Retourne une chaine de caratères formatée avec le tableau de statistiques
d'upload de l'ip fourni
ip_crans : ips des machine
chaine de caratère si il a qu'une machine
liste si il y a plusieurs machines
view : liste des champs à afficher parmi :
ip_crans, ip_ext, port_crans, port_ext
upload_mini : n'affiche que les lignes avec plus d'upload que la valeur donnée
show_limit : nombre max de lignes à afficher
begin : date de départ d'analyse (en heure avant maintenant)
end : date de fin d'analyse (en heure avant maintenant)
"""
if type(ip_crans) == str:
ip_crans = [ip_crans]
if type(ip_ext) == str:
ip_ext = [ip_ext]
# variables pour la requete et l'affichage
##########################################
select = []
largeur = []
titre = []
format = []
alignement = []
if 'ip_crans' in show and len(ip_crans)!=1:
select.append('ip_crans')
largeur.append(13)
titre.append('machine crans')
format.append('s')
alignement.append('c')
if 'ip_ext' in show :
select.append('ip_ext')
largeur.append('*')
titre.append('machine ext')
format.append('s')
alignement.append('c')
if 'port_ext' in show :
select.append('port_ext')
largeur.append(10)
titre.append('port ext')
format.append('s')
alignement.append('d')
if 'port_crans' in show :
select.append('port_crans')
largeur.append(10)
titre.append('port crans')
format.append('s')
alignement.append('d')
select += ['sum(download) as download','sum(upload) as upload']
largeur += [10,10]
titre += ['download','upload']
format += ['o','o']
alignement += ['d','d']
# requete dans la base
######################
ip_crans = ' OR '.join([ "ip_crans='%s'"%x for x in ip_crans ])
if not ip_crans: ip_crans='true'
ip_ext = ' OR '.join([ "ip_ext='%s'"%x for x in ip_ext ])
if not ip_ext: ip_ext='true'
requete = "SELECT * FROM ( SELECT %s FROM upload WHERE (%s) AND (%s) AND (date > timestamp 'now' - interval '%d hours') AND (date < timestamp 'now' - interval '%d hours') GROUP BY %s) AS resultat_intemediaire WHERE upload>='%d' ORDER BY upload DESC LIMIT %d;" % (','.join(select), ip_crans, ip_ext, begin_time, end_time, ','.join(show), upload_mini*1024*1024, show_limit)
pgsql = PgSQL.connect(host='/var/run/postgresql', database='filtrage', user='crans')
curseur = pgsql.cursor()
curseur.execute(requete)
results = curseur.fetchall()
# on transforme tout en chaine
results = [ [ str(x) for x in line ] for line in results ]
# on modifie les ip en noms de machine et les ports en noms
def nom_de_machine (ip) :
try:
return socket.gethostbyaddr(ip)[0]
except:
return ip
port_to_service = {}
for service,port in [ re.split('[ \t]+',x.strip().replace('/tcp','').replace('/udp',''))[:2] for x in open('/etc/services').readlines() if x[0] not in ['\n','#'] ] :
port_to_service[port]=service
for champ in select:
if champ == 'ip_ext':
col = select.index(champ)
results = [ x[:col] + [nom_de_machine(x[col])] + x[col+1:] for x in results ]
elif champ == 'ip_crans':
col = select.index(champ)
results = [ x[:col] + [nom_de_machine(x[col]).split('.')[0]] + x[col+1:] for x in results ]
elif 'port' in champ:
col = select.index(champ)
results = [ x[:col] + [port_to_service.get(x[col],x[col])] + x[col+1:] for x in results ]
return tableau(results, titre=titre, largeur=largeur, alignement=alignement, format=format)
if __name__ == '__main__' :
help = """Statistiques d'upload d'une machine du crans
usage: analyse.py [options]
Option fait partie des options suivantes :
--ip-crans
ip de la machine crans
--ip-ext
ip de la machine extérieure
--show
champs à afficher (parmi ip_crans, ip_ext, port_crans, port_ext)
--upload-mini
upload mini des lignes à afficher
--show-limit
nombre maximum de lignes à afficher
--begin-time
heure de départ de l'analyse (en heure depuis maintenant)
--end-time
heure de fin de l'analyse (en heure depuis maintenant)
Exemples :
sudo /usr/scripts/surveillance/analyse.py bilou.crans.org"""
# import des modules
import getopt
# aide
######
if '-h' in sys.argv or '--help' in sys.argv or len(sys.argv)==1:
print help
sys.exit(0)
# parsage des arguments
#######################
try :
opts, args = getopt.getopt(sys.argv[1:],'',['ip-crans=','ip-ext=','show=','upload-mini=','begin-time=','end-time=','show-limit='])
except getopt.GetoptError,message :
print help
sys.exit(4)
print "Statistiques d'upload"
# recherche de la machine crans
###############################
ip_crans = []
ip_crans_nom = []
for key,value in opts :
if key == '--ip-crans' :
try :
ip_crans.append(socket.gethostbyaddr(value)[2][0])
ip_crans_nom.append(socket.gethostbyaddr(value)[0])
except socket.gaierror :
print "Hôte %s inconnu" % value
sys.exit(5)
if len(ip_crans_nom)==1:
print ' depuis la machine %s' % ip_crans_nom[0]
elif ip_crans_nom:
print ' depuis les machines %s' % ', '.join(ip_crans_nom)
# recherche de la machine ext
#############################
ip_ext = []
ip_ext_nom = []
for key,value in opts :
if key == '--ip-ext' :
# recherche de l'ip de la machine extérieur
try :
ip_ext.append(socket.gethostbyaddr(value)[2][0])
except socket.gaierror :
print "Hôte %s inconnu" % value
sys.exit(5)
# recherche du nom d'hote
try :
ip_ext_nom.append(socket.gethostbyaddr(value)[0])
except socket.gaierror :
ip_ext_nom.append(ip_ext[-1])
if len(ip_ext_nom)==1:
print ' vers la machine extérieure %s' % ip_ext_nom[0]
elif ip_ext_nom:
print ' vers les machines extérieures %s' % ', '.join(ip_ext_nom)
# limite d'affichage
####################
show = [ x[1] for x in opts if x[0] == '--show' and x[1] in ['ip_crans','ip_ext','port_crans','port_ext'] ]
if not show :
show = ['ip_crans','ip_ext','port_crans','port_ext']
else :
print ' affichage de %s' % ', '.join(show)
# upload mini à afficher
########################
upload_mini = 0
for key,value in opts :
if key == '--upload-mini' :
try :
upload_mini = int(value)
except :
print 'L\'upload mini doit être un entier (en MO)'
sys.exit(4)
break
if upload_mini:
print ' pour les traffics supérieurs à %d Mo' % upload_mini
# nombre limite d'enregristrements
##################################
limit = 10
for key,value in opts :
if key == '--show-limit' :
try :
limit = int(value)
print ' affichage des %d premiers résultats' % limit
except :
print 'Le nombre limite n\'est pas un entier'
sys.exit(3)
break
# début de l'analyse
####################
begin_time = 24
for key,value in opts :
if key == '--begin-time' :
try :
begin_time = int(value)
except :
print 'Le nombre d\'heures doit être un entier'
sys.exit(4)
break
# fin de l'analyse
##################
end_time = 0
for key,value in opts :
if key == '--end-time' :
try :
end_time = int(value)
except :
print 'Le nombre d\'heures doit être un entier'
sys.exit(4)
break
if begin_time != 24 or end_time:
print ' entre il y a %d heures et il y a %d heures' % (begin_time,end_time)
# affichage du résultat
#######################
#print stats(ip_crans, group, upload_mini, limit, heures)
print stats(ip_crans, ip_ext, show, upload_mini, limit, begin_time, end_time)