§ ½@¾j÷&ã ó´—UddlZddlZddlZddlZddlZddlZddlZddlZddlZddl m Z ddl m Z m Z m Z ddlmZddlZddlmZdZdZdZejGd „d ¦«¦«ZGd „d ejj¦«Zd efd„Zde de d edefd„ZejGd„d¦«¦«Zia e!edzefe"d<efdedzd ededej#fd„Z$defd„Z%dS)éN)Údatetime)ÚEventÚProcessÚQueue)Ú SentryHandler)Úinit_lve_utils_sentry_clienté i,z4%(asctime)s - %(name)s - %(levelname)s - %(message)scóš—eZdZUdZeed<edzed<edzed<edzed<edzed<edzed<ed e j fd „¦«Z d „Z dS) ÚProcessDescriptiona Process description object pid: int - process id ppid: int | None - parent process id user: str | None - process owner status: str | None - process status start_time: datetime | None - process start time cmdline: str | None - process command line ÚpidNÚppidÚuserÚstatusÚ start_timeÚcmdlineÚprocesscó— | ¦«}n#t$rd}YnwxYw d | ¦«¦«}n#t$rd}YnwxYw t j| ¦«¦«}n#t$rd}YnwxYw | ¦«}n#t$rd}YnwxYw | ¦«}n#t$rd}YnwxYw||j |||||¦«S)z”>ˆDˆDøÝð ð ð ØˆDˆDˆDð øøøð Ø—h’h˜wŸšÑ0Ô0Ñ1Ô1ˆGˆGøÝð ð ð ØˆGˆGˆGð øøøð Ý!Ô/°×0CÒ0CÑ0EÔ0EÑFÔFˆJˆJøÝð ð ð ØˆJˆJˆJð øøøð Ø×#Ò#Ñ%Ô%ˆDˆDøÝð ð ð ØˆDˆDˆDð øøøð Ø—^’^Ñ%Ô%ˆFˆFøÝð ð ð ØˆFˆFˆFð øøøàˆs�7”;  d¨F°JÀÑHÔHÐHsS‚— &¥&ª'AÁ A!Á A!Á%&B  BÂBÂB4Â4 CÃCÃCà C+Ã*C+c óf—d|j›d|j›d|j›d|j›d|j›d|j›� S)NzPID: z, PPID: z, User: z , Status: z Start time: z Command: )r r rrrr©Úselfs rÚto_strzProcessDescription.to_strMsr€ðE�t”xðEðE¨¬ðEðE¸D¼IðEðEÐQUÔQ\ðEðEØœ?ðEðEØ6:´lðEðEð Eó) Ú__name__Ú __module__Ú __qualname__Ú__doc__ÚintÚ__annotations__ÚstrrÚ classmethodÚpsutilrrr ©r!rr r s»€€€€€€ð ð ð €H€H�HØ �‰*ÐÐÑØ �‰*ÐÐÑØ �$‰JÐÐÑØ˜4‘ÐÐÑØ �4‰ZÐÐÑàðI &¤.ðIðIðIñ„[ðIð0EðEðEðEðEr!r cót‡—eZdZeedœdedefˆfd„Zd„Zˆfd„Zd„Z d„Z d „Z d „Z e d „¦«Zd „ZˆxZS) ÚQueueListenerWithHistory)ÚtimeoutÚrecords_history_sizer.r/có”•—t¦«j|g|¢RddiŽtjg|¬¦«|_||_d|_dS)a“Queue listener with log records history :param multiprocessing.Queue queue: log records queue :param int timeout: log records flow timeout, defaults to DEFAULT_LOG_EVENTS_TIMEOUT In case timeput is reached, last log records and process ancestors are logged :param int records_history_size: the max number of records to log in case of timeout Úrespect_handler_levelT)ÚiterableÚmaxlenFN)ÚsuperÚ__init__Ú collectionsÚdequeÚ_records_history_queueÚ_timeoutÚ_timout_registred)rÚqueuer.r/ÚhandlersÚ __class__s €rr5z!QueueListenerWithHistory.__init__Ssfø€ð �‰ŒÔ˜ÐF ÐFÐFÐFÀÐFÐFÐFÝLWÔL]ØØ'ðM ñM ôM ˆÔ#𠈌 Ø!&ˆÔÐÐr!cóÔ— |j |j¬¦«}|j |¦«n*#tj$r| ¦«YnwxYwŒf|S)zDequeue log eventT©r.)r;Úgetr9r8ÚappendÚEmptyÚ_handle_queue_timeout)rÚ_blockÚrecords rÚdequeuez QueueListenerWithHistory.dequeueis~€ð -ð -ØœŸš°´ ˜Ñ>Ô>�ØÔ+×2Ò2°6Ñ:Ô:Ð:ØøÝ”;ð -ð -ð -Ø×*Ò*Ñ,Ô,Ð,Ð,Ð,ð -øøøð  -ðˆ sƒ:>¾#A$Á#A$c󘕗| ¦«t¦« ¦«| ¦«dS)zMain loop to process log eventsN)Ú_handle_monitor_startedr4Ú_monitorÚ_handle_monitor_finished)rr=s €rrIz!QueueListenerWithHistory._monitortsCø€à ×$Ò$Ñ&Ô&Ð&Ý ‰Œ×ÒÑÔÐØ ×%Ò%Ñ'Ô'Ð'Ð'Ð'r!có6—tj¦«|_dS)z+Start monitoring log events processing timeN)ÚtimeÚ _start_tsrs rrHz0QueueListenerWithHistory._handle_monitor_startedzs€åœ™œˆŒˆˆr!cóÞ—|jdurc| tjdt j¦«|jz t j¦«¦«}| |¦«dSdS)z0Log that monitor finished processing log recordsTz/Processing log queue took %.4f seconds. Pid: %sN) r:Ú_create_recordÚloggingÚERRORrLrMÚosÚgetpidÚhandle)rÚrs rrJz1QueueListenerWithHistory._handle_monitor_finished~sc€à Ô ! TÐ )Ð )Ø×#Ò#Ý” ØAÝ” ‘ ” ˜dœnÑ,Ý” ‘ ” ñ ôˆAð �KŠK˜‰NŒNˆNˆNˆNð *Ð )r!cóv—g} tj¦«}t |¦«g}| ¦«x}dkr[tj|¦«}| t |¦«¦«| ¦«x}dk°[|S#t $r|cYSwxYw)z%Collect process ancestors up to pid 1r)r*rr rr rAr)rÚ ancestorsrr s rÚ_get_ancestorsz'QueueListenerWithHistory._get_ancestors‰s€à.0ˆ ð Ý”nÑ&Ô&ˆGÝ+×7Ò7¸Ñ@Ô@ÐAˆIØ"Ÿ<š<™>œ>Ð)�4¨aÒ/Ð/Ý œ.¨Ñ.Ô.�Ø× Ò Õ!3×!?Ò!?ÀÑ!HÔ!HÑIÔIÐIð#Ÿ<š<™>œ>Ð)�4¨aÒ/Ð/ðÐ øÝð ð ð ØÐ Ð Ð ð øøøs„B$B)Â) B8Â7B8c óB—tjt|dd||d¬¦«S)zCreate log recordÚéN)ÚnameÚlevelÚpathnameÚlinenoÚmsgÚargsÚexc_info)rPÚ LogRecordr")rr]r`ras rrOz'QueueListenerWithHistory._create_record–s1€åÔ ÝØØØØØØð ñ ô ð r!có¾—tj|j¦«}|jtjkr|j}ndt|j¦«›d�}d|j›d|›d|›�S)a6 Format one buffered record for the timeout report. DEBUG (sub-INFO) message bodies are redacted so secrets logged only at DEBUG are not promoted into the durable on-disk / Sentry timeout diagnostic; the level, timestamp and body length are retained for hang diagnosis. zú[z] - z: ) rrÚcreatedÚlevelnorPÚINFOÚmessageÚlenÚ levelname)rEÚ timestampÚbodys rÚ_format_history_recordz/QueueListenerWithHistory._format_history_record¢si€õÔ*¨6¬>Ñ:Ô:ˆ Ø Œ>�Wœ\Ò )Ð )Ø”>ˆDˆDàI­C°´Ñ,?Ô,?ÐIÐIÐIˆDØ<�6Ô#Ð<Ð<¨Ð<Ð<°dÐ<Ð<ÐK—|]}| ¦«V—ŒdS©N)r )Ú.0Ú proc_descrs rú zAQueueListenerWithHistory._handle_queue_timeout..¸s?èè€ð'ð'Ø(2� ×!Ò!Ñ#Ô#ð'ð'ð'ð'ð'ð'r!Néÿÿÿÿc3óB•K—|]}‰ |¦«V—ŒdSrr)rn)rsrErs €rruzAQueueListenerWithHistory._handle_queue_timeout..»sEøèè€ð$ð$àð×+Ò+¨FÑ3Ô3ð$ð$ð$ð$ð$ð$r!z8Log queue timeout. Last events: %s Process ancestors: %sT)r:rrXr8rOrPrQrT)rÚproc_ancestorsÚ last_eventsÚ error_msgÚ error_argsrUs` rrCz.QueueListenerWithHistory._handle_queue_timeout±sìø€ð Ô ! UÐ *Ð *Ø!ŸYšYð'ð'Ø6:×6IÒ6IÑ6KÔ6KÈDÈDÈbÈDÔ6Qð'ñ'ô'ñôˆNðŸ)š)ð$ð$ð$ð$à"Ô9ð$ñ$ô$ñôˆKðVˆIØ% ~Ð6ˆJØ#�Ô#¥G¤M°9ÐJ¸zÐJÐJÐJˆAØ �KŠK˜‰NŒNˆNØ%)ˆDÔ "Ð "Ð "ð +Ð *r!)r"r#r$ÚDEFAULT_LOG_EVENTS_TIMEOUTÚDEFAULT_RECORDS_HISTORY_SIZEr&r5rFrIrHrJrXrOÚ staticmethodrnrCÚ __classcell__)r=s@rr-r-Rsñø€€€€€ð 6Ø(Dð 'ð'ð'ðð 'ð #&ð 'ð'ð'ð'ð'ð'ð, ð ð ð(ð(ð(ð(ð(ð %ð%ð%ð ð ð ð ð ð ð  ð  ð  ðð =ð =ñ„\ð =ð*ð*ð*ð*ð*ð*ð*r!r-Ú file_namecó„—tj|›d�¦« ¦«r tjn tjS)z*Get log level based on debug flag presencez .debug.flag)ÚpathlibÚPathÚexistsrPÚDEBUGrh)r€s rÚ get_log_levelr†Æs6€å#œL¨IÐ)BÐ)BÐ)BÑCÔC×JÒJÑLÔLÐ ^�7Œ=ˆ=ÕRYÔR^Ð^r!ÚqÚ stop_eventr.có¸—ttd¦«tj¬¦«}tj|¦«}| tjt¦«¦«| t|¦«¦«t||||¬¦«}|  ¦«|  ¦«|  ¦«dS)z² Main function to process log events in subprocess :param Queue q: log records queue :param Event stop_event: stop event :param str file_name: log file name Úlvectl)r]r?N)rrrPrQÚ FileHandlerÚ setFormatterÚ FormatterÚDEFAULT_LOG_FORMATÚsetLevelr†r-ÚstartÚwaitÚstop)r‡rˆr€r.Úsentry_handlerÚfhÚ q_handlers rÚrun_subpprocess_loggerr–Ës·€õ#Õ#?ÀÑ#IÔ#IÕQXÔQ^Ð_Ñ_Ô_€Nå Ô ˜YÑ 'Ô '€B؇O‚O•GÔ%Õ&8Ñ9Ô9Ñ:Ô:Ð:؇K‚K• ˜iÑ(Ô(Ñ)Ô)Ð)å(¨¨B°ÈÐPÑPÔP€IØ ‡O‚OÑÔÐØ‡O‚OÑÔÐØ ‡N‚NÑÔÐÐÐr!có$—eZdZUeed<eed<dS)ÚSubprocessLoggerÚlogger_processrˆN)r"r#r$rr'rr+r!rr˜r˜ßs*€€€€€€àÐÐÑØÐÐÑÐÐr!r˜Úsubprocess_loggersÚ logger_nameÚreturncóh—t |¦«}|�tj|¦«Stj|¦«}| tj¦«t ¦«}tj |¦«}| tj¦«|  |¦«t¦«}tt||||f¬¦«}|  ¦«tj|j¦«t#||¦«t|<|S)a— Get asynchronous logger running in subprocess Log records asynchronously in subprocess (>=info by default, >= debug when debug flag is present). Log records from debug and higher in subprocess in case of timeout. WARNING: multiprocessing.Queue is used to pass log records. It works asynchornously (passing to subprocess in handled by separate thread). This may lead to log records not being passed to the subprocess in case main process got stuck e.g. in kmodlve kernel space. :param str | None logger_name: logger name :param str file_name: log file :param int timeout: log events processing timeout N)Útargetra)ršr@rPÚ getLoggerr�r…rr<Ú QueueHandlerÚ addHandlerrrr–r�ÚatexitÚregisterÚsetr˜) r›r€r.Úsubprocess_loggerÚloggerÚsubprocess_logger_queueÚ queue_handlerrˆr™s rÚinit_subprocess_loggerr©ès€õ(+×.Ò.¨{Ñ;Ô;ÐØÐ$ÝÔ  Ñ-Ô-Ð-å Ô ˜{Ñ +Ô +€Fð ‡O‚O•G”MÑ"Ô"Ð"å%*¡W¤WÐÝÔ$×1Ò1Ð2IÑJÔJ€MØ×Ò�7œ=Ñ)Ô)Ð)Ø ×Ò�mÑ$Ô$Ð$å‘”€JÝÕ$:Ø#:¸JÈ ÐSZÐ"[ð]ñ]ô]€Nà×ÒÑÔÐÝ „O�J”NÑ#Ô#Ð#Ý&6°~ÀzÑ&RÔ&RÕ�{Ñ#à €Mr!r\có¶—t |¦«}|€dS|j ¦«|j ¦«t|=dS)z Stop subprocess logger N)ršr@rˆr¤r™r)r\r¥s rÚstop_subprocess_loggerr«s[€õ +×.Ò.¨tÑ4Ô4ÐØÐ ØˆàÔ ×$Ò$Ñ&Ô&Ð&ØÔ$×)Ò)Ñ+Ô+Ð+ݘ4Ð Ð Ð r!)&r¢r6Ú dataclassesrPÚlogging.handlersrRr‚r;rLrÚmultiprocessingrrrÚraven.handlers.loggingrr*Úlve_utils.sentryrr}r|rŽÚ dataclassr r<Ú QueueListenerr-r(r†r&r–r˜ršÚdictr'ÚLoggerr©r«r+r!rúrµsgðð€ € € € ØÐÐÐØÐÐÐØ€€€ØÐÐÐØ € € € Ø€€€Ø € € € Ø € € € ØÐÐÐÐÐØ1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1Ð1à0Ð0Ð0Ð0Ð0Ð0Ø € € € à9Ð9Ð9Ð9Ð9Ð9ð "ÐØ ÐØKÐð Ôð.Eð.Eð.Eð.Eð.Eñ.Eô.EñÔð.Eðbq*ðq*ðq*ðq*ðq*˜wÔ/Ô=ñq*ôq*ðq*ðh_˜Sð_ð_ð_ð_ð ˜eð°ðÀ3ðÐQTððððð( ÔðððððñôñÔðð :<Ð�D˜˜t™Ð%5Ð5Ô6Ð;Ð;Ñ;ð .ð)ð)Ø�t‘ð)àð)ðð)ð „^ð )ð)ð)ð)ðX ! ð !ð !ð !ð !ð !ð !r!