scripts/surveillance/statistiques2.py
2014-11-07 00:37:02 +01:00

205 lines
5.8 KiB
Python
Executable file

#!/bin/bash /usr/scripts/python.sh
# -*- encoding: utf-8 -*-
#
# Script qui calcule les statistiques d'upload des diverses machines
# Crans.
# Auteur : Pierre-Elliott Bécue
# Licence : GPLv3
"""
Script gérant les diverses statistiques liées au comptage
d'upload. Exécuté quotidiennement sur le serveur qui compte
l'upload.
"""
import sys
import argparse
import socket
import time
import gestion.affichage as affichage
import lc_ldap.shortcuts
import psycopg2
import psycopg2.extras
import gestion.config.upload as upload_config
import gestion.config as config
from gestion import mail as mail_module
ldap = lc_ldap.shortcuts.lc_ldap_readonly()
encoding = "UTF-8"
pgsql = psycopg2.connect(database='filtrage', user='crans')
pgsql.set_session(autocommit=True)
curseur = pgsql.cursor(cursor_factory=psycopg2.extras.DictCursor)
def ipv4or6(addr):
"""Méthode affichang IPv4/6 en fonction du
type d'IP. C'est juste un bulk pour éviter d'utiliser
des bazookas style netaddr.
"""
if ':' in addr:
return "IPv6"
else:
return "IPv4"
def upload_srv_stats(args):
"""Méthode générant les stats d'upload des serveurs à partir
des données de la base upload.
"""
upload_srv_req = """
WITH
machines_sans_doublon
AS
(
SELECT DISTINCT ON(mac_addr)
*
FROM
machines
)
SELECT
SUM(upload) as tot_upload,
SUM(download) as tot_download,
mac,
ip_crans
FROM (
(
SELECT
sum(bytes) as upload,
'0' as download,
mac_src as mac,
ip_src as ip_crans
FROM
upload
LEFT JOIN
machines_sans_doublon
ON
machines_sans_doublon.mac_addr = upload.mac_src
WHERE
machines_sans_doublon.type = 'crans'
AND NOT
ip_src <<= inet%(ipv6_local)s
AND NOT
ip_dst <<= inet%(ipv6_local)s
AND NOT
ip_dst <<= inet%(plage_ens)s
AND NOT
ip_dst <<= inet%(appt)s
AND NOT
ip_dst <<= inet%(plage_adm)s
AND NOT
ip_dst <<= inet%(plage_ipv6)s
AND
stamp_inserted >= %(begin)s
AND
stamp_inserted <= %(end)s
GROUP BY
mac,
ip_crans
)
UNION
(
SELECT
'0' as upload,
sum(bytes) as download,
mac_dst as mac,
ip_dst as ip_crans
FROM
upload
LEFT JOIN
machines_sans_doublon
ON
machines_sans_doublon.mac_addr = upload.mac_dst
WHERE
machines_sans_doublon.type = 'crans'
AND NOT
ip_src <<= inet%(ipv6_local)s
AND NOT
ip_dst <<= inet%(ipv6_local)s
AND NOT
ip_src <<= inet%(plage_ens)s
AND NOT
ip_src <<= inet%(appt)s
AND NOT
ip_src <<= inet%(plage_adm)s
AND NOT
ip_src <<= inet%(plage_ipv6)s
AND
stamp_inserted >= %(begin)s
AND
stamp_inserted <= %(end)s
GROUP BY
mac,
ip_crans
)
)
AS
famille
GROUP BY
mac,
ip_crans
ORDER BY
tot_upload
DESC
"""
fill_in_dict = {
"begin" : args.begin,
"end" : args.end,
"plage_ens" : config.plage_ens,
"ipv6_local" : 'fe80::/8',
"plage_ipv6" : config.prefix['subnet'][0],
"appt" : config.NETs['personnel-ens'][0],
"plage_adm" : config.NETs['adm'][0],
}
curseur.execute(upload_srv_req, fill_in_dict)
upload_result = curseur.fetchall()
upload_srv = [[socket.getfqdn(ligne["ip_crans"]), ipv4or6(ligne['ip_crans']), ligne['tot_upload'], ligne['tot_download']] for ligne in upload_result if ligne["tot_upload"] >= upload_config.stats_upload_seuil]
return upload_srv
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Script d'analyse d'échange de données entre un truc et un autre.", add_help=False)
parser.add_argument("-b", "--begin", help="Date de début, dans un format \"AAAA/MM/JJ HH:MM:SS\"", type=str, action="store")
parser.add_argument("-e", "--end", help="Date de fin, dans un format \"AAAA/MM/JJTHH:MM:SS\"", type=str, action="store")
parser.add_argument("-m", "--mail", help="Envoyer un mail avec les résultats.", action="store_true")
parser.add_argument("-h", "--help", help="Affiche cette aide et quitte.", action="store_true")
args = parser.parse_args()
now = time.time()
if args.help:
parser.print_help()
sys.exit(0)
if not args.begin:
args.begin = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(now - 86400))
if not args.end:
args.end = time.strftime("%Y/%m/%d %H:%M:%S", time.localtime(now))
stats_upload = upload_srv_stats(args)
entete = [u"Nom", u"Type", u"Upload", u"Download"]
longueur = ['*', 4, 13, 13]
formats = ['s', 's', 'o', 'o']
if args.mail:
styles = [None, None, None, None]
else:
styles = [None, None, "vert", "rouge"]
fetched_upload_srv = affichage.tableau(stats_upload, titre=entete, largeur=longueur, styles=styles, format=formats, width=80)
if args.mail:
expediteur = "disconnect@crans.org"
destinataire = "disconnect@crans.org"
# Testing purpose:
# destinataire = "your.mail@crans.org"
corps = mail_module.generate('upload_stats',
{
'from': expediteur,
'to': destinataire,
'upload_srv': fetched_upload_srv,
'seuil_upload': upload_config.pretty_seuil,
}).as_string()
with mail_module.ServerConnection() as conn:
conn.sendmail(expediteur, destinataire, corps)
else:
print fetched_upload_srv