<s> """<STR_LIT>""" <EOL> import datetime <EOL> import logging <EOL> import os <EOL> import sha <EOL> import traceback <EOL> import urllib <EOL> from google . appengine . api import memcache <EOL> from google . appengine . api import namespace_manager <EOL> from google . appengine . ext import db <EOL> from google . appengine . ext import webapp <EOL> MAX_SIGNATURE_LENGTH = <NUM_LIT> <EOL> class ExceptionRecord ( db . Model ) : <EOL> """<STR_LIT>""" <EOL> signature = db . StringProperty ( required = True ) <EOL> major_version = db . StringProperty ( required = True ) <EOL> minor_version = db . IntegerProperty ( required = True ) <EOL> date = db . DateProperty ( required = True ) <EOL> count = db . IntegerProperty ( required = True , default = <NUM_LIT:0> ) <EOL> stacktrace = db . TextProperty ( required = True ) <EOL> http_method = db . TextProperty ( required = True ) <EOL> url = db . TextProperty ( required = True ) <EOL> handler = db . TextProperty ( required = True ) <EOL> @ classmethod <EOL> def get_key_name ( cls , signature , version , date = None ) : <EOL> """<STR_LIT>""" <EOL> if not date : <EOL> date = datetime . date . today ( ) <EOL> return '<STR_LIT>' % ( signature , date , version ) <EOL> class ExceptionRecordingHandler ( logging . Handler ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , log_interval = <NUM_LIT:10> ) : <EOL> """<STR_LIT>""" <EOL> self . log_interval = log_interval <EOL> logging . Handler . __init__ ( self ) <EOL> @ classmethod <EOL> def __RelativePath ( cls , path ) : <EOL> """<STR_LIT>""" <EOL> cwd = os . getcwd ( ) <EOL> if path . startswith ( cwd ) : <EOL> path = path [ len ( cwd ) + <NUM_LIT:1> : ] <EOL> return path <EOL> @ classmethod <EOL> def __GetSignature ( cls , exc_info ) : <EOL> """<STR_LIT>""" <EOL> ex_type , unused_value , trace = exc_info <EOL> frames = traceback . extract_tb ( trace ) <EOL> fulltype = '<STR_LIT>' % ( ex_type . __module__ , ex_type . __name__ ) <EOL> path , line_no = frames [ - <NUM_LIT:1> ] [ : <NUM_LIT:2> ] <EOL> path = cls . __RelativePath ( path ) <EOL> site = '<STR_LIT>' % ( path , line_no ) <EOL> signature = '<STR_LIT>' % ( fulltype , site ) <EOL> if len ( signature ) > MAX_SIGNATURE_LENGTH : <EOL> signature = '<STR_LIT>' % sha . new ( signature ) . hexdigest ( ) <EOL> return signature <EOL> @ classmethod <EOL> def __GetURL ( cls ) : <EOL> """<STR_LIT>""" <EOL> if os . environ [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> scheme = '<STR_LIT>' <EOL> else : <EOL> scheme = '<STR_LIT>' <EOL> host = os . environ [ '<STR_LIT>' ] <EOL> script_name = urllib . quote ( os . environ [ '<STR_LIT>' ] ) <EOL> path_info = urllib . quote ( os . environ [ '<STR_LIT>' ] ) <EOL> qs = os . environ . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> if qs : <EOL> qs = '<STR_LIT:?>' + qs <EOL> return scheme + host + script_name + path_info + qs <EOL> def __GetFormatter ( self ) : <EOL> """<STR_LIT>""" <EOL> if self . formatter : <EOL> return self . formatter <EOL> else : <EOL> return logging . _defaultFormatter <EOL> def emit ( self , record ) : <EOL> """<STR_LIT>""" <EOL> try : <EOL> if not record . exc_info : <EOL> return <EOL> signature = self . __GetSignature ( record . exc_info ) <EOL> old_namespace = namespace_manager . get_namespace ( ) <EOL> try : <EOL> namespace_manager . set_namespace ( '<STR_LIT>' ) <EOL> if not memcache . add ( signature , None , self . log_interval ) : <EOL> return <EOL> db . run_in_transaction_custom_retries ( <NUM_LIT:1> , self . __EmitTx , signature , <EOL> record . exc_info ) <EOL> finally : <EOL> namespace_manager . set_namespace ( old_namespace ) <EOL> except Exception : <EOL> self . handleError ( record ) <EOL> def __EmitTx ( self , signature , exc_info ) : <EOL> """<STR_LIT>""" <EOL> today = datetime . date . today ( ) <EOL> version = os . environ [ '<STR_LIT>' ] <EOL> major_ver , minor_ver = version . rsplit ( '<STR_LIT:.>' , <NUM_LIT:1> ) <EOL> minor_ver = int ( minor_ver ) <EOL> key_name = ExceptionRecord . get_key_name ( signature , version ) <EOL> exrecord = ExceptionRecord . get_by_key_name ( key_name ) <EOL> if not exrecord : <EOL> exrecord = ExceptionRecord ( <EOL> key_name = key_name , <EOL> signature = signature , <EOL> major_version = major_ver , <EOL> minor_version = minor_ver , <EOL> date = today , <EOL> stacktrace = self . __GetFormatter ( ) . formatException ( exc_info ) , <EOL> http_method = os . environ [ '<STR_LIT>' ] , <EOL> url = self . __GetURL ( ) , <EOL> handler = self . __RelativePath ( os . environ [ '<STR_LIT>' ] ) ) <EOL> exrecord . count += <NUM_LIT:1> <EOL> exrecord . put ( ) <EOL> def register_logger ( logger = None ) : <EOL> if not logger : <EOL> logger = logging . getLogger ( ) <EOL> handler = ExceptionRecordingHandler ( ) <EOL> logger . addHandler ( handler ) <EOL> return handler </s>
