
    Pmj                    z   d Z ddlmZ ddlZddlZddlZddlmZ ddlmZ ddl	m
Z
mZ ddlmZ ddlmZmZ dd	lmZmZmZmZmZ dd
lmZ ddlmZ  ej        e          Zh dZh dZ h dZ! edd           G d d                      Z"d/dZ#d0dZ$d0dZ%d1dZ&d2d Z'dd!d3d%Z(dd!d4d(Z)d5d,Z*d6d-Z+g d.Z,dS )7zDContent-free cron service-health and execution telemetry projection.    )annotationsN)	dataclass)datetime)AnyOptional)CronExecutionEvent)GatewayHealthSnapshotGatewayMetric)_compute_grace_secondsget_catch_up_occurrence_countget_ticker_heartbeat_ageget_ticker_success_age	load_jobs)get_running_job_ids)now>   failedclaimedrunningunknown	completed>   directbuiltinexternal>   r   	delivered
suppressednot_configuredT)frozenslotsc                  $    e Zd ZU ded<   ded<   dS )CronHealthSnapshotzlist[GatewayMetric]metricszlist[CronExecutionEvent]eventsN)__name__
__module____qualname____annotations__     B/home/thesage/.hermes/hermes-agent/agent/monitoring/cron_health.pyr    r       s*             $$$$$$r(   r    returnr   c                     t                      S N)_hermes_nowr'   r(   r)   _nowr.   $   s    ==r(   rawr   strc                    t          | pd                              dd          }dt          j        |                                          d d          S )Nr   zutf-8replace)errorszsha256:   )r0   encodehashlibsha256	hexdigest)r/   values     r)   _job_keyr:   (   sT     y!!(((CCE=W^E**4466ss;===r(   c                   t          | pd                                          t          j        d          s?t          j        d          s*t          j        d          st          j        d          rdS dv sdv sd	v rd
S dv sdv rdS t	          fddD                       rdS dv sdv rdS dv sdv sdv rdS dv rdS t	          fddD                       rdS dS )N zk\b(?:authentication|authenticated|authenticate|authorization|authorized|authorize|unauthorized|forbidden)\bz
\bbearer\bz \b(?:access|api|refresh) token\bz\b(?:401|403)\bauth_failedz
rate limit429quotarate_limitedtimeoutz	timed outc              3      K   | ]}|v V  	d S r,   r'   .0r9   texts     r)   	<genexpr>z&classify_cron_error.<locals>.<genexpr>:   s'      
`
`U5D=
`
`
`
`
`
`r(   )network
connectiondnssocketunreachablenetwork_errordispatchexecutordispatch_failed	interruptzowner exited	restartedinterruptedzempty responseempty_responsec              3      K   | ]}|v V  	d S r,   r'   rC   s     r)   rF   z&classify_cron_error.<locals>.<genexpr>B   s'      
G
GU5D=
G
G
G
G
G
Gr(   )configmissinginvalidinvalid_configr   )r0   lowerresearchany)r/   rE   s    @r)   classify_cron_errorr]   -   sp   syb>>!!D
	  A  CG  	H  	H9]D)) 98$?? 9'..	 }tu}}4~DK4//y

