§
    |Åd£#  ã                   óx   — d Z ddlmZmZ ddlZddlZddlZddlZddlZddl	Z	ddl
Z
 G d„ d¦  «        Zd„ Zd„ ZdS )zq
statfiles.py - class for digesting and plotting NTP logfiles

Requires gnuplot and liberation fonts installed.

é    )Úprint_functionÚdivisionNc                   ó°   — e Zd ZdZdZdZi ZdZdZdZ	dZ
ed„ ¦   «         Zed„ ¦   «         Zed„ ¦   «         Zed	„ ¦   «         Z	 	 dd
„Zd„ Zd„ Zd„ Zd„ Zd„ ZdS )ÚNTPStatsz*Gather statistics for a specified NTP sitei€Q i€:	 NÚ c                 óv  — g }| D ]³}	 |                      ¦   «         }t          |d         ¦  «        }t          |d         ¦  «        }n# t          $ r Y ŒNw xY wt          j        |z  |z   dz
  }||cxk    r|k    r?n Œwt          |dz  ¦  «        |d<   t          |¦  «        |d<   |                     |¦  «         Œ´|S )z¨Extract first two fields, MJD and seconds past midnight.
        convert timestamp (MJD & seconds past midnight) to Unix time
        Replace MJD+second with Unix time.r   é   l   €@" éè  )ÚsplitÚintÚfloatÚ
ValueErrorr   ÚSecondsInDayÚstrÚappend)	ÚlinesÚ	starttimeÚendtimeÚlines1Úliner   ÚmjdÚsecondÚtimes	            ú//usr/lib/python3/dist-packages/ntp/statfiles.pyÚunixizezNTPStats.unixize   sá   € ð ˆØð 	%ð 	%ˆDðØŸ
š
™œ�Ý˜% œ(‘m”m�Ý˜u Qœx™œ��øÝð ð ð à�ðøøøõ
 Ô(¨3Ñ.°Ñ7¸*ÑDˆDØ˜DÐ+Ð+Ò+Ð+ GÒ+Ð+Ð+Ð+Ð+å˜t d™{Ñ+Ô+��a‘å˜t™9œ9��a‘Ø—’˜eÑ$Ô$Ð$øØˆs   ˆ>AÁ
AÁAc                 óP   — t          |                      ¦   «         d         ¦  «        S )z"get Unix time from converted line.r   )r   r   )r   s    r   Ú	timestampzNTPStats.timestamp9   s   € õ �T—Z’Z‘\”\ !”_Ñ%Ô%Ð%ó    c                 ó  — i }t          |¦  «        }d|k    r,d|k    r	|d         }nd}| D ]}||dt          |¦  «        z   <   ŒnH| D ]E}|dk    r||dz
           |d<   Œ|t          ||dz  z  ¦  «                 |dt          |¦  «        z   <   ŒF|S )zwReturn given percentiles of a given row in a given set of entries.
        assuming values are already split and sortedr	   r   Úpéd   Úp100)Úlenr   r   )ÚpercentsÚvaluesÚretÚlengthÚvalueÚpercs         r   ÚpercentileszNTPStats.percentiles>   sÅ   € ð ˆÝ�V‘”ˆØ�Š;ˆ;à�FŠ{ˆ{à˜qœ	��ð �Ø ð -ð -�Ø',��C�#˜d™)œ)‘OÑ$Ð$ð-ð !ð Lð L�Ø˜3’;�;Ø"(¨°!©Ô"4�C˜‘K�Kà+1µ#°fÀÀSÁÑ6IÑ2JÔ2JÔ+K�C˜�c $™iœi™Ñ(Ð(Øˆ
r   c                 ó
  — | d                               ¦   «         rh|                      d¦  «        r#|                      d¦  «        \  }}}}d|›d|›d�S 	 t          j        | ¦  «        \  }}}|S # t          j        $ r Y nw xY w| S )z,Produce appropriate label for an IP address.r   z127.127.ú.zREFCLOCK(type=z,unit=ú))ÚisdigitÚ
startswithr   ÚsocketÚgethostbyaddrÚherror)ÚkeyÚ_Ú
clock_typeÚunitÚhostnames        r   Úip_labelzNTPStats.ip_labelV   s¦   € ð
 ˆqŒ6�>Š>ÑÔð 	ð �~Š~˜jÑ)Ô)ð HØ+.¯9ª9°S©>¬>Ñ(��A�z 4 4Ø6@°j°jÀ$À$À$ÐGÐGðÝ#)Ô#7¸Ñ#<Ô#<Ñ �˜1˜aØ�øÝ”=ð ð ð Ø�ðøøøàˆ
s   ÁA. Á.B Á?B c                 óÐ  — |€t           j        }|| _        |€(|€&t          t	          j        ¦   «         ¦  «        }||z
  }n|€|�||z
  }n	|�|€||z   }|| _        || _        |pt          j         	                    |¦  «        | _
        d| j
        k    rt          j        ¦   «         | _
        t          j                             |¦  «        s1t          j                             d|z  ¦  «         t#          d¦  «        ‚g | _        g | _        g | _        g | _        g | _        g | _        dD ]?}|                      ||¦  «        }|                      ||¦  «        }t5          | ||¦  «         Œ@dS )z.Grab content of logfiles, sorted by timestamp.NÚntpstatsz%ntpviz: ERROR: %s is not a directory
