§ Å«j™-ãó8—dZdZddlZddlZddlZddlZddlmZddlZ ddl m Z ddl m Z ddlmZmZd d lmZd d lmZd d lmZd d lmZmZdZGd„de ¦«Zedkr7e¦«ejdej¬¦«e¦«Ze¦«dSdS)z* This module contains DecisionMaker class z ssa.moduleséN)Úisfile)Úsetup_databaseé)ÚCommon)Úiter_domains_dataÚiter_domain_url_dataé)Ú load_tunables)Ússa_tunables_schema)Ú report_path)Úprevious_day_dateÚ sentry_initic ó\‡—eZdZdZd ˆfd„ Zd„Zedefd„¦«Ze defd„¦«Z e de fd„¦«Z e de fd „¦«Zed „¦«Zde fd „Zd edefd „Zdedefd„Zdedefd„Zededededefd„¦«Zd„Zde fd„Zde fd„Zdedefd„Zd„Zdededefd„ZˆxZS)!Ú DecisionMakerz, SSA Decision maker implementation. Ncóè•—t¦« ¦«tjd¦«|_|j dt ¦«|r|n t¦«|_dS)NÚdecision_makerzDecisionMaker enabled: %s) ÚsuperÚ__init__ÚloggingÚ getLoggerÚloggerÚinfoÚ __package__rÚengine)ÚselfrÚ __class__s €úQ/opt/cloudlinux/venv/lib64/python3.11/site-packages/ssa/modules/decision_maker.pyrzDecisionMaker.__init__,s_ø€Ý ‰Œ×ÒÑÔÐÝÔ'Ð(8Ñ9Ô9ˆŒ Ø Œ ×ÒÐ4µkÑBÔBÐBà &Ð<�f�f­NÑ,<Ô,<ˆŒ ˆ ˆ ócót—|j d¦«|j d|j¦«| ¦«|_|j d|j¦«| ¦«}| |¦«|j d|¦«|S)NzDecisionMaker startedzDecisionMaker loaded config: %sz!DecisionMaker loaded tunables: %szDecisionMaker report: %s)rrÚdebugÚconfigÚload_external_confÚexternal_tunablesÚdata_processingÚadd_json_report)rÚreports rÚ__call__zDecisionMaker.__call__3s§€Ø Œ ×ÒÐ0Ñ1Ô1Ð1Ø Œ ×ÒÐ;¸T¼[ÑIÔIÐIØ!%×!8Ò!8Ñ!:Ô!:ˆÔØ Œ ×ÒÐ=¸tÔ?UÑVÔVÐVØ×%Ò%Ñ'Ô'ˆØ ×Ò˜VÑ$Ô$Ð$Ø Œ ×ÒÐ3°VÑ<Ô<Ð<؈ rÚreturncóL—tj t|¦«S)zE Full path to given filename in DM reports directory )ÚosÚpathÚjoinr )Únames rÚ _report_filezDecisionMaker._report_file=s€õ Œw�|Š|�K¨Ñ.Ô.Ð.rcó,—| d¦«S)zU Full path to current DM report: report.json in DM reports directory z report.json)r.©rs rÚcurrent_report_filez!DecisionMaker.current_report_fileDs€ð × Ò  Ñ/Ô/Ð/rcó<—tt¦«g¬¦«S)z& Returns empty report )ÚdateÚdomains)Údictr r0s rÚ _empty_reportzDecisionMaker._empty_reportKs€õ Õ*Ñ,Ô,°bÐ9Ñ9Ô9Ð9rcó—dhS)NÚ correlation©r0s rÚsolo_filtered_optionsz#DecisionMaker.solo_filtered_optionsRs €àˆÐrcó,—tdt¦«S)z"Load external configuration valueszssa.json)r r r9rrr"z DecisionMaker.load_external_confVs€õ˜ZÕ)<Ñ=Ô=Ð=rc ó´—|j}t|jt¦«r|jdkr|jnd}t |j¦«D�]^}t ¦«}d}d}t|j|j¦«D�]¿\}}} |  |¦«r|j   d|¦«Œ8||j vrŒB|  |  dt dgdz¦«¦«| d¦«sŒ„| | d|j¦«} |s)|j  dt%|¦«¦«ŒÐ| | d¦«rÔ| | ¦«r¿t+j|¦«} t/| d¦«} || z }t1|d t2…| t| ¦«t5| d ›¦«¬ ¦«} | | | f}t7|¦«|krt9j||¦«n!||dkrt9j||¦«|d z }�ŒÁ|rld „t?|d¬¦«D¦«}|d  t1|jt7|¦«|t/|j¦«|¬¦«¦«�Œ`|dr&| !|d|j"d¬¦«|d<|S)aü Going through the list of domains, for each domain we go through the list of urls. During data processing, we will form the resulting dictionary. Per-URL data is streamed via :func:`iter_domain_url_data`, so the per-domain ``{path: [durations...]}`` working set never lives in memory at once. This is what keeps the daily routine inside the ``MemoryMax=1G`` cgroup limit on hosts with very many distinct URLs per domain (CLPRO-3077). réz %s ignoredÚurl_throttled_reqséÚurl_total_reqszUnable to get durations for %sÚ url_slow_reqsNz.2f)r-Úreqs_numÚaverage_durationr8rcó—g|]\}}}|‘Œ Sr9r9)Ú.0Ú_Úentrys rú z1DecisionMaker.data_processing..�s€ÐXÐXÐX©¨¨A¨u˜uÐXÐXÐXrT)Úreverser4)r-Ú slow_urlsÚ slow_reqsÚ total_reqsÚurlsrK©Ú list_to_sortÚ leave_topÚkey_for_sorting)#r6Ú isinstanceÚ urls_numberÚintrrÚlistrÚ domain_nameÚ is_ignoredrr Únon_url_fieldsÚis_throttling_suitableÚgetÚget_correlationÚdomain_total_reqsÚerrorÚstrÚrequest_number_exceededÚcorrelation_conditionsÚnpÚmeanÚsumr5ÚMAX_REPORT_URL_LENÚfloatÚlenÚheapqÚheappushÚ heapreplaceÚsortedÚappendÚreport_sortingÚdomains_number)rr&rPÚ domain_dataÚ urls_dataÚorderÚdomain_slow_reqsÚurlÚ durationsÚurl_dataÚcorrelation_valueÚaverage_duration_calculationÚsum_url_slow_reqsrGÚitemÚ sorted_urlss rr$zDecisionMaker.data_processing[s1€ðÔ#ˆõ)3°4Ô3CÅSÑ(IÔ(IÐiÈdÔN^ÐabÒNbÐNb�DÔ$Ð$Ðhiˆ Ý,¨T¬[Ñ9Ô9ð: ñ: ˆKõ™œˆI؈EØ Ð å,@ÀÄÈkÔNeÑ,fÔ,fð! ñ! Ñ(��Y Ø—?’? 3Ñ'Ô'ðØ”K×%Ò% l°CÑ8Ô8Ð8ØØ˜$Ô-Ð-Ð-ØØ×2Ò2Ø—L’LÐ!5µt¸Q¸CÀ"¹H±~´~ÑFÔFÈÐQaÔHbñôððØ$(×$8Ò$8¸ÐBRÔ9SÐU`ÔUrÑ$sÔ$sÐ!Ø ðØ”K×%Ò%Ð&FÍÈCÉÌÑQÔQÐQØØ×/Ò/°¸Ô0IÑJÔJðÈt×OjÒOjØ%ñPôPðõ46´7¸9Ñ3EÔ3EÐ0Ý(+¨H°_Ô,EÑ(FÔ(FÐ%Ø$Ð(9Ñ9Ð$Ý Ø Ð!4Õ"4Ð!4Ô5Ø!2Ý),Ð-IÑ)JÔ)JÝ$)Ð->Ð*DÐ*DÑ$EÔ$Eð ñô�Eð.°¨v°uÐ=�Dݘ9‘~”~¨ Ò1Ð1Ýœ y°$Ñ7Ô7Ð7Ð7Ø  ¨!¤ Ò,Ð,ÝÔ)¨)°TÑ:Ô:Ð:ؘQ‘J�EùØð ðYÐX½¸yÐRVÐ8WÑ8WÔ8WÐXÑXÔX� Ø�yÔ!×(Ò(ÝØ(Ô4Ý"% kÑ"2Ô"2Ø"2Ý#& {Ô'DÑ#EÔ#EØ(ð ñôñôðùð �)Ô ð Ø $× 3Ò 3Ø# IÔ.¸$Ô:MÐ_jð!4ñ!ô!ˆF�9Ñ ðˆ rrAcón‡‡—|jpdŠˆˆfd„tdt‰¦«‰¦«D¦«S)zÌ Based on the 'url_slow_reqs' list, a new list will be formed, where the elements of the original list will be iteratively summed by the number of elements equal to 'time' r?cóD•—g|]}t‰|‰|z…¦«‘ŒSr9)rc)rEÚiÚtimerAs €€rrHz@DecisionMaker.list_handling_considering_time..´s.ø€Ð]Ð]Ð]°Q•�M ! d¨Q¡h ,Ô/Ñ0Ô0Ð]Ð]Ð]rr)r}Úrangerf)rrAr}s `@rÚlist_handling_considering_timez,DecisionMaker.list_handling_considering_time­sCøø€ð Œyˆ˜BˆØ]Ð]Ð]Ð]Ð]½%ÀÅ3À}ÑCUÔCUÐW[Ñ:\Ô:\Ð]Ñ]Ô]Ð]rÚurl_slow_reqs_by_timecó,—|D]}||jkrdSŒdS)z_ This functions will check if any of elements is greater than "request_number" TF)Úrequest_number)rr€r|s rÚ$compare_elements_with_request_numberz2DecisionMaker.compare_elements_with_request_number¶s2€ð'ð ð ˆAØ�DÔ'Ò'Ð'Ø�t�tð(àˆurr@r\cób—|jsdStjtj||¦«¦«S)z} Calculates the correlation coefficient using the "url_total_reqs" and the "domain_total_reqs" lists r)r8raÚaminÚcorrcoef)rr@r\s rr[zDecisionMaker.get_correlation¿s1€ð Ôð Ø�1ÝŒw•r”{ >Ð3DÑEÔEÑFÔFÐFrrOrPrQcóT‡—| ˆfd„d¬¦«|r |d|…S|S)a Will sort the domain list by "slow_reqs", the goal is to leave only "domains_number" of uppers, also per each domain will sort urls by "reqs_num", the goal is to leave only "urls_number" of uppers. leave_top == 0 allows to keep the full list có•—|‰S©Nr9)Údict_rQs €rúz.DecisionMaker.report_sorting..Ðs ø€¨E°/Ô,B€rT)ÚkeyrIN)ÚsortrNs `rrlzDecisionMaker.report_sortingÈsEø€ð ×ÒÐBÐBÐBÐBÈDÐÑQÔQÐQØ ð Ø     Ô+Ð +àÐ rcó’—|j}t|¦«r°t|¦«5} tj|¦«}| dd¦« dd¦«}n#tj$rd}YnwxYwddd¦«n #1swxYwYd|›d�}| |¦«}tj ||¦«dSdS) z# Rename old report r3z dd.mm.yyyyú.rFÚunknownNÚreport__z.json) r1rÚopenÚjsonÚloadrZÚreplaceÚJSONDecodeErrorr.r*Úrename)rÚ old_reportÚ json_dataÚdÚdate_from_reportÚnew_report_nameÚ new_reports rÚrename_old_reportzDecisionMaker.rename_old_reportÖs@€ðÔ-ˆ Ý �*Ñ Ô ð .Ý�jÑ!Ô!ð U YðUÝœ  )Ñ,Ô,�Að()§u¢u¨V°\Ñ'BÔ'B×'JÒ'JÈ3ÐPSÑ'TÔ'TÐ$Ð$øõÔ+ð1ð1ð1Ø'0Ð$Ð$Ð$ð1øøøð Uð Uð Uñ Uô Uð Uð Uð Uð Uð Uð Uøøøð Uð Uð Uð UðAÐ)9Ð@Ð@Ð@ˆOØ×*Ò*¨?Ñ;Ô;ˆJÝ ŒI�j *Ñ -Ô -Ð -Ð -Ð -ð .ð .s3¦B ¨A'¼+B Á'A;Á8B Á:A;Á;B  BÂBr&có¾—| ¦«t|jdd¬¦«5}tj||dd¬¦«ddd¦«dS#1swxYwYdS)z# Makes json report Úwzutf-8)ÚencodingFé)Ú ensure_asciiÚindentN)ržr’r1r“Údump)rr&Úfs rr%zDecisionMaker.add_json_reportçs¨€ð ×ÒÑ Ô Ð Ý �$Ô*¨C¸'Ð BÑ BÔ Bð ?ÀaÝ ŒI�f˜a¨e¸AÐ >Ñ >Ô >Ð >ð ?ð ?ð ?ñ ?ô ?ð ?ð ?ð ?ð ?ð ?ð ?ð ?øøøð ?ð ?ð ?ð ?ð ?ð ?s¬AÁAÁAcóØ—d} t|j¦«5}tj||¬¦«}ddd¦«n #1swxYwYn##ttjf$r |j}YnwxYw|S)zT Return contents of current report or empty report in case of error N)Ú object_hook)r’r1r“r”ÚOSErrorr–r6)rÚ_filtering_hookr&Ú report_dicts rÚget_json_reportzDecisionMaker.get_json_reportïsË€ðˆð -Ý�dÔ.Ñ/Ô/ð M°6Ý"œi¨¸OÐLÑLÔL� ð Mð Mð Mñ Mô Mð Mð Mð Mð Mð Mð Møøøð Mð Mð Mð Møøå�Ô-Ð.ð -ð -ð -ØÔ,ˆKˆKˆKð -øøøàÐs.„A˜;¯ A»?¿AÁ?ÁAÁA'Á&A'rucó*—|jsdS||jkS)aÔ If correlation flag is enabled - we'll compare correlation_coefficient from configuration with calculated correlation coefficient. If the calculated value exceeds the configuration value - we return True otherwise False. At the same time if correlation flag is disabled - we'll also return "True" since in this case the correlation coefficient is not checked and its value is specified as zero in final report. T)r8Úcorrelation_coefficient)rrus rr`z$DecisionMaker.correlation_conditionsüs"€ðÔð Ø�4Ø  4Ô#?Ò?Ð?rcóV—| |¦«}| |¦«S)z� At least one element from the received list (url_slow_reqs_by_time) must be greater than request_number )rrƒ)rrAr€s rr_z%DecisionMaker.request_number_exceeded s-€ð !%× CÒ CÀMÑ RÔ RÐØ×8Ò8Ð9NÑOÔOÐOrr>cóº—t|¦«t|¦«z dz}|j d|¦«||j dd¦«kS)zY Check that percent of throttled requests per URL passes given threshold édzCalculated throttled percent %sÚallowed_throttling_percentager)rcrr r#rZ)rr>r@Úthrottled_percents rrYz$DecisionMaker.is_throttling_suitables_€õ!Ð!3Ñ4Ô4µs¸>Ñ7JÔ7JÑJÈcÑQÐØ Œ ×ÒÐ;Ð=NÑOÔOÐOØ  DÔ$:×$>Ò$>Ð?^Ð`aÑ$bÔ$bÒbÐbrr‰)Ú__name__Ú __module__Ú __qualname__Ú__doc__rr'Ú staticmethodr^r.Úpropertyr1r5r6Úsetr:r"r$rUrÚboolrƒr[rTrlržr%r¬r`r_rYÚ __classcell__)rs@rrr's’ø€€€€€ððð=ð=ð=ð=ð=ð=ððððð/˜cð/ð/ð/ñ„\ð/ð ð0 Sð0ð0ð0ñ„Xð0ð ð:˜tð:ð:ð:ñ„Xð:ð ð sðððñ„Xððð>ð>ñ„\ð>ðP ðPðPðPðPðd^¸Dð^ÀTð^ð^ð^ð^ðÈ$ðÐSWðððððG¨dðGÀtðGðGðGðGðð   Tð  °cð  ÈCð  ÐTXð  ð  ð  ñ„\ð  ð.ð.ð.ð"? dð?ð?ð?ð?ð  ð ð ð ð ð @¸ð @Àð @ð @ð @ð @ðPðPðPðc¸ðcÈtðcÐX\ðcðcðcðcðcðcðcðcrrÚ__main__zdecision_maker_standalone.log)ÚfilenameÚlevel) r·rrgr“rr*Úos.pathrÚnumpyraÚssa.dbrÚcommonrÚstoragerrÚ configurationr Úconfiguration.schemesr Úinternal.constantsr Úinternal.utilsr rrdrr´Ú basicConfigÚINFOÚdmr9rrúrÌsŒðððð€ à € € € Ø € € € Ø€€€Ø € € € ØÐÐÐÐÐàÐÐÐà!Ð!Ð!Ð!Ð!Ð!ØÐÐÐÐÐððððððððð*Ð)Ð)Ð)Ð)Ð)Ø7Ð7Ð7Ð7Ð7Ð7Ø,Ð,Ð,Ð,Ð,Ð,Ø;Ð;Ð;Ð;Ð;Ð;Ð;Ð;ð Ððpcðpcðpcðpcðpc�Fñpcôpcðpcðf ˆzÒÐØ€K�M„M€MØ€GÔÐ!@ÈÌ ÐUÑUÔUÐUØ ˆ‰Œ€BØ€B�D„D€D€D€Dð Ðr