logger.py (2429B)
1 # logger.py 2 # 3 # Copyright (C) 2017 Brian C. Lane 4 # 5 # This program is free software; you can redistribute it and/or modify 6 # it under the terms of the GNU General Public License as published by 7 # the Free Software Foundation; either version 2 of the License, or 8 # (at your option) any later version. 9 # 10 # This program is distributed in the hope that it will be useful, 11 # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 # GNU General Public License for more details. 14 # 15 # You should have received a copy of the GNU General Public License 16 # along with this program. If not, see <http://www.gnu.org/licenses/>. 17 import logging 18 from logging.handlers import RotatingFileHandler, QueueHandler 19 import multiprocessing as mp 20 21 import structlog 22 23 24 structlog.configure( 25 processors=[ 26 structlog.stdlib.filter_by_level, 27 structlog.stdlib.add_logger_name, 28 structlog.stdlib.add_log_level, 29 structlog.stdlib.PositionalArgumentsFormatter(), 30 structlog.processors.StackInfoRenderer(), 31 structlog.processors.format_exc_info, 32 structlog.processors.TimeStamper(fmt="iso"), 33 structlog.processors.UnicodeDecoder(), 34 structlog.processors.JSONRenderer(), 35 ], 36 context_class=dict, 37 logger_factory=structlog.stdlib.LoggerFactory(), 38 wrapper_class=structlog.stdlib.BoundLogger, 39 cache_logger_on_first_use=True, 40 ) 41 42 def listener(queue, stop_event, log_path): 43 handler = RotatingFileHandler(log_path, maxBytes=100*1024**2, backupCount=10) 44 formatter = logging.Formatter('%(message)s') 45 handler.setFormatter(formatter) 46 logger = logging.getLogger("logger-listener") 47 logger.addHandler(handler) 48 49 # XXX QueueListener doesn't work for me, do it manually 50 while not stop_event.is_set(): 51 try: 52 record = queue.get() 53 if record is None: # We send this as a sentinel to tell the listener to quit. 54 break 55 logger.handle(record) # No level or filter logic applied - just do it! 56 queue.task_done() 57 except (KeyboardInterrupt, SystemExit): 58 raise 59 except: 60 import sys, traceback 61 traceback.print_exc(file=sys.stderr) 62 63 def log(queue): 64 handler = QueueHandler(queue) 65 root = structlog.get_logger() 66 root.addHandler(handler) 67 root.setLevel(logging.DEBUG) 68 return root