r	   )Ú
clockstatsÚ	peerstatsÚ	loopstatsÚrawstatsÚtempsÚgpsd)r   ÚDefaultPeriodÚperiodr   r   r   r   ÚosÚpathÚbasenameÚsitenamer0   ÚgetfqdnÚisdirÚsysÚstderrÚwriteÚ
SystemExitr;   r<   r=   r>   r?   r@   Ú_NTPStats__load_stemÚ_NTPStats__process_stemÚsetattr)	ÚselfÚstatsdirrF   rB   r   r   Ústemr   Ú	processeds	            r   Ú__init__zNTPStats.__init__m   s  € ð ˆ>ÝÔ+ˆFØˆŒð ˆ?˜yÐ0Ý�$œ)™+œ+Ñ&Ô&ˆGØ &Ñ(ˆIˆIØÐ 7Ð#6Ø &Ñ(ˆIˆIØÐ" w Ø &Ñ(ˆGØ"ˆŒØˆŒà Ð>¥B¤G×$4Ò$4°XÑ$>Ô$>ˆŒØ˜œÒ&Ð&å"œNÑ,Ô,ˆDŒMåŒw�}Š}˜XÑ&Ô&ð 	 ÝŒJ×ÒÐEØ'ñ(ñ )ô )ð )å˜Q‘-”-ÐàˆŒØˆŒØˆŒØˆŒØˆŒ
ØˆŒ	ð2ð 	+ð 	+ˆDà×$Ò$ X¨tÑ4Ô4ˆEØ×+Ò+¨D°%Ñ8Ô8ˆIÝ�D˜$ 	Ñ*Ô*Ð*Ð*ð		+ð 	+r   c                 ó$  — g }	 t           j                             ||¦  «        }|dk    r|dk    r|dz  }t          j        |dz   ¦  «        D ]�}| j        t           j                             |¦  «        k    rŒ+|                     d¦  «        r+|t          j        |d¦  «         	                    ¦   «         z  }Œk|t          |d¦  «         	                    ¦   «         z  }Œ‘n2# t          $ r% t          j                             d|z  ¦  «         Y nw xY w|S )	Nr?   r@   r,   Ú*ÚgzÚrtÚrz#ntpviz: WARNING: could not read %s
)rC   rD   ÚjoinÚglobr   ÚgetmtimeÚendswithÚgzipÚopenÚ	readlinesÚIOErrorrI   rJ   rK   )rP   rQ   rR   r   ÚpatternÚlogparts         r   Ú__load_stemzNTPStats.__load_stem–   s,  € Øˆð	(Ý”g—l’l 8¨TÑ2Ô2ˆGØ�wŠˆ 4¨6¢> >Ø˜3‘�Ýœ9 W¨s¡]Ñ3Ô3ð <ð <�à”>¥B¤G×$4Ò$4°WÑ$=Ô$=Ò=Ð=ØØ×#Ò# DÑ)Ô)ð <Ø�TœY w°Ñ5Ô5×?Ò?ÑAÔAÑA�E�Eà�T '¨3Ñ/Ô/×9Ò9Ñ;Ô;Ñ;�E�Eð<øõ ð 	(ð 	(ð 	(ÝŒJ×ÒÐCØ&ñ'ñ (ô (ð (ð (ð (ð	(øøøð ˆs   „CC Ã,DÄDc                 óê  — g }|dk    s|dk    rª|D ]¦}|                      ¦   «         }dt          |¦  «        k    rŒ*	 t          |d         ¦  «        }n# t          $ r Y ŒMw xY w| j        |cxk    r| j        k    r>n Œk|                     dt          |dz  ¦  «        ¦  «         |                     |¦  «         Œ§n&t           
                    || j        | j        ¦  «        }|                     ¦   «          |S )Nr?   r@   é   r   r
   )r   r#   r   r   r   r   Úinsertr   r   r   r   Úsort)rP   rR   r   r   r   r   Ú
