1#!/usr/bin/env python 2"""Log utilities for tmuxp. 3 4tmuxp.log 5~~~~~~~~~ 6 7""" 8import logging 9import time 10 11from colorama import Fore, Style 12 13LEVEL_COLORS = { 14 'DEBUG': Fore.BLUE, # Blue 15 'INFO': Fore.GREEN, # Green 16 'WARNING': Fore.YELLOW, 17 'ERROR': Fore.RED, 18 'CRITICAL': Fore.RED, 19} 20 21LOG_LEVELS = { 22 'CRITICAL': 50, 23 'ERROR': 40, 24 'WARNING': 30, 25 'INFO': 20, 26 'DEBUG': 10, 27 'NOTSET': 0, 28} 29 30 31def set_style( 32 message, stylized, style_before=None, style_after=None, prefix='', suffix='' 33): 34 if stylized: 35 return prefix + style_before + message + style_after + suffix 36 37 return prefix + message + suffix 38 39 40def default_log_template(self, record, stylized=False): 41 """ 42 Return the prefix for the log message. Template for Formatter. 43 44 Parameters 45 ---------- 46 :py:class:`logging.LogRecord` : 47 object. this is passed in from inside the 48 :py:meth:`logging.Formatter.format` record. 49 50 Returns 51 ------- 52 str 53 template for logger message 54 """ 55 56 reset = Style.RESET_ALL 57 levelname = set_style( 58 '(%(levelname)s)', 59 stylized, 60 style_before=(LEVEL_COLORS.get(record.levelname) + Style.BRIGHT), 61 style_after=Style.RESET_ALL, 62 suffix=' ', 63 ) 64 asctime = set_style( 65 '%(asctime)s', 66 stylized, 67 style_before=(Fore.BLACK + Style.DIM + Style.BRIGHT), 68 style_after=(Fore.RESET + Style.RESET_ALL), 69 prefix='[', 70 suffix=']', 71 ) 72 name = set_style( 73 '%(name)s', 74 stylized, 75 style_before=(Fore.WHITE + Style.DIM + Style.BRIGHT), 76 style_after=(Fore.RESET + Style.RESET_ALL), 77 prefix=' ', 78 suffix=' ', 79 ) 80 81 if stylized: 82 return reset + levelname + asctime + name + reset 83 84 return levelname + asctime + name 85 86 87class LogFormatter(logging.Formatter): 88 template = default_log_template 89 90 def __init__(self, color=True, *args, **kwargs): 91 logging.Formatter.__init__(self, *args, **kwargs) 92 93 def format(self, record): 94 try: 95 record.message = record.getMessage() 96 except Exception as e: 97 record.message = "Bad message (%r): %r" % (e, record.__dict__) 98 99 date_format = '%H:%m:%S' 100 record.asctime = time.strftime(date_format, self.converter(record.created)) 101 102 prefix = self.template(record) % record.__dict__ 103 104 parts = prefix.split(record.message) 105 formatted = prefix + " " + record.message 106 return formatted.replace("\n", "\n" + parts[0] + " ") 107 108 109def debug_log_template(self, record): 110 """ 111 Return the prefix for the log message. Template for Formatter. 112 113 Parameters 114 ---------- 115 record : :py:class:`logging.LogRecord` 116 This is passed in from inside the :py:meth:`logging.Formatter.format` 117 record. 118 119 Returns 120 ------- 121 str 122 Log template. 123 """ 124 125 reset = Style.RESET_ALL 126 levelname = ( 127 LEVEL_COLORS.get(record.levelname) 128 + Style.BRIGHT 129 + '(%(levelname)1.1s)' 130 + Style.RESET_ALL 131 + ' ' 132 ) 133 asctime = ( 134 '[' 135 + Fore.BLACK 136 + Style.DIM 137 + Style.BRIGHT 138 + '%(asctime)s' 139 + Fore.RESET 140 + Style.RESET_ALL 141 + ']' 142 ) 143 name = ( 144 ' ' 145 + Fore.WHITE 146 + Style.DIM 147 + Style.BRIGHT 148 + '%(name)s' 149 + Fore.RESET 150 + Style.RESET_ALL 151 + ' ' 152 ) 153 module_funcName = Fore.GREEN + Style.BRIGHT + '%(module)s.%(funcName)s()' 154 lineno = ( 155 Fore.BLACK 156 + Style.DIM 157 + Style.BRIGHT 158 + ':' 159 + Style.RESET_ALL 160 + Fore.CYAN 161 + '%(lineno)d' 162 ) 163 164 tpl = reset + levelname + asctime + name + module_funcName + lineno + reset 165 166 return tpl 167 168 169class DebugLogFormatter(LogFormatter): 170 """Provides greater technical details than standard log Formatter.""" 171 172 template = debug_log_template 173