logging_.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. '''
  2. @author: devone, 02-2020
  3. '''
  4. import logging.config
  5. import os
  6. import sys
  7. import threading
  8. import traceback
  9. import yaml
  10. from path import Path
  11. HERE = Path(__file__).parent
  12. LOGDIR = HERE
  13. LOGCONF = HERE / 'logging.yml'
  14. SYS_EXCEPT_HOOK = sys.excepthook
  15. def start(name="main", level=0, filename="", replace=False):
  16. # charge la configuration du logging depuis le fichier 'logging.yaml'
  17. with open(LOGCONF, 'rt') as f:
  18. conf = yaml.load(f, Loader=yaml.FullLoader)
  19. if level:
  20. conf["loggers"][name]["level"] = level
  21. if not filename:
  22. filename = LOGDIR / r'{}.log'.format(name)
  23. if replace:
  24. filename.remove_p()
  25. conf["handlers"]["file"]["filename"] = filename
  26. logging.config.dictConfig(conf)
  27. logger = logging.getLogger(name)
  28. def _excepthook(typ, value, trace):
  29. """ Remplace la gestion d'erreur standard, pour logger aussi les erreurs non gérées """
  30. logger.error("{}\n{}\n{}".format(typ.__name__, value, ''.join(traceback.format_tb(trace))))
  31. SYS_EXCEPT_HOOK(typ, value, trace)
  32. sys.excepthook = _excepthook
  33. class LogPipe(threading.Thread):
  34. def __init__(self, logger_name, level=logging.INFO):
  35. """Setup the object with a logger and a loglevel
  36. and start the thread
  37. """
  38. threading.Thread.__init__(self)
  39. self.logger_name = logger_name
  40. self.daemon = False
  41. self.level = level
  42. self.fdRead, self.fdWrite = os.pipe()
  43. self.pipeReader = os.fdopen(self.fdRead)
  44. self.start()
  45. def fileno(self):
  46. """Return the write file descriptor of the pipe
  47. """
  48. return self.fdWrite
  49. def run(self):
  50. """Run the thread, logging everything.
  51. """
  52. logger = logging.getLogger(self.logger_name)
  53. for line in iter(self.pipeReader.readline, ''):
  54. logger.log(self.level, line.strip('\n'))
  55. self.pipeReader.close()
  56. def close(self):
  57. """Close the write end of the pipe.
  58. """
  59. os.close(self.fdWrite)