`
`
`
`&_
`
`
``` TZ4//  dn44t8K8K}4

G
G
G
G&F
G
G
GGG  9r(   Optional[datetime]c                ~    	 | r!t          j        t          |                     nd S # t          t          f$ r Y d S w xY wr,   )r   fromisoformatr0   	TypeError
ValueError)r/   s    r)   _parse_timerc   G   sO    36@x%c#hh///D@z"   tts   $' <<recorddict[str, Any]Optional[int]c                |   t          |                     d                    p!t          |                     d                    }t          |                     d                    }||d S 	 t          ||z
                                  dz            }n# t          t
          f$ r Y d S w xY wt          d|          S )N
started_at
claimed_atfinished_ati  r   )rc   getinttotal_secondsra   rb   max)rd   startfinishdurations       r)   _duration_msrr   N   s    

<0011Z[LAYAY5Z5ZEM2233F}t5577$>??z"   ttq(s   .'B B+*B+delivery_outcomert   Optional[str]r   c               X   t          |                     d          pd                                          }t          |                     d          pd                                          }|t          vr|dk    rd}|!t          |                                          nd }t	          |t
          v r|ndt          |                     d                    |t          v r|ndt          |           |t          v r|nd |dv r"t          |                     d                    nd           S )	Nstatusr   sourcer   job_id>   r   r   error)rw   job_keyrx   duration_msrt   error_class)
r0   rk   rY   _KNOWN_SOURCESr   _KNOWN_STATUSESr:   rr   _KNOWN_DELIVERY_OUTCOMESr]   )rd   rt   rw   rx   outcomes        r)   project_execution_eventr   Z   s1    H%%23399;;FH%%23399;;F^##)(;(;/?/Kc"##))+++QUG?22vv	H--..>11vvy ((":::GG ...  

7 3 3444   r(   Optional[dict[str, Any]]Nonec               ,   | sdS 	 ddl m} t          | |          }|                                }|                    |           |j        dv r|                    d           dS dS # t          $ r  t          	                    dd	
           Y dS w xY w)zRBest-effort lifecycle emit; terminal states synchronously cross the queue barrier.Nr   )emitterrs   >   r   r   r   g      ?)rA   z$cron execution telemetry emit failedTexc_info)
agent.monitoringr   r   get_emitteremitrw   flush	Exceptionloggerdebug)rd   rt   r   eventtargets        r)   emit_execution_stater   r   s      	L,,,,,,'AQRRR$$&&E<===LLL%%%%% >= L L L;dKKKKKKLs   AA) )&BBjobr   boolc                   |                      dd          sdS t          |                      d                    }|                      d          }|t          |t                    sdS 	 |j        "|j        |                    |j                  }||z
                                  }|t          |          k    S # t          t          f$ r Y dS w xY w)NenabledTFnext_run_atschedule)tzinfo)
rk   rc   
isinstancedictr   r2   rm   r   ra   rb   )r   r   next_runr   latenesss        r)   _is_overduer      s    779d## u377=1122Hwwz""Hz(D99u?"sz'=''sz'::H(N11330::::z"   uus   *AB= =CCc                 B   g } dt           fdt          ffD ]}\  }}	  |            }|?|                     t          |t	          dt          |                    i                      R# t          $ r t                              dd           Y zw xY w	 |                     t          dt                      i                      n,# t          $ r t                              dd           Y nw xY w	 t                      }d	 |D             }|                     t          d
t          |          i                      |                     t          dt          d |D                       i                      n,# t          $ r t                              dd           Y nw xY w	 |                     t          dt          t                                i                      n,# t          $ r t                              dd           Y nw xY wt          | g           S )Nz+hermes.cron.scheduler.heartbeat_age_secondsz.hermes.cron.scheduler.last_success_age_secondsg        z!cron freshness metric unavailableTr   z*hermes.cron.scheduler.catch_up_occurrencesz cron catch-up metric unavailablec                >    g | ]}|                     d d          |S )r   T)rk   rD   r   s     r)   
<listcomp>z.build_cron_health_snapshot.<locals>.<listcomp>   s+    CCC3#'')T*B*BC3CCCr(   zhermes.cron.jobs.enabledzhermes.cron.jobs.overduec              3  R   K   | ]"}t          |t                                d V  #dS )   N)r   r.   r   s     r)   rF   z-build_cron_health_snapshot.<locals>.<genexpr>   s5      EE#KTVV,D,DEAEEEEEEr(   zcron job metrics unavailablezhermes.cron.jobs.runningz#cron running-job metric unavailable)r!   r"   )r   r   appendr
   rn   floatr   r   r   r   r   lensumr   r    )r!   namereaderr9   jobsr   s         r)   build_cron_health_snapshotr      s   #%G	68PQ	9;QR 	M 	Mf	MFHHE }T3sE%LL3I3I2NNOOO 	M 	M 	MLL<tLLLLLL	M	H<-// 	
 	
 	
 	
  H H H7$GGGGGHD{{CC$CCC}%?WrRRSSS*EEEEEEE 	
 	
 	
 	
  D D D3dCCCCCDK4c:M:O:O6P6PRTUU	
 	
 	
 	
  K K K:TJJJJJKgb9999sI   AA''&BB0C &C.-C.2BE9 9&F"!F"&=G$ $&HH)r    r   r]   r   r   )r*   r   )r/   r   r*   r0   )r/   r   r*   r^   )rd   re   r*   rf   )rd   re   rt   ru   r*   r   )rd   r   rt   ru   r*   r   )r   re   r   r   r*   r   )r*   r    )-__doc__
__future__r   r6   loggingrZ   dataclassesr   r   typingr   r   agent.monitoring.eventsr   agent.monitoring.gateway_healthr	   r
   	cron.jobsr   r   r   r   r   cron.schedulerr   hermes_timer   r-   	getLoggerr#   r   r   r~   r   r    r.   r:   r]   rc   rr   r   r   r   r   __all__r'   r(   r)   <module>r      st   J J " " " " " "   				 ! ! ! ! ! !                       6 6 6 6 6 6 P P P P P P P P              / . . . . . * * * * * *		8	$	$JJJ222RRR  $d###% % % % % % % $#%
   > > > >
   4   	 	 	 	 BF     2 LPL L L L L L$    ,: ,: ,: ,:^  r(   