time_floats          r   Ú__process_stemzNTPStats.__process_stemª   s  € ØˆØ�7Š?ˆ?˜d fšn˜nàð )ð )�ØŸ
š
™œ�Ø•s˜5‘z”z’>�>àðÝ!& u¨Q¤x¡¤�J�JøÝ!ð ð ð à�Hðøøøð ”> ZÐ?Ð?Ò?Ð?°4´<Ò?Ð?Ð?Ð?Ð?à—L’L ¥C¨
°TÑ(9Ñ$:Ô$:Ñ;Ô;Ð;Ø—M’M %Ñ(Ô(Ð(øð)õ& ×%Ò% e¨T¬^¸T¼\ÑJÔJˆFð 	�Š‰ŒˆØˆs   ¼AÁ
AÁAc                 óØ   — | j         r| j         S | j        D ]N}	 |d         }|| j         vr
g | j         |<   | j         |                              |¦  «         Œ?# t          $ r Y ŒKw xY w| j         S )zoReturn a dictionary mapping peerstats IPs to entry subsets.
        This is very expensive, so cache the resulté   )Úpeermapr<   r   Ú
IndexError)rP   ÚrowÚ
ip_addresss      r   Ú	peersplitzNTPStats.peersplitÊ   s–   € ð Œ<ð 	 Ø”<Ðà”>ð 	ð 	ˆCðØ  œV�
Ø T¤\Ð1Ð1Ø/1�D”L Ñ,Ø”˜ZÔ(×/Ò/°Ñ4Ô4Ð4Ð4øÝð ð ð à�ðøøøð Œ|Ðs   ™;AÁ
A"Á!A"c                 ó˜   — i }| j         D ]?}	 |d         }||vrg ||<   ||                              |¦  «         Œ0# t          $ r Y Œ<w xY w|S )z9Return a dictionary mapping gps sources to entry subsets.rl   )r@   r   rn   )rP   Úgpsmapro   Úsources       r   ÚgpssplitzNTPStats.gpssplitÛ   s|   € àˆØ”9ð 	ð 	ˆCðØ˜Qœ�Ø Ð'Ð'Ø%'�F˜6‘NØ�v”×%Ò% cÑ*Ô*Ð*Ð*øÝð ð ð à�ðøøøð ˆó   �,:º
AÁAc                 ó˜   — i }| j         D ]?}	 |d         }||vrg ||<   ||                              |¦  «         Œ0# t          $ r Y Œ<w xY w|S )zAReturn a dictionary mapping temperature sources to entry subsets.rl   )r?   r   rn   )rP   Útempsmapro   rt   s       r   Ú
tempssplitzNTPStats.tempssplité   s~   € àˆØ”:ð 	ð 	ˆCðØ˜Qœ�Ø Ð)Ð)Ø')�H˜VÑ$Ø˜Ô ×'Ò'¨Ñ,Ô,Ð,Ð,øÝð ð ð à�ðøøøð ˆrv   )NNNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   rA   rm   rB   r   r   rF   Ústaticmethodr   r   r*   r8   rT   rM   rN   rq   ru   ry   © r   r   r   r      s  € € € € € Ø0Ð0Ø€LØ€MØ€GØ€FØ€IØ€GØ€Hàðð ñ „\ðð2 ð&ð &ñ „\ð&ð ðð ñ „\ðð. ðð ñ „\ðð, +/Ø6:ð'+ð '+ð '+ð '+ðRð ð ð(ð ð ð@ð ð ð"ð ð ðð ð ð ð r   r   c                 ó´   — t          | ¦  «                             ¦   «         rt          | ¦  «        S t          j        | d¦  «        }t          j        |¦  «        S )zEAccept timestamps in ISO 8661 format or numeric POSIX time. UTC only.ú%Y-%m-%dT%H:%M:%S)r   r.   r   r   ÚstrptimeÚcalendarÚtimegm)Útime_stringÚtime_structs     r   Úiso_to_posixr‡   ø   sN   € å
ˆ;ÑÔ×ÒÑ!Ô!ð  Ý�;ÑÔÐÝ”- Ð-@ÑAÔA€KåŒ?˜;Ñ'Ô'Ð'r   c                 óP   — t          j        dt          j        | ¦  «        ¦  «        S )z&ISO 8601 string in UTC from Unix time.r�   )r   ÚstrftimeÚgmtime)Ú	unix_times    r   Úposix_to_isorŒ     s   € åŒ=Ð,­d¬k¸)Ñ.DÔ.DÑEÔEÐEr   )r}   Ú
__future__r   r   rƒ   r[   r^   rC   r0   rI   r   r   r‡   rŒ   r   r   r   ú<module>rŽ      sÆ   ððð ð 0Ð /Ð /Ð /Ð /Ð /Ð /Ð /à €€€Ø €€€Ø €€€Ø 	€	€	€	Ø €€€Ø 
€
€
€
Ø €€€ð`ð `ð `ð `ð `ñ `ô `ð `ðF(ð (ð (ðFð Fð Fð Fð Fr   