Advertisement
Uno-Dan

Logging Server Update

May 11th, 2019
202
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 9.08 KB | None | 0 0
  1.  
  2. from os import path, makedirs
  3. from socket import gethostname, gethostbyname
  4. from logging import config, Filter, getLogger, INFO, DEBUG, WARNING, ERROR, CRITICAL, FATAL, NOTSET
  5. from multiprocessing import Process
  6.  
  7. from zmq import Context
  8. from zmq.backend.cython.constants import SUB, SUBSCRIBE, PUSH, PULL
  9.  
  10. PATH = path.dirname(path.realpath(__file__))
  11. PATH_LOGS = path.join(PATH, '../logs')
  12. LOGGER_FORMAT = '%(levelname)s:%(asctime)s,%(msecs)d:%(process)d:%(name)s:%(filename)s:%(funcName)s:' \
  13.                 '%(lineno)d:%(message)s'
  14. LOG_FILE_BACKUP_COUNT = 3  
  15. LOG_FILE_MAXIMUM_BYTES = 5242880  # 5MB
  16.  
  17. _nameToLevel = {
  18.     'CRITICAL': CRITICAL,
  19.     'FATAL': FATAL,
  20.     'ERROR': ERROR,
  21.     'WARN': WARNING,
  22.     'WARNING': WARNING,
  23.     'INFO': INFO,
  24.     'DEBUG': DEBUG,
  25.     'NOTSET': NOTSET,
  26. }
  27.  
  28.  
  29. def spawn(task, *args):
  30.     process = Process(target=task, args=args)
  31.     process.daemon = True
  32.     process.start()
  33.     return process
  34.  
  35.  
  36. class Logger:
  37.     def __init__(self, name, frontend, backend):
  38.         super().__init__()
  39.  
  40.         logger = 'local'
  41.         self.ctx = None
  42.         self.name = name
  43.         self.backend = backend
  44.         self.frontend = frontend
  45.         self.processes = []
  46.         self.logger = getLogger(logger)
  47.         self.hostname = gethostname()
  48.         self.ipaddr = gethostbyname(self.hostname)
  49.  
  50.         _path = path.join(PATH_LOGS, logger)
  51.         if not path.exists(_path):
  52.             makedirs(_path)
  53.  
  54.         self.logger.setLevel(DEBUG)
  55.         config.dictConfig(log_config)
  56.  
  57.     def start(self, nbr_workers):
  58.         ctx = Context()
  59.  
  60.         # Clients connect to the frontend
  61.         front_socket = ctx.socket(SUB)
  62.         front_socket.setsockopt_string(SUBSCRIBE, '')
  63.         front_socket.bind(self.frontend)
  64.  
  65.         # Workers connect to the backend
  66.         back_socket = ctx.socket(PUSH)
  67.         back_socket.bind(self.backend)
  68.  
  69.         for idx in range(nbr_workers):
  70.             process = spawn(self.worker, idx)
  71.             self.processes.append(process)
  72.  
  73.         while True:
  74.             request = front_socket.recv_multipart()
  75.             back_socket.send_multipart(request)
  76.  
  77.     def worker(self, index):
  78.         socket = Context().socket(PULL)
  79.         socket.connect(self.backend)
  80.  
  81.         remote_logger = getLogger('remote')  # Handles logs for remote clients
  82.         remote_logger.setLevel(DEBUG)
  83.  
  84.         message = f'{self.hostname}:{self.ipaddr}:{self.name}-{index}:started'
  85.         self.logger.info(message)
  86.  
  87.         while True:
  88.             errorlevel, message = socket.recv_multipart()
  89.             message = message.decode('utf-8')
  90.             errorlevel = errorlevel.decode('utf-8')
  91.             remote_logger.log(_nameToLevel[errorlevel], message)
  92.  
  93.  
  94. class Equals(Filter):
  95.     def __init__(self, param):
  96.         super().__init__()
  97.         self.errorlevel = param if param else NOTSET
  98.  
  99.     def filter(self, record):
  100.         return True if record.levelno == self.errorlevel else False
  101.  
  102.  
  103. class LessThan(Filter):
  104.     def __init__(self, param):
  105.         super().__init__()
  106.         self.errorlevel = param if param else WARNING
  107.  
  108.     def filter(self, record):
  109.         return True if record.levelno < self.errorlevel else False
  110.  
  111.  
  112. class GreaterThan(Filter):
  113.     def __init__(self, param):
  114.         super().__init__()
  115.         self.errorlevel = param if param else INFO
  116.  
  117.     def filter(self, record):
  118.         return True if record.levelno > self.errorlevel else False
  119.  
  120.  
  121. log_config = {
  122.     'version': 1,
  123.     'formatters': {
  124.         'remote': {'format': ''},
  125.         'default': {'format': LOGGER_FORMAT, 'datefmt': '%Y/%m/%d %H:%M:%S'}
  126.     },
  127.     'loggers': {
  128.         'local': {
  129.             'handlers': [
  130.                 'stdout',
  131.                 'stderr',
  132.                 'debug',
  133.                 'info',
  134.                 'warning',
  135.                 'error',
  136.                 'critical'
  137.             ]
  138.         },
  139.         'remote': {
  140.             'handlers': [
  141.                 'stdout2',
  142.                 'stderr2',
  143.                 'debug2',
  144.                 'info2',
  145.                 'warning2',
  146.                 'error2',
  147.                 'critical2'
  148.             ]
  149.         },
  150.     },
  151.     'filters': {
  152.         'stdout': {
  153.             '()': LessThan,
  154.             'param': WARNING
  155.         },
  156.         'stderr': {
  157.             '()': GreaterThan,
  158.             'param': INFO
  159.         },
  160.         'info': {
  161.             '()': Equals,
  162.             'param': INFO
  163.         },
  164.         'warning': {
  165.             '()': Equals,
  166.             'param': WARNING
  167.         },
  168.         'error': {
  169.             '()': Equals,
  170.             'param': ERROR
  171.         },
  172.         'critical': {
  173.             '()': Equals,
  174.             'param': CRITICAL
  175.         },
  176.     },
  177.     'handlers': {
  178.         'stdout': {
  179.             'class': 'logging.StreamHandler',
  180.             'level': DEBUG,
  181.             'stream': 'ext://sys.stdout',
  182.             'formatter': 'default',
  183.             'filters': ['stdout']
  184.         },
  185.         'stdout2': {
  186.             'class': 'logging.StreamHandler',
  187.             'level': DEBUG,
  188.             'stream': 'ext://sys.stdout',
  189.             'formatter': 'remote',
  190.             'filters': ['stdout']
  191.         },
  192.         'stderr': {
  193.             'class': 'logging.StreamHandler',
  194.             'level': WARNING,
  195.             'stream': 'ext://sys.stderr',
  196.             'formatter': 'default',
  197.             'filters': ['stderr']
  198.         },
  199.         'stderr2': {
  200.             'class': 'logging.StreamHandler',
  201.             'level': WARNING,
  202.             'stream': 'ext://sys.stderr',
  203.             'formatter': 'remote',
  204.             'filters': ['stderr']
  205.         },
  206.         'debug': {
  207.             'class': 'logging.handlers.RotatingFileHandler',
  208.             'filename': path.join(PATH_LOGS, 'local', 'debug.log'),
  209.             'level': DEBUG,
  210.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  211.             'backupCount': LOG_FILE_BACKUP_COUNT,
  212.             'formatter': 'default',
  213.         },
  214.         'debug2': {
  215.             'class': 'logging.handlers.RotatingFileHandler',
  216.             'filename': path.join(PATH_LOGS, 'debug.log'),
  217.             'level': DEBUG,
  218.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  219.             'backupCount': LOG_FILE_BACKUP_COUNT,
  220.             'formatter': 'remote',
  221.         },
  222.         'info': {
  223.             'class': 'logging.handlers.RotatingFileHandler',
  224.             'filename': path.join(PATH_LOGS, 'local', 'info.log'),
  225.             'level': INFO,
  226.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  227.             'backupCount': LOG_FILE_BACKUP_COUNT,
  228.             'formatter': 'default',
  229.             'filters': ['info'],
  230.         },
  231.         'info2': {
  232.             'class': 'logging.handlers.RotatingFileHandler',
  233.             'filename': path.join(PATH_LOGS, 'info.log'),
  234.             'level': INFO,
  235.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  236.             'backupCount': LOG_FILE_BACKUP_COUNT,
  237.             'formatter': 'remote',
  238.             'filters': ['info'],
  239.         },
  240.         'warning': {
  241.             'class': 'logging.handlers.RotatingFileHandler',
  242.             'filename': path.join(PATH_LOGS, 'local', 'warn.log'),
  243.             'level': WARNING,
  244.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  245.             'backupCount': LOG_FILE_BACKUP_COUNT,
  246.             'formatter': 'default',
  247.             'filters': ['warning'],
  248.         },
  249.         'warning2': {
  250.             'class': 'logging.handlers.RotatingFileHandler',
  251.             'filename': path.join(PATH_LOGS, 'warn.log'),
  252.             'level': WARNING,
  253.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  254.             'backupCount': LOG_FILE_BACKUP_COUNT,
  255.             'formatter': 'remote',
  256.             'filters': ['warning'],
  257.         },
  258.         'error': {
  259.             'class': 'logging.handlers.RotatingFileHandler',
  260.             'filename': path.join(PATH_LOGS, 'local', 'error.log'),
  261.             'level': ERROR,
  262.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  263.             'backupCount': LOG_FILE_BACKUP_COUNT,
  264.             'formatter': 'default',
  265.             'filters': ['error'],
  266.         },
  267.         'error2': {
  268.             'class': 'logging.handlers.RotatingFileHandler',
  269.             'filename': path.join(PATH_LOGS, 'error.log'),
  270.             'level': ERROR,
  271.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  272.             'backupCount': LOG_FILE_BACKUP_COUNT,
  273.             'formatter': 'remote',
  274.             'filters': ['error'],
  275.         },
  276.         'critical': {
  277.             'class': 'logging.handlers.RotatingFileHandler',
  278.             'filename': path.join(PATH_LOGS, 'local', 'critical.log'),
  279.             'level': CRITICAL,
  280.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  281.             'backupCount': LOG_FILE_BACKUP_COUNT,
  282.             'formatter': 'default',
  283.             'filters': ['critical'],
  284.         },
  285.         'critical2': {
  286.             'class': 'logging.handlers.RotatingFileHandler',
  287.             'filename': path.join(PATH_LOGS, 'critical.log'),
  288.             'level': CRITICAL,
  289.             'maxBytes': LOG_FILE_MAXIMUM_BYTES,
  290.             'backupCount': LOG_FILE_BACKUP_COUNT,
  291.             'formatter': 'remote',
  292.             'filters': ['critical'],
  293.         },
  294.     },
  295. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement