<s> import os <EOL> import sys <EOL> import time <EOL> import types <EOL> import atexit <EOL> import logging <EOL> import operator <EOL> import textwrap <EOL> import traceback <EOL> from . import ansi , conf , ircutils , registry , utils <EOL> from . utils import minisix <EOL> deadlyExceptions = [ KeyboardInterrupt , SystemExit ] <EOL> testing = False <EOL> class Formatter ( logging . Formatter ) : <EOL> _fmtConf = staticmethod ( lambda : conf . supybot . log . format ( ) ) <EOL> def formatTime ( self , record , datefmt = None ) : <EOL> return timestamp ( record . created ) <EOL> def formatException ( self , exc_info ) : <EOL> ( E , e , tb ) = exc_info <EOL> for exn in deadlyExceptions : <EOL> if issubclass ( e . __class__ , exn ) : <EOL> raise <EOL> return logging . Formatter . formatException ( self , ( E , e , tb ) ) <EOL> def format ( self , record ) : <EOL> self . _fmt = self . _fmtConf ( ) <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> self . _style . _fmt = self . _fmtConf ( ) <EOL> return logging . Formatter . format ( self , record ) <EOL> class PluginFormatter ( Formatter ) : <EOL> _fmtConf = staticmethod ( lambda : conf . supybot . log . plugins . format ( ) ) <EOL> class Logger ( logging . Logger ) : <EOL> def exception ( self , * args ) : <EOL> ( E , e , tb ) = sys . exc_info ( ) <EOL> tbinfo = traceback . extract_tb ( tb ) <EOL> path = '<STR_LIT>' % '<STR_LIT:|>' . join ( map ( operator . itemgetter ( <NUM_LIT:2> ) , tbinfo ) ) <EOL> eStrId = '<STR_LIT>' % ( E , path ) <EOL> eId = hex ( hash ( eStrId ) & <NUM_LIT> ) <EOL> logging . Logger . exception ( self , * args ) <EOL> self . error ( '<STR_LIT>' , eId ) <EOL> self . debug ( '<STR_LIT:%s>' , utils . python . collect_extra_debug_data ( ) ) <EOL> def _log ( self , level , msg , args , exc_info = None , extra = None ) : <EOL> msg = format ( msg , * args ) <EOL> logging . Logger . _log ( self , level , msg , ( ) , exc_info = exc_info , <EOL> extra = extra ) <EOL> class StdoutStreamHandler ( logging . StreamHandler ) : <EOL> def format ( self , record ) : <EOL> s = logging . StreamHandler . format ( self , record ) <EOL> if record . levelname != '<STR_LIT>' and conf . supybot . log . stdout . wrap ( ) : <EOL> if not isinstance ( record . levelname , minisix . string_types ) : <EOL> print ( record ) <EOL> print ( record . levelname ) <EOL> print ( utils . stackTrace ( ) ) <EOL> prefixLen = len ( record . levelname ) + <NUM_LIT:1> <EOL> s = textwrap . fill ( s , width = <NUM_LIT> , subsequent_indent = '<STR_LIT:U+0020>' * prefixLen ) <EOL> s . rstrip ( '<STR_LIT:\r\n>' ) <EOL> return s <EOL> def emit ( self , record ) : <EOL> if conf . supybot . log . stdout ( ) and not conf . daemonized : <EOL> try : <EOL> logging . StreamHandler . emit ( self , record ) <EOL> except ValueError : <EOL> self . disable ( ) <EOL> error ( '<STR_LIT>' ) <EOL> exception ( '<STR_LIT>' ) <EOL> def disable ( self ) : <EOL> self . setLevel ( sys . maxsize ) <EOL> _logger . removeHandler ( self ) <EOL> logging . _acquireLock ( ) <EOL> try : <EOL> del logging . _handlers [ self ] <EOL> finally : <EOL> logging . _releaseLock ( ) <EOL> class BetterFileHandler ( logging . FileHandler ) : <EOL> def emit ( self , record ) : <EOL> msg = self . format ( record ) <EOL> try : <EOL> self . stream . write ( msg ) <EOL> except ( UnicodeError , TypeError ) : <EOL> try : <EOL> self . stream . write ( msg . encode ( "<STR_LIT:utf8>" ) ) <EOL> except ( UnicodeError , TypeError ) : <EOL> try : <EOL> self . stream . write ( msg . encode ( "<STR_LIT:utf8>" ) . decode ( '<STR_LIT:ascii>' , '<STR_LIT:replace>' ) ) <EOL> except ( UnicodeError , TypeError ) : <EOL> self . stream . write ( repr ( msg ) ) <EOL> self . stream . write ( os . linesep ) <EOL> try : <EOL> self . flush ( ) <EOL> except OSError as e : <EOL> if e . args [ <NUM_LIT:0> ] == <NUM_LIT> : <EOL> print ( '<STR_LIT>' ) <EOL> else : <EOL> raise <EOL> class ColorizedFormatter ( Formatter ) : <EOL> _fmtConf = staticmethod ( lambda : conf . supybot . log . stdout . format ( ) ) <EOL> def formatException ( self , exc_info ) : <EOL> ( E , e , tb ) = exc_info <EOL> if conf . supybot . log . stdout . colorized ( ) : <EOL> return '<STR_LIT>' . join ( [ ansi . RED , <EOL> Formatter . formatException ( self , ( E , e , tb ) ) , <EOL> ansi . RESET ] ) <EOL> else : <EOL> return Formatter . formatException ( self , ( E , e , tb ) ) <EOL> def format ( self , record , * args , ** kwargs ) : <EOL> if conf . supybot . log . stdout . colorized ( ) : <EOL> color = '<STR_LIT>' <EOL> if record . levelno == logging . CRITICAL : <EOL> color = ansi . WHITE + ansi . BOLD <EOL> elif record . levelno == logging . ERROR : <EOL> color = ansi . RED <EOL> elif record . levelno == logging . WARNING : <EOL> color = ansi . YELLOW <EOL> if color : <EOL> return '<STR_LIT>' . join ( [ color , <EOL> Formatter . format ( self , record , * args , ** kwargs ) , <EOL> ansi . RESET ] ) <EOL> else : <EOL> return Formatter . format ( self , record , * args , ** kwargs ) <EOL> else : <EOL> return Formatter . format ( self , record , * args , ** kwargs ) <EOL> conf . registerGlobalValue ( conf . supybot . directories , '<STR_LIT>' , <EOL> conf . Directory ( '<STR_LIT>' , """<STR_LIT>""" ) ) <EOL> _logDir = conf . supybot . directories . log ( ) <EOL> if not os . path . exists ( _logDir ) : <EOL> os . mkdir ( _logDir , <NUM_LIT> ) <EOL> pluginLogDir = os . path . join ( _logDir , '<STR_LIT>' ) <EOL> if not os . path . exists ( pluginLogDir ) : <EOL> os . mkdir ( pluginLogDir , <NUM_LIT> ) <EOL> try : <EOL> messagesLogFilename = os . path . join ( _logDir , '<STR_LIT>' ) <EOL> _handler = BetterFileHandler ( messagesLogFilename ) <EOL> except EnvironmentError as e : <EOL> raise SystemExit ( '<STR_LIT>' '<STR_LIT>' '<STR_LIT>' '<STR_LIT>' '<STR_LIT>' % ( messagesLogFilename , utils . gen . exnToString ( e ) ) ) <EOL> formatter = Formatter ( '<STR_LIT>' ) <EOL> pluginFormatter = PluginFormatter ( '<STR_LIT>' ) <EOL> logging . setLoggerClass ( Logger ) <EOL> _logger = logging . getLogger ( '<STR_LIT>' ) <EOL> _stdoutHandler = StdoutStreamHandler ( sys . stdout ) <EOL> class ValidLogLevel ( registry . String ) : <EOL> """<STR_LIT>""" <EOL> handler = None <EOL> minimumLevel = - <NUM_LIT:1> <EOL> def set ( self , s ) : <EOL> s = s . upper ( ) <EOL> try : <EOL> try : <EOL> level = logging . _levelNames [ s ] <EOL> except AttributeError : <EOL> level = logging . _nameToLevel [ s ] <EOL> except KeyError : <EOL> try : <EOL> level = int ( s ) <EOL> except ValueError : <EOL> self . error ( ) <EOL> if level < self . minimumLevel : <EOL> self . error ( ) <EOL> if self . handler is not None : <EOL> self . handler . setLevel ( level ) <EOL> self . setValue ( level ) <EOL> def __str__ ( self ) : <EOL> level = str ( logging . getLevelName ( self . value ) ) <EOL> if level . startswith ( '<STR_LIT>' ) : <EOL> level = level . split ( ) [ - <NUM_LIT:1> ] <EOL> return level <EOL> class LogLevel ( ValidLogLevel ) : <EOL> """<STR_LIT>""" <EOL> handler = _handler <EOL> class StdoutLogLevel ( ValidLogLevel ) : <EOL> """<STR_LIT>""" <EOL> handler = _stdoutHandler <EOL> conf . registerGroup ( conf . supybot , '<STR_LIT>' ) <EOL> conf . registerGlobalValue ( conf . supybot . log , '<STR_LIT>' , <EOL> registry . String ( '<STR_LIT>' , <EOL> """<STR_LIT>""" ) ) <EOL> conf . registerGlobalValue ( conf . supybot . log , '<STR_LIT>' , <EOL> LogLevel ( logging . INFO , """<STR_LIT>""" ) ) <EOL> conf . registerGlobalValue ( conf . supybot . log , '<STR_LIT>' , <EOL> registry . String ( '<STR_LIT>' , """<STR_LIT>""" ) ) <EOL> class BooleanRequiredFalseOnWindows ( registry . Boolean ) : <EOL> """<STR_LIT>""" <EOL> def set ( self , s ) : <EOL> registry . Boolean . set ( self , s ) <EOL> if self . value and os . name == '<STR_LIT>' : <EOL> self . error ( ) <EOL> conf . registerGlobalValue ( conf . supybot . log , '<STR_LIT>' , <EOL> registry . Boolean ( True , """<STR_LIT>""" ) ) <EOL> conf . registerGlobalValue ( conf . supybot . log . stdout , '<STR_LIT>' , <EOL> BooleanRequiredFalseOnWindows ( False , """<STR_LIT>""" ) ) <EOL> conf . registerGlobalValue ( conf . supybot . log . stdout , '<STR_LIT>' , <EOL> registry . Boolean ( False , """<STR_LIT>""" ) ) <EOL> conf . registerGlobalValue ( conf . supybot . log . stdout , '<STR_LIT>' , <EOL> registry . String ( '<STR_LIT>' , <EOL> """<STR_LIT>""" ) ) <EOL> conf . registerGlobalValue ( conf . supybot . log . stdout , '<STR_LIT>' , <EOL> StdoutLogLevel ( logging . INFO , """<STR_LIT>""" ) ) <EOL> conf . registerGroup ( conf . supybot . log , '<STR_LIT>' ) <EOL> conf . registerGlobalValue ( conf . supybot . log . plugins , '<STR_LIT>' , <EOL> registry . Boolean ( False , """<STR_LIT>""" ) ) <EOL> conf . registerGlobalValue ( conf . supybot . log . plugins , '<STR_LIT>' , <EOL> registry . String ( '<STR_LIT>' , <EOL> """<STR_LIT>""" ) ) <EOL> debug = _logger . debug <EOL> info = _logger . info <EOL> warning = _logger . warning <EOL> error = _logger . error <EOL> critical = _logger . critical <EOL> exception = _logger . exception <EOL> registry . error = error <EOL> registry . exception = exception <EOL> setLevel = _logger . setLevel <EOL> atexit . register ( logging . shutdown ) <EOL> ircutils . debug = debug <EOL> def getPluginLogger ( name ) : <EOL> if not conf . supybot . log . plugins . individualLogfiles ( ) : <EOL> return _logger <EOL> log = logging . getLogger ( '<STR_LIT>' % name ) <EOL> if not log . handlers : <EOL> filename = os . path . join ( pluginLogDir , '<STR_LIT>' % name ) <EOL> handler = BetterFileHandler ( filename ) <EOL> handler . setLevel ( - <NUM_LIT:1> ) <EOL> handler . setFormatter ( pluginFormatter ) <EOL> log . addHandler ( handler ) <EOL> if name in sys . modules : <EOL> log . info ( '<STR_LIT>' , name ) <EOL> return log <EOL> def timestamp ( when = None ) : <EOL> if when is None : <EOL> when = time . time ( ) <EOL> format = conf . supybot . log . timestampFormat ( ) <EOL> t = time . localtime ( when ) <EOL> if format : <EOL> return time . strftime ( format , t ) <EOL> else : <EOL> return str ( int ( time . mktime ( t ) ) ) <EOL> def firewall ( f , errorHandler = None ) : <EOL> def logException ( self , s = None ) : <EOL> if s is None : <EOL> s = '<STR_LIT>' <EOL> if hasattr ( self , '<STR_LIT>' ) : <EOL> logging_function = self . log . exception <EOL> else : <EOL> logging_function = exception <EOL> logging_function ( '<STR_LIT>' , s , self . __class__ . __name__ , f . __name__ ) <EOL> def m ( self , * args , ** kwargs ) : <EOL> try : <EOL> return f ( self , * args , ** kwargs ) <EOL> except Exception : <EOL> if testing : <EOL> raise <EOL> logException ( self ) <EOL> if errorHandler is not None : <EOL> try : <EOL> return errorHandler ( self , * args , ** kwargs ) <EOL> except Exception : <EOL> logException ( self , '<STR_LIT>' ) <EOL> m = utils . python . changeFunctionName ( m , f . __name__ , f . __doc__ ) <EOL> return m <EOL> class MetaFirewall ( type ) : <EOL> def __new__ ( cls , name , bases , classdict ) : <EOL> firewalled = { } <EOL> for base in bases : <EOL> if hasattr ( base , '<STR_LIT>' ) : <EOL> cls . updateFirewalled ( firewalled , base . __firewalled__ ) <EOL> cls . updateFirewalled ( firewalled , classdict . get ( '<STR_LIT>' , [ ] ) ) <EOL> for ( attr , errorHandler ) in firewalled . items ( ) : <EOL> if attr in classdict : <EOL> classdict [ attr ] = firewall ( classdict [ attr ] , errorHandler ) <EOL> return super ( MetaFirewall , cls ) . __new__ ( cls , name , bases , classdict ) <EOL> def getErrorHandler ( cls , dictOrTuple , name ) : <EOL> if isinstance ( dictOrTuple , dict ) : <EOL> return dictOrTuple [ name ] <EOL> else : <EOL> return None <EOL> getErrorHandler = classmethod ( getErrorHandler ) <EOL> def updateFirewalled ( cls , firewalled , __firewalled__ ) : <EOL> for attr in __firewalled__ : <EOL> firewalled [ attr ] = cls . getErrorHandler ( __firewalled__ , attr ) <EOL> updateFirewalled = classmethod ( updateFirewalled ) <EOL> Firewalled = MetaFirewall ( '<STR_LIT>' , ( ) , { } ) <EOL> class PluginLogFilter ( logging . Filter ) : <EOL> def filter ( self , record ) : <EOL> if conf . supybot . log . plugins . individualLogfiles ( ) : <EOL> if record . name . startswith ( '<STR_LIT>' ) : <EOL> return False <EOL> return True <EOL> _handler . setFormatter ( formatter ) <EOL> _handler . addFilter ( PluginLogFilter ( ) ) <EOL> _handler . setLevel ( conf . supybot . log . level ( ) ) <EOL> _logger . addHandler ( _handler ) <EOL> _logger . setLevel ( - <NUM_LIT:1> ) <EOL> _stdoutFormatter = ColorizedFormatter ( '<STR_LIT>' ) <EOL> _stdoutHandler . setFormatter ( _stdoutFormatter ) <EOL> _stdoutHandler . setLevel ( conf . supybot . log . stdout . level ( ) ) <EOL> if not conf . daemonized : <EOL> _logger . addHandler ( _stdoutHandler ) </s>
