Commit edd879ef1eca845a7230d05326cdd195be439cd4

Authored by ronan
1 parent 4c1c3ce81a
Exists in master

added new file

Showing 1 changed file with 152 additions and 0 deletions

logrotate.py View file @ edd879e
  1 +# -*- coding: UTF-8 -*-
  2 +
  3 +"""
  4 + logrotate.py
  5 + ============
  6 +
  7 + Permet la rotation des logs Apache
  8 +
  9 + :Example:
  10 +
  11 + >>> import logrotate
  12 + >>> logrotate.main()
  13 +"""
  14 +
  15 +import os, shutil, zipfile
  16 +import datetime as dt
  17 +
  18 +F = r'C:\wamp\logs' # Répertoire des logs Apache
  19 +LOG = 'logrotate.log' # Fichier de log pour les rotations
  20 +TXT = 'ROTATION DU FICHIER' # Texte affiché dans le log des rotations
  21 +TXT2 = 'SUPPRESSION DU FICHIER' # Texte affiché dans le log des rotations
  22 +TXT3 = 'COMPRESSION DU FICHIER' # Texte affiché dans le log des rotations
  23 +NBARCHIVE = 20 # Nombre de fichier de log historisé .0 .1 .2 etc etc ...
  24 +
  25 +def now():
  26 + """
  27 + Retourne la date et l'heure courante au format ISO 2018-06-28T10:30:23.816122
  28 +
  29 + :return: La date et heure courante
  30 + :rtype: datetime.datetime
  31 + """
  32 + return dt.datetime.now().isoformat()
  33 +
  34 +def log(FLOG, TXT, FILE, MSG):
  35 + """
  36 + Ecrit dans le fichier ``FLOG`` les infos
  37 + ``TXT``, ``FILE`` et ``MSG`` avec la date courante
  38 + """
  39 + print('{DATETIME} {T:<25s} {FILE:<40s} --> {MSG}'.format(DATETIME=now(), FILE=FILE, T=TXT, MSG=MSG), file=FLOG)
  40 +
  41 +def delFile(FILE, FLOG):
  42 + """
  43 + Supprime le fichier ``FILE``
  44 + """
  45 + try: os.remove(FILE)
  46 + except: log(FLOG, TXT2, FILE, 'KO')
  47 + else: log(FLOG, TXT2, FILE, 'OK')
  48 +
  49 +def listLog(LIST, EXT):
  50 + """
  51 + Extrait tous les fichiers de log avec l'extension ``EXT``
  52 + de la liste ``LIST``
  53 +
  54 + :return: Une liste contenant uniquement les fichiers ayant l'extension ``EXT``
  55 + :rtype: list
  56 + """
  57 + return list(filter(lambda f: f.endswith(EXT), LIST))
  58 +
  59 +def removeUnusedFiles(FLOG):
  60 + """
  61 + Supprime tous les fichiers qui ne sont plus concernés par des fichiers LOG
  62 + Retourne une nouvelle liste avec les fichiers supprimés en moins
  63 +
  64 + :return: Une nouvelle liste avec les fichiers supprimés en moins
  65 + :rtype: list
  66 + """
  67 + LIST = os.listdir(F)
  68 + LISTLOG = listLog(LIST, '.log')
  69 + LISTDEL = list(filter(lambda x: '.'.join(x.split('.')[:2]) not in LISTLOG, LIST))
  70 + for FILE in LISTDEL:
  71 + delFile(os.path.join(F, FILE), FLOG)
  72 + return list(set(LIST) - set(LISTDEL))
  73 +
  74 +def incrementZipFile(LIST, FLOG):
  75 + """
  76 + Incrémente les archives ZIP jusqu'à ``NBARCHIVE``
  77 + Suppression de l'archive ZIP dont son index est supérieur
  78 + ou égal à ``NBARCHIVE``
  79 + """
  80 + LISTLOG = listLog(LIST, '.log')
  81 + LISTZIP = listLog(LIST, '.zip')
  82 + for f in LISTLOG:
  83 + WLIST = sorted(list(filter(lambda x: x.startswith(f), LISTZIP)), key=lambda y: int(y.split('.')[2]), reverse=True)
  84 + for FILE in WLIST:
  85 + TF = FILE.split('.')
  86 + IDX = int(TF[2])
  87 + OLDFILE = os.path.join(F, FILE)
  88 + if IDX >= NBARCHIVE:
  89 + delFile(OLDFILE, FLOG)
  90 + else:
  91 + TF[2] = str(IDX + 1)
  92 + NEWFILE = os.path.join(F, '.'.join(TF))
  93 + try: os.rename(OLDFILE, NEWFILE)
  94 + except: log(FLOG, TXT, OLDFILE, '{NEWFILE} ***KO***'.format(NEWFILE=NEWFILE))
  95 + else: log(FLOG, TXT, OLDFILE, '{NEWFILE}'.format(NEWFILE=NEWFILE))
  96 +
  97 +def log_0ToZip(LIST, FLOG):
  98 + """
  99 + On écrit tout le contenu des fichiers LOG *.log.0
  100 + dans de nouveaux fichiers ZIP *.log.1.zip
  101 + On supprime ensuite tous les fichiers *.log.0
  102 + """
  103 + LISTLOG0 = listLog(LIST, '.log.0')
  104 + for FILE in LISTLOG0:
  105 + with open(os.path.join(F, FILE), mode='r', encoding='UTF-8') as f1:
  106 + BASE = '.'.join(FILE.split('.')[:-1]) + '.1'
  107 + ZIP = os.path.join(F, BASE + '.zip')
  108 + with zipfile.ZipFile(ZIP, 'w', compression=zipfile.ZIP_DEFLATED) as f2:
  109 + try: f2.writestr(BASE, f1.read().encode('UTF-8'))
  110 + except: log(FLOG, TXT3, os.path.join(F, FILE), '{NEWFILE} ***KO***'.format(NEWFILE=ZIP))
  111 + else: log(FLOG, TXT3, os.path.join(F, FILE), '{NEWFILE}'.format(NEWFILE=ZIP))
  112 + delFile(os.path.join(F, FILE), FLOG)
  113 +
  114 +def logTo0(LIST, FLOG):
  115 + """
  116 + On écrit tout le contenu des fichiers LOG *.log
  117 + dans de nouveaux fichiers numérotés *.log.0
  118 + On écrase ensuite le contenu des fichiers LOG
  119 + """
  120 + LISTLOG = listLog(LIST, '.log')
  121 + for FILE in LISTLOG:
  122 + OLDFILE = os.path.join(F, FILE)
  123 + NEWFILE = os.path.join(F, FILE + '.0')
  124 + try:
  125 + with open(OLDFILE, mode='r', encoding='UTF-8') as f1:
  126 + with open(NEWFILE, mode='w', encoding='UTF-8') as f2:
  127 + f2.write(f1.read())
  128 + except: log(FLOG, TXT, OLDFILE, '{NEWFILE} ***KO***'.format(NEWFILE=NEWFILE))
  129 + else: log(FLOG, TXT, OLDFILE, '{NEWFILE}'.format(NEWFILE=NEWFILE))
  130 + try:
  131 + with open(OLDFILE, mode='w', encoding='UTF-8') as f1:
  132 + f1.write('')
  133 + except: log(FLOG, TXT2, OLDFILE, 'KO')
  134 + else: log(FLOG, TXT2, OLDFILE, 'OK')
  135 +
  136 +def main():
  137 + """
  138 + Fonction principale
  139 +
  140 + Pour chaque fichier de log (*.log) trouvé dans le dossier (variable ``F``)
  141 + Chaque niveau d'archive est incrémenté de 1 dans la limite du nombre d'archive
  142 + indiqué dans la variable ``NBARCHIVE``
  143 + """
  144 + with open(os.path.join(F, LOG), mode='a', encoding='UTF-8') as FLOG:
  145 + LIST = removeUnusedFiles(FLOG)
  146 + LIST.remove(LOG) # On supprime de la liste le fichier de LOG du script
  147 + incrementZipFile(LIST, FLOG)
  148 + log_0ToZip(LIST, FLOG)
  149 + logTo0(LIST, FLOG)
  150 +
  151 +if __name__ == '__main__':
  152 + main()