a \·äd£#ã@sndZddlmZmZddlZddlZddlZddlZddlZddl Z ddl Z Gdd„dƒZ dd„Z dd „Z dS) zq statfiles.py - class for digesting and plotting NTP logfiles Requires gnuplot and liberation fonts installed. é)Úprint_functionÚdivisionNc@sŽeZdZdZdZdZiZdZdZdZ dZ e dd„ƒZ e dd „ƒZ e d d „ƒZe d d „ƒZddd„Zdd„Zdd„Zdd„Zdd„Zdd„ZdS)ÚNTPStatsz*Gather statistics for a specified NTP sitei€Qi€: NÚc Csžg}|D]}z$| ¡}t|dƒ}t|dƒ}WntyFYqYn0tj||d}||krn|krnqt|dƒ|d<t|ƒ|d<| |¡q|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ÚlinerZmjdÚsecondÚtime©rú3/usr/lib64/python3.9/site-packages/ntp/statfiles.pyÚunixizes     zNTPStats.unixizecCst| ¡dƒS)z"get Unix time from converted line.r)r r)rrrrÚ timestamp9szNTPStats.timestampcCsŽi}t|ƒ}d|krFd|kr&|d}nd}|D]}||dt|ƒ<q.nD|D]>}|dkrh||d|d<qJ|t||dƒ|dt|ƒ<qJ|S)zwReturn given percentiles of a given row in a given set of entries. assuming values are already split and sortedrrÚpédZp100)Úlenr r )ÚpercentsÚvaluesÚretÚlengthÚvalueÚpercrrrÚ percentiles>s "zNTPStats.percentilescCsd|d ¡r`| d¡r4| d¡\}}}}d||fSzt |¡\}}}|WStjy^Yn0|S)z,Produce appropriate label for an IP address.rz127.127.Ú.zREFCLOCK(type=%s,unit=%s))ÚisdigitÚ startswithrÚsocketZ gethostbyaddrZherror)ÚkeyÚ_Z clock_typeZunitÚhostnamerrrÚip_labelVs   zNTPStats.ip_labelc Cs|durtj}||_|dur:|dur:tt ¡ƒ}||}n2|durT|durT||}n|durl|durl||}||_||_|p†tj  |¡|_ d|j kržt   ¡|_ tj  |¡sÂtj d|¡tdƒ‚g|_g|_g|_g|_g|_g|_dD](}| ||¡}| ||¡}t|||ƒqêdS)z.Grab content of logfiles, sorted by timestamp.NZntpstatsz%ntpviz: ERROR: %s is not a directory r)Ú clockstatsÚ peerstatsÚ loopstatsÚrawstatsÚtempsÚgpsd)rÚ DefaultPeriodÚperiodr rrrÚosÚpathÚbasenameÚsitenamer'ZgetfqdnÚisdirÚsysÚstderrÚwriteÚ SystemExitr,r-r.r/r0r1Ú_NTPStats__load_stemÚ_NTPStats__process_stemÚsetattr) ÚselfÚstatsdirr7r3rrÚstemrZ processedrrrÚ__init__ms<      ÿ  zNTPStats.__init__cCs°g}z„tj ||¡}|dkr,|dkr,|d7}t |d¡D]J}|jtj |¡krRq:| d¡rr|t |d¡  ¡7}q:|t|dƒ  ¡7}q:Wn"t yªt j   d|¡Yn0|S) Nr0r1r$Ú*ÚgzZrtÚrz#ntpviz: WARNING: could not read %s )r4r5ÚjoinÚglobrÚgetmtimeÚendswithÚgzipÚopenÚ readlinesÚIOErrorr9r:r;)r@rArBrÚpatternZlogpartrrrZ __load_stem–s   ÿ zNTPStats.__load_stemc Cs¶g}|dks|dkr˜|D]|}| ¡}dt|ƒkr2qzt|dƒ}WntyXYqYn0|j|krr|jkrnq| dt|dƒ¡| |¡qnt   ||j|j¡}|  ¡|S)Nr0r1érr) rrr r rrÚinsertr rrrÚsort)r@rBrrrrZ time_floatrrrZ__process_stemªs    zNTPStats.__process_stemc Csb|jr |jS|jD]H}z0|d}||jvr4g|j|<|j| |¡WqtyXYq0q|jS)zoReturn a dictionary mapping peerstats IPs to entry subsets. This is very expensive, so cache the resulté)Úpeermapr-rÚ IndexError)r@ÚrowZ ip_addressrrrÚ peersplitÊs    zNTPStats.peersplitc CsRi}|jD]B}z*|d}||vr(g||<|| |¡Wq tyJYq 0q |S)z9Return a dictionary mapping gps sources to entry subsets.rS)r1rrU)r@ZgpsmaprVÚsourcerrrÚgpssplitÛs  zNTPStats.gpssplitc CsRi}|jD]B}z*|d}||vr(g||<|| |¡Wq tyJYq 0q |S)zAReturn a dictionary mapping temperature sources to entry subsets.rS)r0rrU)r@ZtempsmaprVrXrrrÚ tempssplités  zNTPStats.tempssplit)NNNN)Ú__name__Ú __module__Ú __qualname__Ú__doc__r r2rTr3rrr7Ú staticmethodrrr#r+rCr=r>rWrYrZrrrrrs0    ÿ ) rcCs*t|ƒ ¡rt|ƒSt |d¡}t |¡S)zEAccept timestamps in ISO 8661 format or numeric POSIX time. UTC only.ú%Y-%m-%dT%H:%M:%S)r r%r rÚstrptimeÚcalendarZtimegm)Z time_stringZ time_structrrrÚ iso_to_posixøs  rccCst dt |¡¡S)z&ISO 8601 string in UTC from Unix time.r`)rÚstrftimeÚgmtime)Z unix_timerrrÚ posix_to_isosrf)r^Z __future__rrrbrHrKr4r'r9rrrcrfrrrrÚsd