1""" 2This file sets up logging for the entire logparse package. Custom log formatter 3and handler classes are specified below and the logger is supplied to all 4subsequent modules, including parsers. 5""" 6 7__version__ ='2.0' 8__name__ ='logparse' 9 10 11from copy import copy 12import logging 13import logging.handlers 14 15 16# Standard shell escape codes 17ESC = { 18"reset":"\033[0m", 19"color":"\033[1;%dm", 20"bold":"\033[1m", 21"underlined":"\033[4m" 22} 23 24# Standard shell colour codes (30..39 are the foreground colors) 25DEFAULT =39 26BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN =range(30,37) 27 28# Map colours to log levels (used for level text only) 29COLORS = { 3010: BLUE,# debug 3120: DEFAULT,# info 3230: YELLOW,# warning 3340: RED,# error 3450: RED # critical 35} 36 37# Template for formatting log messages 38FORMAT = ("{bold}%(name)-15s{reset} %(levelname)-18s%(message)s" 39"({bold}%(filename)s{reset}:%(lineno)d)") 40 41 42classColoredFormatter(logging.Formatter): 43""" 44 Custom implementation of a log formatter to apply standard shell colour 45 escape sequences depending on the log level. The original record is copied 46 so as to not interfere with subsequent handlings (i.e. the syslog handler). 47 """ 48 49def__init__(self, msg): 50 logging.Formatter.__init__(self, msg) 51 52defformat(self, record): 53 temprecord =copy(record) 54 levelname = temprecord.levelname 55if temprecord.levelno in COLORS: 56 levelname_color = ESC["color"] % (COLORS[temprecord.levelno]) \ 57+ levelname + ESC["reset"] 58 temprecord.levelname = levelname_color 59 temprecord.name = record.name.replace(__name__ +".","") 60return logging.Formatter.format(self, temprecord) 61 62 63classColoredLogger(logging.Logger): 64""" 65 Custom implementation of a logger object using the `ColoredFormatter` class 66 above. This class also includes a syslog handler to direct a minimal amount 67 of output to /dev/log. 68 """ 69 70 message = FORMAT.format(**ESC) 71 72def__init__(self, name): 73""" 74 Initialise the logger for the entire package. This is done here so that 75 the configuration is applied to all child modules. A syslog handler 76 is also initialised, with a min level of INFO so that journald doesn't 77 get spammed with debug messages.. 78 """ 79 80 logging.Logger.__init__(self, name) 81 82 color_formatter =ColoredFormatter(self.message) 83 84 syslog_handler = logging.handlers.SysLogHandler(address ='/dev/log') 85 syslog_handler.setLevel(logging.INFO) 86 syslog_handler.setFormatter(logging.Formatter( 87 fmt='{}[%(process)d]: (%(module)s)%(message)s'.format(__name__))) 88 89 console = logging.StreamHandler() 90 console.setFormatter(color_formatter) 91 92 self.addHandler(console) 93 self.addHandler(syslog_handler) 94return 95 96 97# Initialise logger object 98logging.setLoggerClass(ColoredLogger) 99logger = logging.getLogger()