<s> from twisted . internet import defer <EOL> import threading <EOL> import logging <EOL> logger = logging . getLogger ( __name__ ) <EOL> try : <EOL> import resource <EOL> RUSAGE_THREAD = <NUM_LIT:1> <EOL> resource . getrusage ( RUSAGE_THREAD ) <EOL> def get_thread_resource_usage ( ) : <EOL> return resource . getrusage ( RUSAGE_THREAD ) <EOL> except : <EOL> def get_thread_resource_usage ( ) : <EOL> return None <EOL> class LoggingContext ( object ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ <EOL> "<STR_LIT>" , "<STR_LIT:name>" , "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" , <EOL> ] <EOL> thread_local = threading . local ( ) <EOL> class Sentinel ( object ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ ] <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT>" <EOL> def copy_to ( self , record ) : <EOL> pass <EOL> def start ( self ) : <EOL> pass <EOL> def stop ( self ) : <EOL> pass <EOL> def add_database_transaction ( self , duration_ms ) : <EOL> pass <EOL> def __nonzero__ ( self ) : <EOL> return False <EOL> sentinel = Sentinel ( ) <EOL> def __init__ ( self , name = None ) : <EOL> self . previous_context = LoggingContext . current_context ( ) <EOL> self . name = name <EOL> self . ru_stime = <NUM_LIT:0.> <EOL> self . ru_utime = <NUM_LIT:0.> <EOL> self . db_txn_count = <NUM_LIT:0> <EOL> self . db_txn_duration = <NUM_LIT:0.> <EOL> self . usage_start = None <EOL> self . main_thread = threading . current_thread ( ) <EOL> self . tag = "<STR_LIT>" <EOL> self . alive = True <EOL> def __str__ ( self ) : <EOL> return "<STR_LIT>" % ( self . name , id ( self ) ) <EOL> @ classmethod <EOL> def current_context ( cls ) : <EOL> """<STR_LIT>""" <EOL> return getattr ( cls . thread_local , "<STR_LIT>" , cls . sentinel ) <EOL> @ classmethod <EOL> def set_current_context ( cls , context ) : <EOL> """<STR_LIT>""" <EOL> current = cls . current_context ( ) <EOL> if current is not context : <EOL> current . stop ( ) <EOL> cls . thread_local . current_context = context <EOL> context . start ( ) <EOL> return current <EOL> def __enter__ ( self ) : <EOL> """<STR_LIT>""" <EOL> old_context = self . set_current_context ( self ) <EOL> if self . previous_context != old_context : <EOL> logger . warn ( <EOL> "<STR_LIT>" , <EOL> self . previous_context , old_context <EOL> ) <EOL> self . alive = True <EOL> return self <EOL> def __exit__ ( self , type , value , traceback ) : <EOL> """<STR_LIT>""" <EOL> current = self . set_current_context ( self . previous_context ) <EOL> if current is not self : <EOL> if current is self . sentinel : <EOL> logger . debug ( "<STR_LIT>" , self ) <EOL> else : <EOL> logger . warn ( <EOL> "<STR_LIT>" , <EOL> current , <EOL> self <EOL> ) <EOL> self . previous_context = None <EOL> self . alive = False <EOL> def copy_to ( self , record ) : <EOL> """<STR_LIT>""" <EOL> for key , value in self . __dict__ . items ( ) : <EOL> setattr ( record , key , value ) <EOL> record . ru_utime , record . ru_stime = self . get_resource_usage ( ) <EOL> def start ( self ) : <EOL> if threading . current_thread ( ) is not self . main_thread : <EOL> return <EOL> if self . usage_start and self . usage_end : <EOL> self . ru_utime += self . usage_end . ru_utime - self . usage_start . ru_utime <EOL> self . ru_stime += self . usage_end . ru_stime - self . usage_start . ru_stime <EOL> self . usage_start = None <EOL> self . usage_end = None <EOL> if not self . usage_start : <EOL> self . usage_start = get_thread_resource_usage ( ) <EOL> def stop ( self ) : <EOL> if threading . current_thread ( ) is not self . main_thread : <EOL> return <EOL> if self . usage_start : <EOL> self . usage_end = get_thread_resource_usage ( ) <EOL> def get_resource_usage ( self ) : <EOL> ru_utime = self . ru_utime <EOL> ru_stime = self . ru_stime <EOL> if self . usage_start and threading . current_thread ( ) is self . main_thread : <EOL> current = get_thread_resource_usage ( ) <EOL> ru_utime += current . ru_utime - self . usage_start . ru_utime <EOL> ru_stime += current . ru_stime - self . usage_start . ru_stime <EOL> return ru_utime , ru_stime <EOL> def add_database_transaction ( self , duration_ms ) : <EOL> self . db_txn_count += <NUM_LIT:1> <EOL> self . db_txn_duration += duration_ms / <NUM_LIT> <EOL> class LoggingContextFilter ( logging . Filter ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , ** defaults ) : <EOL> self . defaults = defaults <EOL> def filter ( self , record ) : <EOL> """<STR_LIT>""" <EOL> context = LoggingContext . current_context ( ) <EOL> for key , value in self . defaults . items ( ) : <EOL> setattr ( record , key , value ) <EOL> context . copy_to ( record ) <EOL> return True <EOL> class PreserveLoggingContext ( object ) : <EOL> """<STR_LIT>""" <EOL> __slots__ = [ "<STR_LIT>" , "<STR_LIT>" , "<STR_LIT>" ] <EOL> def __init__ ( self , new_context = LoggingContext . sentinel ) : <EOL> self . new_context = new_context <EOL> def __enter__ ( self ) : <EOL> """<STR_LIT>""" <EOL> self . current_context = LoggingContext . set_current_context ( <EOL> self . new_context <EOL> ) <EOL> if self . current_context : <EOL> self . has_parent = self . current_context . previous_context is not None <EOL> if not self . current_context . alive : <EOL> logger . debug ( <EOL> "<STR_LIT>" , <EOL> self . current_context , <EOL> ) <EOL> def __exit__ ( self , type , value , traceback ) : <EOL> """<STR_LIT>""" <EOL> context = LoggingContext . set_current_context ( self . current_context ) <EOL> if context != self . new_context : <EOL> logger . debug ( <EOL> "<STR_LIT>" , <EOL> context , self . new_context , <EOL> ) <EOL> if self . current_context is not LoggingContext . sentinel : <EOL> if not self . current_context . alive : <EOL> logger . debug ( <EOL> "<STR_LIT>" , <EOL> self . current_context , <EOL> ) <EOL> class _PreservingContextDeferred ( defer . Deferred ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , context ) : <EOL> self . _log_context = context <EOL> defer . Deferred . __init__ ( self ) <EOL> def addCallbacks ( self , callback , errback = None , <EOL> callbackArgs = None , callbackKeywords = None , <EOL> errbackArgs = None , errbackKeywords = None ) : <EOL> callback = self . _wrap_callback ( callback ) <EOL> errback = self . _wrap_callback ( errback ) <EOL> return defer . Deferred . addCallbacks ( <EOL> self , callback , <EOL> errback = errback , <EOL> callbackArgs = callbackArgs , <EOL> callbackKeywords = callbackKeywords , <EOL> errbackArgs = errbackArgs , <EOL> errbackKeywords = errbackKeywords , <EOL> ) <EOL> def _wrap_callback ( self , f ) : <EOL> def g ( res , * args , ** kwargs ) : <EOL> with PreserveLoggingContext ( self . _log_context ) : <EOL> res = f ( res , * args , ** kwargs ) <EOL> return res <EOL> return g <EOL> def preserve_context_over_fn ( fn , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> with PreserveLoggingContext ( ) : <EOL> res = fn ( * args , ** kwargs ) <EOL> if isinstance ( res , defer . Deferred ) : <EOL> return preserve_context_over_deferred ( res ) <EOL> else : <EOL> return res <EOL> def preserve_context_over_deferred ( deferred ) : <EOL> """<STR_LIT>""" <EOL> current_context = LoggingContext . current_context ( ) <EOL> d = _PreservingContextDeferred ( current_context ) <EOL> deferred . chainDeferred ( d ) <EOL> return d <EOL> def preserve_fn ( f ) : <EOL> """<STR_LIT>""" <EOL> current = LoggingContext . current_context ( ) <EOL> def g ( * args , ** kwargs ) : <EOL> with PreserveLoggingContext ( current ) : <EOL> return f ( * args , ** kwargs ) <EOL> return g <EOL> _to_ignore = [ <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> "<STR_LIT>" , <EOL> ] <EOL> def logcontext_tracer ( frame , event , arg ) : <EOL> """<STR_LIT>""" <EOL> if event == '<STR_LIT>' : <EOL> name = frame . f_globals [ "<STR_LIT>" ] <EOL> if name . startswith ( "<STR_LIT>" ) : <EOL> if name == "<STR_LIT>" : <EOL> if frame . f_code . co_name in [ "<STR_LIT>" , "<STR_LIT>" ] : <EOL> tracer = frame . f_back . f_trace <EOL> if tracer : <EOL> tracer . just_changed = True <EOL> tracer = frame . f_trace <EOL> if tracer : <EOL> return tracer <EOL> if not any ( name . startswith ( ig ) for ig in _to_ignore ) : <EOL> return LineTracer ( ) <EOL> class LineTracer ( object ) : <EOL> __slots__ = [ "<STR_LIT>" , "<STR_LIT>" ] <EOL> def __init__ ( self ) : <EOL> self . context = LoggingContext . current_context ( ) <EOL> self . just_changed = False <EOL> def __call__ ( self , frame , event , arg ) : <EOL> if event in '<STR_LIT>' : <EOL> if self . just_changed : <EOL> self . context = LoggingContext . current_context ( ) <EOL> self . just_changed = False <EOL> else : <EOL> c = LoggingContext . current_context ( ) <EOL> if c != self . context : <EOL> logger . info ( <EOL> "<STR_LIT>" , <EOL> self . context , c , <EOL> frame . f_code . co_filename , frame . f_lineno <EOL> ) <EOL> self . context = c <EOL> return self </s>
