Files
the-nexus/bin/__pycache__/webhook_health_dashboard.cpython-312.pyc

125 lines
14 KiB
Plaintext
Raw Normal View History

<EFBFBD>
<00><><EFBFBD>iN$<00> <01> <00>dZddlmZddlZddlZddlZddlZddlZddl Zddl
m Z m Z ddl mZddlmZddd d
d <0B>Zeej&j)d d <0A><00>Zeej&j)dd<0F><00>Zeej&j)deej2<00>dz dz dz <00><00><00>j5<00>Zeej&j)deej2<00>dz dz dz <00><00><00>j5<00>Ze Gd<16>d<17><00>Zd$d<18>Zd%d<19>Zd&d<1A>Z d'd<1B>Z!eef d(d<1C>Z"d)d<1D>Z#d*d+d<1E>Z$d,d<1F>Z%d-d <20>Z&d*d.d!<21>Z'e(d"k(rddl)Z)e*e'e)jVd#d<00><00><00>y)/a<>
Webhook health dashboard for fleet agent endpoints.
Issue: #855 in Timmy_Foundation/the-nexus
Probes each configured /health endpoint, persists the last-known-good state to a
JSON log, and generates a markdown dashboard in ~/.hermes/burn-logs/.
Default targets:
- bezalel: http://127.0.0.1:8650/health
- allegro: http://127.0.0.1:8651/health
- ezra: http://127.0.0.1:8652/health
- adagio: http://127.0.0.1:8653/health
Environment overrides:
- WEBHOOK_HEALTH_TARGETS="allegro=http://127.0.0.1:8651/health,ezra=http://127.0.0.1:8652/health"
- WEBHOOK_HEALTH_TIMEOUT=3
- WEBHOOK_STALE_AFTER=300
- WEBHOOK_HEALTH_OUTPUT=/custom/webhook-health-latest.md
- WEBHOOK_HEALTH_HISTORY=/custom/webhook-health-history.json
<EFBFBD>)<01> annotationsN)<02>asdict<63> dataclass)<01>Path)<01>Anyzhttp://127.0.0.1:8650/healthzhttp://127.0.0.1:8651/healthzhttp://127.0.0.1:8652/healthzhttp://127.0.0.1:8653/health)<04>bezalel<65>allegro<72>ezra<72>adagio<69>WEBHOOK_HEALTH_TIMEOUT<55>3<>WEBHOOK_STALE_AFTER<45>300<30>WEBHOOK_HEALTH_OUTPUTz.hermesz burn-logszwebhook-health-latest.md<6D>WEBHOOK_HEALTH_HISTORYzwebhook-health-history.jsonc<01>x<00>eZdZUded<ded<ded<ded<ded<ded <d
ed <d ed <ded<dd<0F>Zdd<10>Zy)<14> AgentHealth<74>str<74>name<6D>url<72>
int | None<6E> http_status<75>bool<6F>healthy<68>
latency_ms<EFBFBD>stale<6C> float | None<6E>last_success_ts<74>float<61>
checked_at<EFBFBD>messagec<01>8<00>|jry|jryy)Nu🟢u🔴u🟠)rr<00><01>selfs <20>g/Users/apayne/worktrees/claude-833-73ECFC55-8015-4B20-97BC-8BAF8CBB34FE/bin/webhook_health_dashboard.py<70> status_iconzAgentHealth.status_iconGs<00><00> <0F><<3C><<3C><19> <0F>:<3A>:<3A><19><15>c<01>t<00>|j<00>ytdt|j|jz
<00><00>S)Nr)r<00>max<61>intr r#s r%<00>last_success_age_secondsz$AgentHealth.last_success_age_secondsNs2<00><00> <0F> <1F> <1F> '<27><17><12>1<EFBFBD>c<EFBFBD>$<24>/<2F>/<2F>D<EFBFBD>,@<40>,@<40>@<40>A<>B<>Br'N)<02>returnr)r,r)<06>__name__<5F>
__module__<EFBFBD> __qualname__<5F>__annotations__r&r+<00>r'r%rr;s><00><00>
<0A>I<EFBFBD> <0C>H<EFBFBD><1B><1B> <11>M<EFBFBD><1A><1A> <0F>K<EFBFBD>!<21>!<21><15><15> <10>L<EFBFBD><16>Cr'rc<01>(<00>|stt<00>Si}|jd<01>D]]}|j<00>}|s<01>d|vrt d|<02><02><02><00>|jdd<04>\}}|j<00>||j<00><<00>_|s t d<05><00>|S)N<>,<2C>=zInvalid target spec: <20>zNo valid targets parsed)<05>dict<63>DEFAULT_TARGETS<54>split<69>strip<69>
ValueError)<05>raw<61>targets<74>chunkrrs r%<00> parse_targetsr>Ts<><00><00> <0E><13>O<EFBFBD>$<24>$<24> <20>G<EFBFBD><14><19><19>3<EFBFBD><1E>,<2C><05><15> <0B> <0B> <0A><05><14> <14> <0E>e<EFBFBD> <1B><1C>4<>U<EFBFBD>I<EFBFBD>><3E>?<3F> ?<3F><19>K<EFBFBD>K<EFBFBD><03>Q<EFBFBD>'<27> <09><04>c<EFBFBD> #<23> <09> <09> <0B><07><04>
<EFBFBD>
<EFBFBD> <0C><1D>,<2C> <13><18>2<>3<>3<> <12>Nr'c<01>v<00>|j<00>sigd<01>Stj|jd<02><03><00>S)N)<02>agents<74>runs<6E>utf-8<><01>encoding)<04>exists<74>json<6F>loads<64> read_text)<01>paths r%<00> load_historyrJes0<00><00> <0F>;<3B>;<3B>=<3D><1C>b<EFBFBD>)<29>)<29> <0F>:<3A>:<3A>d<EFBFBD>n<EFBFBD>n<EFBFBD>g<EFBFBD>n<EFBFBD>6<> 7<>7r'c<01><><00>|jjdd<01><02>|jtj|dd<01><04>d<05><06>y)NT<4E><02>parents<74>exist_ok<6F>)<02>indent<6E> sort_keysrBrC)<05>parent<6E>mkdir<69>
write_textrF<00>dumps)rI<00>historys r%<00> save_historyrWks6<00><00><08>K<EFBFBD>K<EFBFBD><15><15>d<EFBFBD>T<EFBFBD><15>2<><08>O<EFBFBD>O<EFBFBD>D<EFBFBD>J<EFBFBD>J<EFBFBD>w<EFBFBD>q<EFBFBD>D<EFBFBD>A<>G<EFBFBD>O<EFBFBD>Tr'c<01>h<00>tj<00>}tjj |ddi<01><03>} tjj ||<01><04>5}|j d<05>}ttj<00>|z
dz<00>}t|dd<00>xsd}d |<07><00>}|rS tj|jd
d <0B> <0C><00>} t| t<00>r| jd<07>r d |<07>d | d<00><00>}d|cxkxrdknc|||fcddd<00>S#t$rY<00>(wxYw#1swYyxYw#tj j"$rJ}
ttj<00>|z
dz<00>}d|
j$|d |
j$<00><00>fcYd}
~
Sd}
~
wtj j&$r@}
ttj<00>|z
dz<00>}dd|d|
j(<00><00>fcYd}
~
Sd}
~
wt$r6}
ttj<00>|z
dz<00>}dd|d|
<EFBFBD><00>fcYd}
~
Sd}
~
wwxYw)Nz
User-Agentz"the-nexus/webhook-health-dashboard)<01>headers)<01>timeoutii<><00>status<75><73>zHTTP rB<00>replace)<01>errorsu — i,Fz URL error: zProbe failed: )<15>time<6D> perf_counter<65>urllib<69>request<73>Request<73>urlopen<65>readr*<00>getattrrFrG<00>decode<64>
isinstancer6<00>get<65> Exception<6F>error<6F> HTTPError<6F>code<64>URLError<6F>reason) rrZ<00>started<65>req<65>resp<73>bodyrr[r!<00>payload<61>es r%<00> probe_healthrvps<00><00><12><1F><1F>!<21>G<EFBFBD>
<10>.<2E>.<2E>
<20>
<20><13>|<7C>=a<>.b<>
<20>
c<EFBFBD>C<EFBFBD>=<3D> <13>^<5E>^<5E> #<23> #<23>C<EFBFBD><17> #<23> 9<> D<01>T<EFBFBD><17>9<EFBFBD>9<EFBFBD>S<EFBFBD>><3E>D<EFBFBD><1C>d<EFBFBD>/<2F>/<2F>1<>G<EFBFBD>;<3B>t<EFBFBD>C<>D<>J<EFBFBD><1C>T<EFBFBD>8<EFBFBD>T<EFBFBD>2<>9<>c<EFBFBD>F<EFBFBD><1D>f<EFBFBD>X<EFBFBD>&<26>G<EFBFBD><13><19>"<22>j<EFBFBD>j<EFBFBD><14><1B><1B>W<EFBFBD>Y<EFBFBD><1B>)O<>P<>G<EFBFBD>!<21>'<27>4<EFBFBD>0<>W<EFBFBD>[<5B>[<5B><18>5J<35>$)<29>&<26><18><15>w<EFBFBD>x<EFBFBD>7H<37>6I<36>"J<><07><17>&<26>&<26>3<EFBFBD>&<26><06>
<EFBFBD>G<EFBFBD>C<> D<01> D<01><>!<21><19><18><19><> D<01> D<01><> <12><<3C><<3C> !<21> !<21>;<3B><18>$<24>+<2B>+<2B>-<2D><07>7<>4<EFBFBD>?<3F>@<40>
<EFBFBD><14>a<EFBFBD>f<EFBFBD>f<EFBFBD>j<EFBFBD>E<EFBFBD>!<21>&<26>&<26><18>*:<3A>:<3A>:<3A><> <11><<3C><<3C> <20> <20>A<01><18>$<24>+<2B>+<2B>-<2D><07>7<>4<EFBFBD>?<3F>@<40>
<EFBFBD><14>d<EFBFBD>J<EFBFBD>+<2B>a<EFBFBD>h<EFBFBD>h<EFBFBD>Z<EFBFBD>(@<40>@<40>@<40><> <14>=<3D><18>$<24>+<2B>+<2B>-<2D><07>7<>4<EFBFBD>?<3F>@<40>
<EFBFBD><14>d<EFBFBD>J<EFBFBD>.<2E><11><03>(<<3C><<3C><<3C><>=<3D>s<EFBFBD><00>!D2<00>A D&<03>(AD<02>:D&<03> D2<00> D#<05> D&<03>"D#<05>#D&<03>&D/<07>+D2<00>/D2<00>2H1<03>?F<03>H1<03> H1<03>45G/<03>)H1<03>/ H1<03>;+H,<03>&H1<03>,H1c <01>^<00>tj<00>}g}|jdi<00>}|j<00>D]<5D>\}}|j|i<00>} | jd<02>}
t ||<02>\} } } }| r|}
d}| s|
<EFBFBD>|t |
<EFBFBD>z
|kD}t ||| | | ||
||<0E><04> }||
| ||d<05>||<|j|<10><00><>|jdg<00>j|td<07>|D<00><00>td<08>|D<00><00>|D<00>cgc] }t|<11><00><02>c}d <09><04>|dd
d|d<|Scc}w) Nr@rF) rrrrrrrr r!)rr<00>last_http_status<75> last_message<67>last_checked_atrAc3<01>:K<00>|]}|js<01>d<00><01><00>y<01>w<01>r5N<>r<00><02>.0<EFBFBD>rs r%<00> <genexpr>zcheck_agents.<locals>.<genexpr><3E>s<00><00><><00> A<>q<EFBFBD>q<EFBFBD>y<EFBFBD>y<EFBFBD><11> A<><41><00><01>c3<01>:K<00>|]}|jr<01>d<00><01><00>y<01>wr|r}r~s r%r<>zcheck_agents.<locals>.<genexpr><3E>s<00><00><><00>"G<><11>Q<EFBFBD>Y<EFBFBD>Y<EFBFBD>1<EFBFBD>"G<>r<EFBFBD>)r <00> healthy_count<6E>unhealthy_countr@i<><69><EFBFBD><EFBFBD>)
r_<00>
setdefault<EFBFBD>itemsrirvrr<00>append<6E>sumr)r<rVrZ<00> stale_afterr <00>results<74> agent_staterr<00>stater<00>okrrr!r<00>resultr<74>s r%<00> check_agentsr<73><00>s_<00><00> <16><19><19><1B>J<EFBFBD>!#<23>G<EFBFBD><19>$<24>$<24>X<EFBFBD>r<EFBFBD>2<>K<EFBFBD><1C>]<5D>]<5D>_<EFBFBD><1F> <09><04>c<EFBFBD><1B><0F><0F><04>b<EFBFBD>)<29><05><1F>)<29>)<29>$5<>6<><0F>/;<3B>C<EFBFBD><17>/I<>,<2C><02>K<EFBFBD><1A>W<EFBFBD> <0A>(<28>O<EFBFBD><15><05><11>o<EFBFBD>1<><1F>%<25><0F>"8<>8<>K<EFBFBD>G<>E<EFBFBD><1C><15><13>#<23><16>!<21><17>+<2B>!<21><1B>

