<s> import logging <EOL> import logging . handlers <EOL> import multiprocessing <EOL> import os <EOL> import re <EOL> import threading <EOL> import traceback <EOL> import sys <EOL> import time <EOL> LOGGERS = { } <EOL> LOGGER_QUEUE_MAP = { } <EOL> default_logger_location = '<STR_LIT>' <EOL> default_logger_name = '<STR_LIT>' <EOL> def set_default_logger_location ( loc ) : <EOL> global default_logger_location <EOL> default_logger_location = loc <EOL> def set_default_logger_name ( name ) : <EOL> global default_logger_name <EOL> default_logger_name = name <EOL> class ParentLoggerDoesNotExist ( Exception ) : <EOL> def __init__ ( self , parent_logger_name ) : <EOL> self . reason = "<STR_LIT>" "<STR_LIT>" % parent_logger_name <EOL> def _create_parent_logger ( parent_logger_name ) : <EOL> if parent_logger_name not in LOGGERS : <EOL> logger = _create_timed_rotating_logger ( parent_logger_name ) <EOL> LOGGERS [ parent_logger_name ] = logger <EOL> LOGGER_QUEUE_MAP [ parent_logger_name ] = multiprocessing . Queue ( - <NUM_LIT:1> ) <EOL> return LOGGERS [ parent_logger_name ] <EOL> def _create_child_logger ( parent_logger_name ) : <EOL> child_logger_name = "<STR_LIT>" % parent_logger_name <EOL> if child_logger_name in LOGGERS : <EOL> return LOGGERS [ child_logger_name ] <EOL> if parent_logger_name in LOGGERS : <EOL> queue = LOGGER_QUEUE_MAP [ parent_logger_name ] <EOL> logger = _create_queue_logger ( child_logger_name , queue ) <EOL> LOGGERS [ child_logger_name ] = logger <EOL> else : <EOL> raise ParentLoggerDoesNotExist ( parent_logger_name ) <EOL> return LOGGERS [ child_logger_name ] <EOL> def _logger_factory ( parent_logger_name , is_parent ) : <EOL> if parent_logger_name is None : <EOL> parent_logger_name = default_logger_name <EOL> if is_parent : <EOL> return _create_parent_logger ( parent_logger_name ) <EOL> else : <EOL> return _create_child_logger ( parent_logger_name ) <EOL> def get_logger ( name = None , is_parent = True ) : <EOL> return _logger_factory ( name , is_parent ) <EOL> def warn ( msg , name = None ) : <EOL> if name is None : <EOL> name = default_logger_name <EOL> get_logger ( name = name , is_parent = False ) . warn ( msg ) <EOL> def error ( msg , name = None ) : <EOL> if name is None : <EOL> name = default_logger_name <EOL> get_logger ( name = name , is_parent = False ) . error ( msg ) <EOL> def info ( msg , name = None ) : <EOL> if name is None : <EOL> name = default_logger_name <EOL> get_logger ( name = name , is_parent = False ) . info ( msg ) <EOL> def _create_timed_rotating_logger ( name ) : <EOL> logger = logging . getLogger ( name ) <EOL> logger . setLevel ( logging . DEBUG ) <EOL> handler = TimedRotatingFileHandlerWithCurrentTimestamp ( <EOL> default_logger_location % name , when = '<STR_LIT>' , interval = <NUM_LIT:1> , <EOL> backupCount = <NUM_LIT:6> ) <EOL> formatter = logging . Formatter ( <EOL> '<STR_LIT>' ) <EOL> handler . setFormatter ( formatter ) <EOL> logger . addHandler ( handler ) <EOL> logger . handlers [ <NUM_LIT:0> ] . doRollover ( ) <EOL> return logger <EOL> def _create_queue_logger ( name , queue ) : <EOL> logger = logging . getLogger ( name ) <EOL> logger . setLevel ( logging . DEBUG ) <EOL> handler = QueueHandler ( queue ) <EOL> formatter = logging . Formatter ( <EOL> '<STR_LIT>' ) <EOL> handler . setFormatter ( formatter ) <EOL> logger . addHandler ( handler ) <EOL> return logger <EOL> class QueueHandler ( logging . Handler ) : <EOL> def __init__ ( self , queue ) : <EOL> logging . Handler . __init__ ( self ) <EOL> self . queue = queue <EOL> def emit ( self , record ) : <EOL> try : <EOL> if record . exc_info : <EOL> self . format ( record ) <EOL> record . exc_info = None <EOL> if record . args : <EOL> record . msg = record . msg % record . args <EOL> record . args = None <EOL> self . queue . put_nowait ( record ) <EOL> except ( KeyboardInterrupt , SystemExit ) : <EOL> raise <EOL> except : <EOL> self . handleError ( record ) <EOL> class LogListener : <EOL> def __init__ ( self , logger ) : <EOL> self . logger = logger <EOL> self . queue = get_queue ( logger . name ) <EOL> def start ( self ) : <EOL> self . thread = threading . Thread ( target = self . _receive ) <EOL> self . thread . daemon = True <EOL> self . thread . start ( ) <EOL> def _receive ( self ) : <EOL> while True : <EOL> try : <EOL> record = self . queue . get ( ) <EOL> if record is None : <EOL> break <EOL> self . logger . handle ( record ) <EOL> except ( KeyboardInterrupt , SystemExit ) : <EOL> raise <EOL> except EOFError : <EOL> break <EOL> except : <EOL> traceback . print_exc ( file = sys . stderr ) <EOL> def end ( self ) : <EOL> self . queue . put_nowait ( None ) <EOL> self . thread . join ( ) <EOL> for handler in self . logger . handlers : <EOL> handler . close ( ) <EOL> def get_queue ( logger_name ) : <EOL> return LOGGER_QUEUE_MAP [ logger_name ] <EOL> class TimedRotatingFileHandlerWithCurrentTimestamp ( <EOL> logging . handlers . TimedRotatingFileHandler ) : <EOL> def __init__ ( self , filename , when = '<STR_LIT:h>' , interval = <NUM_LIT:1> , backupCount = <NUM_LIT:0> , <EOL> encoding = None , delay = False , utc = False ) : <EOL> logging . handlers . TimedRotatingFileHandler . __init__ ( <EOL> self , filename , when , interval , backupCount , encoding , delay , utc ) <EOL> self . suffix = "<STR_LIT>" <EOL> self . extMatch = re . compile ( r"<STR_LIT>" ) <EOL> def doRollover ( self ) : <EOL> """<STR_LIT>""" <EOL> currentTime = int ( time . time ( ) ) <EOL> if self . stream : <EOL> self . stream . close ( ) <EOL> self . stream = None <EOL> if self . utc : <EOL> timeTuple = time . gmtime ( currentTime ) <EOL> else : <EOL> timeTuple = time . localtime ( currentTime ) <EOL> dfn = self . baseFilename + "<STR_LIT:.>" + time . strftime ( self . suffix , timeTuple ) <EOL> if os . path . exists ( dfn ) : <EOL> os . remove ( dfn ) <EOL> os . rename ( self . baseFilename , dfn ) <EOL> if self . backupCount > <NUM_LIT:0> : <EOL> for s in self . getFilesToDelete ( ) : <EOL> os . remove ( s ) <EOL> self . mode = '<STR_LIT:w>' <EOL> self . stream = self . _open ( ) <EOL> newRolloverAt = self . computeRollover ( currentTime ) <EOL> while newRolloverAt <= currentTime : <EOL> newRolloverAt = newRolloverAt + self . interval <EOL> if ( self . when == '<STR_LIT>' or self . when . startswith ( '<STR_LIT>' ) ) and not self . utc : <EOL> dstNow = time . localtime ( currentTime ) [ - <NUM_LIT:1> ] <EOL> dstAtRollover = time . localtime ( newRolloverAt ) [ - <NUM_LIT:1> ] <EOL> if dstNow != dstAtRollover : <EOL> if not dstNow : <EOL> newRolloverAt = newRolloverAt - <NUM_LIT> <EOL> else : <EOL> newRolloverAt = newRolloverAt + <NUM_LIT> <EOL> self . rolloverAt = newRolloverAt </s>