<EFBFBD><06><17>.<2E> +<2B>#<23>)<29> 
<EFBFBD> <0B>D<EFBFBD><19> <10><0E><0E>v<EFBFBD><1E>7<1F>: <0C><16><16>v<EFBFBD>r<EFBFBD>"<22>)<29>)<29>$<24> <20> A<>G<EFBFBD> A<>A<>"<22>"G<>g<EFBFBD>"G<>G<>*1<>2<>Q<EFBFBD>v<EFBFBD>a<EFBFBD>y<EFBFBD>2<> 
<EFBFBD><06><1E>f<EFBFBD>o<EFBFBD>d<EFBFBD>e<EFBFBD>,<2C>G<EFBFBD>F<EFBFBD>O<EFBFBD> <12>N<EFBFBD><4E> 3s<00>D*c<01>F<00>|<00>y|dkr|<00>d<03>S|dkr|dz<00>d<05>S|dz<00>d<06>S)N<>never<65><zs agoizm agozh agor1)<01>secondss r%<00> _format_ager<65><00>sH<00><00><0E><EFBFBD><16><0E><12>|<7C><19><19>%<25> <20> <20><0E><14>~<7E><19>R<EFBFBD>-<2D><1F><05>&<26>&<26><15><14>o<EFBFBD> <1E>e<EFBFBD> $<24>$r'c <01>*<00>|xstj<00>}tjdtj|<01><00>}td<02>|D<00><00>}t |<00>}d|<02><00>dd|<03>d|<04><00>dddg}|D]<5D>}|j
<00>t |j
<00>nd }|j<00>|j<00>d
<EFBFBD>nd }|jd j|j|j<00>||t|j<00><00>|j|j<00> <0C><00><00><>|D<00> cgc]} | j s<01>| j<00><02>}
} |
r#|j#dd dj%|
<EFBFBD>g<03>|j#ddg<02>dj%|<05>Scc} w)Nz%Y-%m-%d %H:%M:%S UTCc3<01>:K<00>|]}|js<01>d<00><01><00>y<01>wr|r}r~s r%r<>zto_markdown.<locals>.<genexpr><3E>s<00><00><><00>2<><01><01> <09> <09>!<21>2<>r<EFBFBD>u%# Agent Webhook Health Dashboard — <20>z Healthy: <20>/zE| Agent | Status | HTTP | Latency | Last success | Endpoint | Notes |zD|:------|:------:|:----:|--------:|:------------|:---------|:------|u<>mszO| {name} | {icon} | {http} | {latency} | {last_success} | `{url}` | {message} |)r<00>icon<6F>http<74>latency<63> last_successrr!z## Stale agentsz, z/Generated by `bin/webhook_health_dashboard.py`.<2E>
)r_<00>strftime<6D>gmtimer<65><00>lenrrrr<><00>formatrr&r<>r+rr!r<00>extend<6E>join) r<><00> generated_at<61>tsr<00>total<61>linesr<73>r<>r<>r<><00> stale_agentss r%<00> to_markdownr<6E><00>s<><00><00><1F>.<2E>4<EFBFBD>9<EFBFBD>9<EFBFBD>;<3B>L<EFBFBD> <0A><1D><1D>.<2E><04> <0B> <0B>L<EFBFBD>0I<30> J<>B<EFBFBD><11>2<>W<EFBFBD>2<>2<>G<EFBFBD> <0F><07>L<EFBFBD>E<EFBFBD> 0<><02>t<EFBFBD>4<>
<EFBFBD>
<13>G<EFBFBD>9<EFBFBD>A<EFBFBD>e<EFBFBD>W<EFBFBD>%<25>
<EFBFBD>O<>N<>  <06>E<EFBFBD><1A> 
<EFBFBD><06>*0<>*<<3C>*<<3C>*H<>s<EFBFBD>6<EFBFBD>%<25>%<25>&<26>e<EFBFBD><04>.4<EFBFBD>.?<3F>.?<3F>.K<>V<EFBFBD>&<26>&<26>'<27>r<EFBFBD>*<2A>QV<51><07> <0A> <0C> <0C> ]<5D> d<> d<><1B>[<5B>[<5B><1B>'<27>'<27>)<29><19><1F>(<28><16>)H<>)H<>)J<>K<><1A>J<EFBFBD>J<EFBFBD><1E><0E><0E> e<01> <0E>
<EFBFBD> 
<EFBFBD>%,<2C>7<>q<EFBFBD>q<EFBFBD>w<EFBFBD>w<EFBFBD>A<EFBFBD>F<EFBFBD>F<EFBFBD>7<>L<EFBFBD>7<><13> <0A> <0C> <0C> <0E> <1D> <10>I<EFBFBD>I<EFBFBD>l<EFBFBD> #<23>
<EFBFBD> <0B> 
<EFBFBD>L<EFBFBD>L<EFBFBD>
<EFBFBD>9<><06><07> <10>9<EFBFBD>9<EFBFBD>U<EFBFBD> <1B><1B><>8s <00>%F<04>7Fc<01>j<00>|jjdd<01><02>|j|dzd<04><05>y)NTrLr<>rBrC)rRrSrT)rI<00>markdowns r%<00>write_dashboardr<64><00>s-<00><00><08>K<EFBFBD>K<EFBFBD><15><15>d<EFBFBD>T<EFBFBD><15>2<><08>O<EFBFBD>O<EFBFBD>H<EFBFBD>t<EFBFBD>O<EFBFBD>g<EFBFBD>O<EFBFBD>6r'c<01><><00>tjd<01><02>}|jdtjj d<04><00><05>|jdt t<00><07>|jdtt<00><07>|jd tt<00><07>|jd
tt<00><07>|j|<00>S) Nz!Generate webhook health dashboard)<01> descriptionz --targets<74>WEBHOOK_HEALTH_TARGETS)<01>defaultz --timeout)<02>typer<65>z --stale-afterz--outputz --history)<0E>argparse<73>ArgumentParser<65> add_argument<6E>os<6F>environrir<00>DEFAULT_TIMEOUTr*<00>DEFAULT_STALE_AFTERr<00>DEFAULT_OUTPUT<55>DEFAULT_HISTORY<52>
parse_args)<02>argv<67>parsers r%r<>r<><00>s<><00><00> <15> $<24> $<24>1T<31> U<>F<EFBFBD>
<EFBFBD><17><17> <0B>R<EFBFBD>Z<EFBFBD>Z<EFBFBD>^<5E>^<5E><T<>-U<><17>V<>
<EFBFBD><17><17> <0B>%<25><1F><17>I<>
<EFBFBD><17><17><0F>c<EFBFBD>;N<><17>O<>
<EFBFBD><17><17>
<EFBFBD><14>~<7E><17>F<>
<EFBFBD><17><17> <0B>$<24><0F><17>H<> <11> <1C> <1C>T<EFBFBD> "<22>"r'c<01><><00>t|xstjdd<00>}t|j<00>}t |j <00>}t|||j|j<00><02>}t|j |<03>t|<04>}t|j|<05>t|j<00>tdtd<04>|D<00><00><00>dt!|<04><00><00><04>y)Nr5)rZr<>zhealthy=c3<01>:K<00>|]}|js<01>d<00><01><00>y<01>wr|r}r~s r%r<>zmain.<locals>.<genexpr> s<00><00><><00>9<>q<EFBFBD>q<EFBFBD>y<EFBFBD>y<EFBFBD><11>9<>r<EFBFBD>z total=r)r<><00>sysr<73>r>r<rJrVr<>rZr<>rWr<>r<><00>output<75>printr<74>r<>)r<><00>argsr<rVr<><00> dashboards r%<00>mainr<6E>s<><00><00> <15>d<EFBFBD>*<2A>c<EFBFBD>h<EFBFBD>h<EFBFBD>q<EFBFBD>r<EFBFBD>l<EFBFBD> +<2B>D<EFBFBD><1B>D<EFBFBD>L<EFBFBD>L<EFBFBD>)<29>G<EFBFBD><1A>4<EFBFBD><<3C><<3C>(<28>G<EFBFBD><1A>7<EFBFBD>G<EFBFBD>T<EFBFBD>\<5C>\<5C>t<EFBFBD>O_<4F>O_<4F>`<60>G<EFBFBD><10><14><1C><1C>w<EFBFBD>'<27><1B>G<EFBFBD>$<24>I<EFBFBD><13>D<EFBFBD>K<EFBFBD>K<EFBFBD><19>+<2B> <09>$<24>+<2B>+<2B><16> <09>H<EFBFBD>S<EFBFBD>9<>G<EFBFBD>9<>9<>:<3A>'<27>#<23>g<EFBFBD>,<2C><1E>
P<EFBFBD>Q<> r'<00>__main__r5)r;z
str | Noner,<00>dict[str, str])rIrr,<00>dict[str, Any])rIrrVr<>r,<00>None)rrrZrr,z(tuple[bool, int | None, int | None, str])
r<r<>rVr<>rZrr<>r*r,<00>list[AgentHealth])r<>rr,r)N)r<>r<>r<>rr,r)rIrr<>rr,r<>)r<>z list[str]r,zargparse.Namespace)r<>zlist[str] | Noner,r*),<2C>__doc__<5F>
__future__rr<>rFr<>r_<00> urllib.errorra<00>urllib.request<73> dataclassesrr<00>pathlibr<00>typingrr7rr<>rir<>r*r<>r<00>home<6D>
expanduserr<EFBFBD>r<>rr>rJrWrvr<>r<>r<>r<>r<>r<>r-r<><00>
SystemExitr<EFBFBD>r1r'r%<00><module>r<>s<><00><01><04>,#<23><0F> <0B> <09> <0B><13><15>)<29><18><16>.<2E>-<2D> *<2A>,<2C> <02><0F><18><02>
<EFBFBD>
<EFBFBD><0E><0E>'?<3F><13>E<>F<><0F><19>"<22>*<2A>*<2A>.<2E>.<2E>)><3E><05>F<>G<><13><15><06>J<EFBFBD>J<EFBFBD>N<EFBFBD>N<EFBFBD><1F> <0B>I<EFBFBD>D<EFBFBD>I<EFBFBD>I<EFBFBD>K<EFBFBD>)<29> #<23>k<EFBFBD> 1<>4N<34> N<>O<><06><02>
 <0A>*<2A>,<2C> <0F> <17><06>J<EFBFBD>J<EFBFBD>N<EFBFBD>N<EFBFBD> <20> <0B>I<EFBFBD>D<EFBFBD>I<EFBFBD>I<EFBFBD>K<EFBFBD>)<29> #<23>k<EFBFBD> 1<>4Q<34> Q<>R<><06><02>
 <0A>*<2A>,<2C> <10> <0B>C<01>C<01> <0B>C<01>0<13>"8<> U<01>
=<3D>>%<25>*<2A> 0<13> <1B>0<13> <1B>0<13><13>0<13><15> 0<13>
<17> 0<13>f%<25>)<1C>X7<>
#<23>
 <0A> <0C>z<EFBFBD><19><0E>
<14>T<EFBFBD>#<23>(<28>(<28>1<EFBFBD>2<EFBFBD>,<2C>'<27>
(<28>(<28>r'